提交 2d9f4774 编写于 作者: L liu13

20190320

上级 de13f7e7
package code;
/*
* 112. Path Sum
* 题意:是否存在跟到叶子节点的和为sum
* 难度:Easy
* 分类:
* 思路:
* Tips:lc112, lc113, lc437, lc129, lc124, lc337
* 总结一下 lc112 找跟到叶子和为sum的路径是否存在
* lc113 把lc112的路径找出来
* lc437 是任意一条向下走的路径
* lc129 计算所有的和
* lc124 任意一条路径
* lc337 树的dp
*/
public class lc112 {
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
public boolean hasPathSum(TreeNode root, int sum) {
if(root==null) return false;
if(root.val==sum&&root.left==null&&root.right==null) return true;
return hasPathSum(root.left, sum-root.val)||hasPathSum(root.right, sum-root.val);
}
}
......@@ -8,7 +8,7 @@ import java.util.List;
* 难度:Medium
* 分类:Tree, Depth-first Search
* 思路:回溯,注意因为节点上可能正值,可能负值,所以不能剪枝
* Tips:lc124
* Tips:lc112, lc113, lc437, lc129, lc124, lc337
*/
public class lc113 {
public class TreeNode {
......
......@@ -6,7 +6,7 @@ package code;
* 分类:Tree, Depth-first Search
* 思路:因为二叉树只有两个节点,一条路径可以想象成倒V字,从低层的某个节点一路向上,到达一个顶点,再一路向下,理解了这一点,整道题就好解了。
* Tips:用了一个全局变量存储最后结果,因为函数返回的是直线路径上的最优解,而不是V字路径最优解
* lc133
* lc112, lc113, lc437, lc129, lc124, lc337, lc543
*/
public class lc124 {
public class TreeNode {
......
package code;
/*
* 129. Sum Root to Leaf Numbers
* 题意:一条路径上的数字组成一个数字,求所有从跟到叶子的路径和
* 难度:Medium
* 分类:Tree, Depth-first Search
* 思路:dfs
* Tips:lc112, lc113, lc437, lc129, lc124, lc337
*/
public class lc129 {
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
public int sumNumbers(TreeNode root) {
if(root==null) return 0;
return helper(root, 0);
}
public int helper(TreeNode root, int sum){
if(root==null) return 0; //一条路径,另一边返回0
if(root.left==null&&root.right==null) return sum*10+root.val; //这点注意,是叶子节点直接返回了
return helper(root.left, sum*10+root.val) + helper(root.right, sum*10+root.val);
}
}
package code;
import java.util.Arrays;
import java.util.Collections;
/*
* 151. Reverse Words in a String
* 题意:反转字符串中的单词
* 难度:Medium
* 分类:String
* 思路:难点在中间的空格可能是多个空格,注意如何解决
* Tips:
*/
public class lc151 {
public String reverseWords(String s) {
String[] words = s.trim().split(" +"); //+号匹配多个
Collections.reverse(Arrays.asList(words));
return String.join(" ", words);
}
}
......@@ -35,7 +35,7 @@ public class lc236 {
parent.put(root, null);
stack.push(root);
while (!parent.containsKey(p) || !parent.containsKey(q)) {
while (!parent.containsKey(p) || !parent.containsKey(q)) { //遍历了一遍节点,把节点的父节点信息记录了一下
TreeNode node = stack.pop();
if (node.left != null) {
parent.put(node.left, node);
......@@ -47,11 +47,11 @@ public class lc236 {
}
}
Set<TreeNode> ancestors = new HashSet<>();
while (p != null) {
while (p != null) { //p的路径节点添加到hashset中
ancestors.add(p);
p = parent.get(p);
}
while (!ancestors.contains(q))
while (!ancestors.contains(q)) //第一个hashset中遇到的节点,就是最近公共祖先
q = parent.get(q);
return q;
}
......
package code;
/*
* 239. Sliding Window Maximum
* 题意:滑动窗口最大值
* 题意:滑动窗口最大值
* 难度:Hard
* 分类:Heap
* 思路:用双向队列,保证队列里是递的。单调队列,好好学习一下。
* 思路:用双向队列,保证队列里是递的。单调队列,好好学习一下。
* Tips:与lc84做比较,84是递增栈
*/
import java.util.ArrayDeque;
......@@ -25,7 +25,7 @@ public class lc239 {
return new int[]{};
int[] res = new int[nums.length-k+1];
int cur = 0;
Deque<Integer> dq = new ArrayDeque();
Deque<Integer> dq = new ArrayDeque(); //队列里是递减的
for (int i = 0; i < nums.length ; i++) {
if( !dq.isEmpty() && dq.peekFirst()<=i-k)
dq.removeFirst();
......
......@@ -7,7 +7,7 @@ package code;
* 思路:两种巧妙的方法,时间空间都是O(1)
* 异或
* 求和以后,减去所有
* Tips:
* Tips:lc268 lc448 lc287
*/
public class lc268 {
public int missingNumber(int[] nums) {
......@@ -16,7 +16,7 @@ public class lc268 {
return res;
}
public int missingNumber2(int[] nums) {
int res = nums.length;
int res = nums.length; //异或上长度
for(int i=0; i<nums.length; i++) res^=i^nums[i];
return res;
}
......
......@@ -17,7 +17,7 @@ public class lc279 {
int[] dp = new int[n];
Arrays.fill(dp,Integer.MAX_VALUE);
for (int i = 1; i <= n ; i++) { //两个for循环
for (int j=1; j<=i ; j++) {
for (int j=1; j*j<=i ; j++) {
if(j*j==i)
dp[i-1] = 1;
if(j*j<i){
......
......@@ -3,11 +3,12 @@ package code;
* 287. Find the Duplicate Number
* 题意:n+1个数属于[1~n],找出重复的那个数
* 难度:Medium
* 分类:Array, Two Pointers, Binary Search
* 分类:Array, Two Pointers, Binary Searn+1个数属于[1~n],找出重复的那个数ch
* 思路:如果nums[i]不在对应位置,则和对应位置交换。如果对应位置上也为该数,说明这个数就是重复的数字。这个方法改变了数组。是错误的。
* 另一种方法,把问题转换成有环链表,找环的起始节点。O(n) O(1) lc142
* 二分查找,每次看一边数字的个数, O(nlog(n)) O(1)
* Tips:剑指offer原题
* lc268 lc448 lc287
*/
public class lc287 {
public int findDuplicate(int[] nums) { //该方法修改了数组,是错误的,没看清题意
......
......@@ -6,6 +6,7 @@ package code;
* 分类:Dynamic Programming
* 思路:
* Tips:Bingo!
* lc303, lc437, lc560
*/
public class lc303 {
class NumArray {
......
......@@ -11,6 +11,7 @@ import java.util.HashMap;
* Tips:https://leetcode.com/problems/house-robber-iii/discuss/79330/Step-by-step-tackling-of-the-problem
* 解答给了三种方法,递归,记忆递归,dp
* 多理解一下树的dp,核心是返回数组而不是一个数字
* lc112, lc113, lc437, lc129, lc124, lc337
*/
public class lc337 {
public class TreeNode {
......@@ -26,7 +27,7 @@ public class lc337 {
public int helper(TreeNode root, HashMap<TreeNode, Integer> mem){
if(root==null)
return 0;
if(mem.containsKey(root)) //用mem去记忆一下情况的结果,防止重复计算
if(mem.containsKey(root)) //用mem去记忆一下情况的结果,防止重复计算
return mem.get(root);
int val =0;
if(root.left!=null){
......
......@@ -11,6 +11,7 @@ import java.util.PriorityQueue;
* 思路:两种思路。 1是类似多个有序链表合并的思路,优先队列。
* 2是二分,二分的是val,看比这个val小的数是不是k
* Tips:lc23方法很像
* lc240
*/
public class lc378 {
class Cell{
......
......@@ -23,7 +23,7 @@ public class lc395 {
if( cur_uni_char==i && less_than_k_char==i) res = Math.max(res, right-left);
else if(cur_uni_char>i){ //左边推进
else if(cur_uni_char>i){ //左边推进。不在外边加上一个循环的话,就不知道怎么推荐左指针了。
while(cur_uni_char!=i){
map[s.charAt(left)-'a']--;
if(map[s.charAt(left)-'a']==0) cur_uni_char--;
......
......@@ -9,7 +9,8 @@ import java.util.HashSet;
* 思路:题意可以转换为用任意个元素组成的和等于数组和/2。可以和 lc1, lc15 3-Sum 对比。
* 0,1背包问题,递推比较简单,所以空间可以压缩成一维
* 自己想的思路其实和压缩后的0,1背包类似,但没想到该问题可以抽象为0,1背包
* Tips:
* dp[i][j] = dp[i-1][j] || dp[i-1][j-nums[i]]
* Tips:lc416, lc494
*/
public class lc416 {
public static void main(String[] args) {
......
......@@ -12,35 +12,19 @@ import java.util.HashMap;
* 递归的时候用减是否==0的方式,而不是+==sum的方式
* 和lc560有共同的思想,每个节点只需遍历一遍就可以了
* 虽然是Easy题,做好也不简单
* lc112, lc113, lc437, lc129, lc124, lc337
* lc303, lc437, lc560
*/
public class lc437 {
public static class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
public static void main(String[] args) {
TreeNode node10 = new TreeNode(10);
TreeNode node5 = new TreeNode(5);
TreeNode node3 = new TreeNode(3);
TreeNode node2 = new TreeNode(2);
TreeNode node1 = new TreeNode(1);
TreeNode noden3 = new TreeNode(-3);
TreeNode node11 = new TreeNode(11);
node10.left = node5;
node10.right = noden3;
node5.left = node3;
node5.right = node2;
node2.right = node1;
noden3.right = node11;
System.out.println(pathSum2(node10, 8));
}
public static int pathSum(TreeNode root, int sum) { //该节点作为起点
if (root == null) return 0;
......@@ -48,10 +32,8 @@ public class lc437 {
}
public static int dfs(TreeNode root, int sum) { //一条路径向下走
if (root == null)
return 0;
if (root.val == sum)
return 1 + dfs(root.left, sum - root.val) + dfs(root.right, sum - root.val);//不要直接返回1,因为可能后边节点,或节点和为0
if (root == null) return 0;
if (root.val == sum) return 1 + dfs(root.left, sum - root.val) + dfs(root.right, sum - root.val);//不要直接返回1,因为可能后边节点,或节点和为0
return dfs(root.left, sum - root.val) + dfs(root.right, sum - root.val);
}
......
......@@ -9,7 +9,7 @@ import java.util.List;
* 难度:Easy
* 分类:Array
* 思路:把对应的数字放到对应的位置,最后遍历一遍,如果位置和数字不对应,则为缺失的值。
* Tips:
* Tips:lc268 lc448 lc287
*/
public class lc448 {
public static void main(String[] args) {
......
......@@ -5,7 +5,10 @@ package code;
* 难度:Medium
* 分类:Dynamic Programming, Depth-first Search
* 思路:可以用递归+mem的方法。也可以转化为0,1背包问题,注意dp的时候把下标移位。另一种方法是转化为子数组的和为(target + sum(nums))/2的问题,求解方法类似lc416
* Tips:多抽象总结一下相关的问题,如何抽象出背包。对于这个数字,要么+,要么-,就两种情况。
* Tips:多抽象总结一下相关的问题,如何抽象出背包。对于这个数字,要么+,要么-,就两种情况。https://leetcode.com/problems/target-sum/discuss/97335/Short-Java-DP-Solution-with-Explanation
* dp[i][j] 表示前i个元素和为j的方案个数
* dp[i][j] = dp[i-1][j-nums[j]] + dp[i-1][j+nums[j]] //加减两种方案加起来
* lc416, lc494
*/
public class lc494 {
public int findTargetSumWays(int[] nums, int S) {
......
......@@ -17,14 +17,11 @@ public class lc538 {
}
int sum = 0;
public TreeNode convertBST(TreeNode root) {
helper(root);
if(root==null) return null;
convertBST(root.right);
sum += root.val;
root.val = sum;
convertBST(root.left);
return root;
}
public void helper(TreeNode root){
if(root==null) return;
helper(root.right);
root.val = root.val + sum;
sum = root.val;
helper(root.left);
}
}
package code;
/*
* 543. Diameter of Binary Tree
* 题意:树的最长路径
* 题意:树的最长路径
* 难度:Easy
* 分类:Tree
* 思路:和lc124思路一样,但lc124是Hard,这道竟然是Easy,哈哈哈
......
......@@ -9,6 +9,7 @@ import java.util.HashMap;
* 分类:Array, Hash Table
* 思路:求出累加和存在hashmap中,如果当前hashmap中存在sum-k,那么就是一个解
* Tips:经典思路,记一下。lc437有类似思想。
* lc303, lc437, lc560
*/
public class lc560 {
public int subarraySum(int[] nums, int k) {
......
......@@ -42,13 +42,11 @@ public class lc617 {
}
public TreeNode mergeTrees2(TreeNode t1, TreeNode t2) {
if (t1 == null)
return t2;
if (t2 == null)
return t1;
t1.val += t2.val;
if(t1==null) return t2; //这里注意一下,比较难想明白,可以记一下
if(t2==null) return t1;
t1.left = mergeTrees(t1.left, t2.left);
t1.right = mergeTrees(t1.right, t2.right);
t1.val += t2.val;
return t1;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册