From be6623d125bc1c7abe4c18653b87216611fa8839 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Wed, 10 Apr 2019 11:01:03 +0800 Subject: [PATCH 001/308] feat(MEDIUM): _18_fourSum --- src/pp/arithmetic/leetcode/_18_fourSum.java | 142 ++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_18_fourSum.java diff --git a/src/pp/arithmetic/leetcode/_18_fourSum.java b/src/pp/arithmetic/leetcode/_18_fourSum.java new file mode 100644 index 0000000..4bc4a1e --- /dev/null +++ b/src/pp/arithmetic/leetcode/_18_fourSum.java @@ -0,0 +1,142 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Created by wangpeng on 2019-04-10. + * 18. 四数之和 + *

+ * 给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。 + *

+ * 注意: + *

+ * 答案中不可以包含重复的四元组。 + *

+ * 示例: + *

+ * 给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。 + *

+ * 满足要求的四元组集合为: + * [ + * [-1, 0, 0, 1], + * [-2, -1, 1, 2], + * [-2, 0, 0, 2] + * ] + * + * @see 4sum + */ +public class _18_fourSum { + + public static void main(String[] args) { + _18_fourSum fourSum = new _18_fourSum(); + List> lists = fourSum.fourSum(new int[]{-3, -2, -1, 0, 0, 1, 2, 3}, 0); + for (int i = 0; i < lists.size(); i++) { + Util.printList(lists.get(i)); + } + } + + /** + * 解题思路: + * 1、先对数组进行排序 + * 2、先用四个指针i1=0,i2=1,i3=len-2,i4=len-1,分别指向数组开头和结尾两处 + * 3、先控制i1,i4不动,i2,i3向中心遍历,寻找满足条件的所有情况 + * 4、i1,i4再想内部移动,重复步骤#3 + * 5、注意遍历过程总重复数据的问题 + *

+ * 首次提交: + * 执行用时 : 77 ms, 在4Sum的Java提交中击败了64.43% 的用户 + * 内存消耗 : 39.5 MB, 在4Sum的Java提交中击败了13.83% 的用户 + * 时间复杂度在O(n^3)级别,待优化 + * 优化方案:添加一些异常情况,提前终止遍历 + * 优化提交: + * 执行用时 : 26 ms, 在4Sum的Java提交中击败了96.13% 的用户 + * 内存消耗 : 39.7 MB, 在4Sum的Java提交中击败了13.83% 的用户 + * + * @param nums + * @param target + * @return + */ + public List> fourSum(int[] nums, int target) { + List> retList = new ArrayList<>(); + int length = nums.length; + if (length < 4) { + return retList; + } + //先排序 + Arrays.sort(nums); + //定义四个指针 + int i1 = 0, i4 = length - 1; + int i2, i3; + while (i1 < length - 2) { + //添加终止条件 + if (nums[i1] * 4 > target) { + break; + } + if (i1 >= i4 - 2 || nums[i1] + nums[i4] * 3 < target) { + i1 = getNextIndex(nums, i1); + i4 = length - 1; + continue; + } + i2 = i1 + 1; + i3 = i4 - 1; + while (i2 < i3) { + int sum = nums[i1] + nums[i2] + nums[i3] + nums[i4]; + if (sum == target) { + retList.add(Arrays.asList(nums[i1], nums[i2], nums[i3], nums[i4])); + i2 = getNextIndex(nums, i2); + i3 = getPreIndex(nums, i3); + continue; + } + if (sum > target) { + i3 = getPreIndex(nums, i3); + continue; + } + if (sum < target) { + i2 = getNextIndex(nums, i2); + continue; + } + } + i4 = getPreIndex(nums, i4); + } + + return retList; + } + + /** + * 获取下个不重复index + * + * @param nums + * @param ci + * @return + */ + private int getNextIndex(int[] nums, int ci) { + int c = nums[ci]; + for (int i = ci + 1; i < nums.length; i++) { + if (nums[i] != c) { + return i; + } + } + return nums.length - 1; + } + + /** + * 取前一个不重复的index + * + * @param nums + * @param ci + * @return + */ + private int getPreIndex(int[] nums, int ci) { + int c = nums[ci]; + for (int i = ci - 1; i >= 0; i--) { + if (nums[i] != c) { + return i; + } + } + return 0; + } +} From 657bd36e409a7ed2c80f7d6bc9c8459bf6b98471 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Wed, 10 Apr 2019 11:05:49 +0800 Subject: [PATCH 002/308] docs: add _18_fourSum --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e0a5e18..ead8e0a 100644 --- a/README.md +++ b/README.md @@ -18,12 +18,16 @@ - [x] [13. 罗马数字转整数](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_13_romanToInt.java) - [x] [16. 最接近的三数之和](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_16_threeSumClosest.java) - [x] [17. 电话号码的字母组合](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_17_letterCombinations.java) -- [ ] [18. 四数之和](https://leetcode-cn.com/problems/4sum) +- [x] [18. 四数之和](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_18_fourSum.java) - [ ] [20. 有效的括号](https://leetcode-cn.com/problems/valid-parentheses) - [ ] [27. 移除元素](https://leetcode-cn.com/problems/remove-element) - [ ] [28. 实现strStr()](https://leetcode-cn.com/problems/implement-strstr) - [ ] [29. 两数相除](https://leetcode-cn.com/problems/divide-two-integers) +额外添加几道关联题目 + +- [ ] [454. 四数相加 II](https://leetcode-cn.com/problems/4sum-ii/) + ## 已解题目 > 20190404# leetcode目前已有题目1020道,免费852道 @@ -78,6 +82,7 @@ | #15 | [三数之和](https://leetcode-cn.com/problems/3sum/) | [ThreeSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_15_threeSum.java) | [数组]()、[双指针]() | Medium | | | #16 | [最接近的三数之和](https://leetcode-cn.com/problems/3sum-closest/) | [ThreeSumClosest](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_16_threeSumClosest.java) | [数组]()、[双指针]() | Medium | | | #17 | [电话号码的字母组合](https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/) | [LetterCombinations](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_17_letterCombinations.java) | [字符串]()、[回溯算法]() | Medium | | +| #18 | [四数之和](https://leetcode-cn.com/problems/4sum/) | [FourSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_18_fourSum.java) | [数组]()、[双指针]()、[哈希表]() | Medium | | | #19 | [删除链表的倒数第N个节点](https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/) | [RemoveNthFromEnd](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_19_RemoveNthFromEnd.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Medium | | | #21 | [合并两个有序链表](https://leetcode-cn.com/problems/merge-two-sorted-lists/) | [MergeTwoLists](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_21_MergeTwoLists.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Easy | | | #22 | [括号生成](https://leetcode-cn.com/problems/generate-parentheses/) | [GenerateParenthesis](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_22_generateParenthesis.java) | [字符串]()、[回溯算法]() | Medium | | From 9e9827d7956abdf2e07722fdf8b7a1f1ff327367 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 11 Apr 2019 15:04:04 +0800 Subject: [PATCH 003/308] feat(MEDIUM): _454_fourSumCount --- .../leetcode/_454_fourSumCount.java | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_454_fourSumCount.java diff --git a/src/pp/arithmetic/leetcode/_454_fourSumCount.java b/src/pp/arithmetic/leetcode/_454_fourSumCount.java new file mode 100644 index 0000000..911caca --- /dev/null +++ b/src/pp/arithmetic/leetcode/_454_fourSumCount.java @@ -0,0 +1,74 @@ +package pp.arithmetic.leetcode; + +import java.util.HashMap; + +/** + * Created by wangpeng on 2019-04-10. + * 454. 四数相加 II + *

+ * 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。 + *

+ * 为了使问题简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500 。所有整数的范围在 -228 到 228 - 1 之间,最终结果不会超过 231 - 1 。 + *

+ * 例如: + *

+ * 输入: + * A = [ 1, 2] + * B = [-2,-1] + * C = [-1, 2] + * D = [ 0, 2] + *

+ * 输出: + * 2 + *

+ * 解释: + * 两个元组如下: + * 1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0 + * 2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0 + * + * @see 4sum-ii + */ +public class _454_fourSumCount { + public static void main(String[] args) { + _454_fourSumCount fourSumCount = new _454_fourSumCount(); + System.out.println(fourSumCount.fourSumCount( + new int[]{-1, -1}, + new int[]{-1, 1}, + new int[]{-1, 1}, + new int[]{-1, 1}) + ); + } + + /** + * 最直接的方案就是四次循环拿到满足条件的计数,不过这个通不过,时间复杂度在O(n^4) + * 可行解题思路: + * 看题目关联到哈希表,所以往那个方向考虑下 + * 1、先将4个数组分层两组A+B,C+D + * 2、定义个一个hash表,存储A+B所有的结果计数 + * 3、在遍历C+D的时候,取反后,看hash表中是否存在计数 + * + * @param A + * @param B + * @param C + * @param D + * @return + */ + public int fourSumCount(int[] A, int[] B, int[] C, int[] D) { + int retCount = 0; + HashMap map = new HashMap<>(); + for (int i = 0; i < A.length; i++) { + for (int j = 0; j < B.length; j++) { + int sumAB = A[i] + B[j]; + map.put(sumAB, map.getOrDefault(sumAB, 0) + 1); + } + } + for (int i = 0; i < C.length; i++) { + for (int j = 0; j < D.length; j++) { + int sumCD = C[i] + D[j]; + retCount += map.getOrDefault(-sumCD, 0); + } + } + + return retCount; + } +} From e01f260b1456dca4bf8529dbd1dc8ab482410b6a Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 11 Apr 2019 15:06:23 +0800 Subject: [PATCH 004/308] docs: _454_fourSumCount --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ead8e0a..7f0a251 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ 额外添加几道关联题目 -- [ ] [454. 四数相加 II](https://leetcode-cn.com/problems/4sum-ii/) +- [x] [454. 四数相加 II](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_454_fourSumCount.java) ## 已解题目 @@ -181,6 +181,7 @@ | #449 | [序列化和反序列化二叉搜索树](https://leetcode-cn.com/problems/serialize-and-deserialize-bst/) | [Serialize_deserialize](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_449_serialize_deserialize.java) | [树](https://leetcode-cn.com/tag/tree/) | Medium | | | #450 | [删除二叉搜索树中的节点](https://leetcode-cn.com/problems/delete-node-in-a-bst/) | [DeleteNode](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_450_deleteNode.java) | [树](https://leetcode-cn.com/tag/tree/) | Medium | | | #452 | [用最少数量的箭引爆气球](https://leetcode-cn.com/problems/minimum-number-of-arrows-to-burst-balloons/) | [FindMinArrowShots](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_452_findMinArrowShots.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/) | Medium | | +| #454 | [四数相加 II](https://leetcode-cn.com/problems/4sum-ii/) | [FourSumCount](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_454_fourSumCount.java) | [哈希表]()、[二分查找]() | Medium | | | #455 | [分发饼干](https://leetcode-cn.com/problems/assign-cookies/) | [FindContentChildren](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_455_findContentChildren.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/) | Easy | | | #457 | [环形数组循环](https://leetcode-cn.com/problems/circular-array-loop/) | [CircularArrayLoop](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_457_circularArrayLoop.java) | [数组]()、[双指针]() | Medium | | | #460 | [LFU缓存](https://leetcode-cn.com/problems/lfu-cache/) | [LFUCache](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_460_LFUCache.java) | [设计](https://leetcode-cn.com/tag/design/) | Hard | | From 728ffd30da30473525c6293d71d934703a6731dc Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 11 Apr 2019 15:59:24 +0800 Subject: [PATCH 005/308] docs: add wx --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7f0a251..e1f5502 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,9 @@ - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 -- 尽量分析一下解题步骤和复杂度 +- 每道题会尽量分析一下解题步骤和复杂度 - 欢迎star、fork、交流,一起互勉 +- 微信号:pp_hdsny(备注leetcode) - 网址:https://leetcode-cn.com/ ## 20190408-20190415待解题目列表 From 0924adee9a8cc0c041d711766aac2afb31f57fa4 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Fri, 12 Apr 2019 10:10:44 +0800 Subject: [PATCH 006/308] feat(EASY): _20_isValid --- src/pp/arithmetic/leetcode/_20_isValid.java | 93 +++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_20_isValid.java diff --git a/src/pp/arithmetic/leetcode/_20_isValid.java b/src/pp/arithmetic/leetcode/_20_isValid.java new file mode 100644 index 0000000..665e4eb --- /dev/null +++ b/src/pp/arithmetic/leetcode/_20_isValid.java @@ -0,0 +1,93 @@ +package pp.arithmetic.leetcode; + +import java.util.Stack; + +/** + * Created by wangpeng on 2019-04-12. + * 20. 有效的括号 + *

+ * 给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。 + *

+ * 有效字符串需满足: + *

+ * 左括号必须用相同类型的右括号闭合。 + * 左括号必须以正确的顺序闭合。 + * 注意空字符串可被认为是有效字符串。 + *

+ * 示例 1: + *

+ * 输入: "()" + * 输出: true + * 示例 2: + *

+ * 输入: "()[]{}" + * 输出: true + * 示例 3: + *

+ * 输入: "(]" + * 输出: false + * 示例 4: + *

+ * 输入: "([)]" + * 输出: false + * 示例 5: + *

+ * 输入: "{[]}" + * 输出: true + * + * @see valid-parentheses + */ +public class _20_isValid { + public static void main(String[] args) { + _20_isValid valid = new _20_isValid(); + System.out.println(valid.isValid("()")); + System.out.println(valid.isValid("()[]{}")); + System.out.println(valid.isValid("(]")); + System.out.println(valid.isValid("([)]")); + System.out.println(valid.isValid("{[]}")); + } + + /** + * 解题思路: + * 需要知道是否有效,也就是左右得成对出现,利用栈去做存储 + * 1、左括号时,则入栈 + * 2、有括号时,则判断栈顶是否是配套左括号,如是则将其出栈,否则无效 + * 3、遍历完成后,如栈空则有效,反则无效 + * + * @param s + * @return + */ + public boolean isValid(String s) { + Stack stack = new Stack<>(); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '(' || c == '{' || c == '[') { + stack.push(c); + } else { + if (stack.isEmpty()){ + return false; + } + Character pop = stack.pop(); + switch (c) { + case ')': + if (pop != '(') { + return false; + } + break; + case '}': + if (pop != '{') { + return false; + } + break; + case ']': + if (pop != '[') { + return false; + } + break; + } + } + } + + return stack.isEmpty(); + } +} From a45f03da63e7dc2fb4ca4e09f7d2c26dd124361e Mon Sep 17 00:00:00 2001 From: wangpeng Date: Fri, 12 Apr 2019 10:15:52 +0800 Subject: [PATCH 007/308] docs: add _20_isValid --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e1f5502..ca86c79 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ - [x] [16. 最接近的三数之和](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_16_threeSumClosest.java) - [x] [17. 电话号码的字母组合](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_17_letterCombinations.java) - [x] [18. 四数之和](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_18_fourSum.java) -- [ ] [20. 有效的括号](https://leetcode-cn.com/problems/valid-parentheses) +- [x] [20. 有效的括号](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_20_isValid.java) - [ ] [27. 移除元素](https://leetcode-cn.com/problems/remove-element) - [ ] [28. 实现strStr()](https://leetcode-cn.com/problems/implement-strstr) - [ ] [29. 两数相除](https://leetcode-cn.com/problems/divide-two-integers) @@ -29,6 +29,10 @@ - [x] [454. 四数相加 II](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_454_fourSumCount.java) +- [ ] [32. 最长有效括号-Hard](https://leetcode-cn.com/problems/longest-valid-parentheses/) + +- [ ] [301. 删除无效的括号-Hard](https://leetcode-cn.com/problems/remove-invalid-parentheses/) + ## 已解题目 > 20190404# leetcode目前已有题目1020道,免费852道 @@ -85,6 +89,7 @@ | #17 | [电话号码的字母组合](https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/) | [LetterCombinations](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_17_letterCombinations.java) | [字符串]()、[回溯算法]() | Medium | | | #18 | [四数之和](https://leetcode-cn.com/problems/4sum/) | [FourSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_18_fourSum.java) | [数组]()、[双指针]()、[哈希表]() | Medium | | | #19 | [删除链表的倒数第N个节点](https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/) | [RemoveNthFromEnd](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_19_RemoveNthFromEnd.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Medium | | +| #20 | [有效的括号](https://leetcode-cn.com/problems/valid-parentheses/) | [IsValid](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_20_isValid.java) | [栈](https://leetcode-cn.com/tag/stack/)、[字符串]() | Easy | | | #21 | [合并两个有序链表](https://leetcode-cn.com/problems/merge-two-sorted-lists/) | [MergeTwoLists](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_21_MergeTwoLists.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Easy | | | #22 | [括号生成](https://leetcode-cn.com/problems/generate-parentheses/) | [GenerateParenthesis](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_22_generateParenthesis.java) | [字符串]()、[回溯算法]() | Medium | | | #23 | [合并K个排序链表](https://leetcode-cn.com/problems/merge-k-sorted-lists/) | [MergeKLists](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_23_mergeKLists.java) | [堆](https://leetcode-cn.com/tag/heap/)、[链表](https://leetcode-cn.com/tag/linked-list/)、[分治算法]() | Hard | | From 0276636d6f29d19e7199523754662ce5254de932 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 15 Apr 2019 09:43:39 +0800 Subject: [PATCH 008/308] docs: update doc --- README.md | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/README.md b/README.md index ca86c79..fbf4c0e 100644 --- a/README.md +++ b/README.md @@ -11,26 +11,12 @@ - 欢迎star、fork、交流,一起互勉 - 微信号:pp_hdsny(备注leetcode) - 网址:https://leetcode-cn.com/ -## 20190408-20190415待解题目列表 +## 20190415-20190422待解题目列表 -共9道题目,4道Easy,5道Medium - -- [x] [12. 整数转罗马数字](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_12_intToRoman.java) -- [x] [13. 罗马数字转整数](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_13_romanToInt.java) -- [x] [16. 最接近的三数之和](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_16_threeSumClosest.java) -- [x] [17. 电话号码的字母组合](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_17_letterCombinations.java) -- [x] [18. 四数之和](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_18_fourSum.java) -- [x] [20. 有效的括号](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_20_isValid.java) - [ ] [27. 移除元素](https://leetcode-cn.com/problems/remove-element) - [ ] [28. 实现strStr()](https://leetcode-cn.com/problems/implement-strstr) - [ ] [29. 两数相除](https://leetcode-cn.com/problems/divide-two-integers) - -额外添加几道关联题目 - -- [x] [454. 四数相加 II](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_454_fourSumCount.java) - - [ ] [32. 最长有效括号-Hard](https://leetcode-cn.com/problems/longest-valid-parentheses/) - - [ ] [301. 删除无效的括号-Hard](https://leetcode-cn.com/problems/remove-invalid-parentheses/) ## 已解题目 From d36bc9bce739c058293113c7761d4751caaa4b9b Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 15 Apr 2019 14:53:53 +0800 Subject: [PATCH 009/308] feat(EASY):add _27_removeElement --- .../leetcode/_27_removeElement.java | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_27_removeElement.java diff --git a/src/pp/arithmetic/leetcode/_27_removeElement.java b/src/pp/arithmetic/leetcode/_27_removeElement.java new file mode 100644 index 0000000..a61ca67 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_27_removeElement.java @@ -0,0 +1,100 @@ +package pp.arithmetic.leetcode; + +import java.util.Arrays; +import java.util.Collections; + +/** + * Created by wangpeng on 2019-04-15. + * 27. 移除元素 + *

+ * 给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。 + *

+ * 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 + *

+ * 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。 + *

+ * 示例 1: + *

+ * 给定 nums = [3,2,2,3], val = 3, + *

+ * 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 + *

+ * 你不需要考虑数组中超出新长度后面的元素。 + * 示例 2: + *

+ * 给定 nums = [0,1,2,2,3,0,4,2], val = 2, + *

+ * 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。 + *

+ * 注意这五个元素可为任意顺序。 + *

+ * 你不需要考虑数组中超出新长度后面的元素。 + * 说明: + *

+ * 为什么返回数值是整数,但输出的答案是数组呢? + *

+ * 请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。 + *

+ * 你可以想象内部操作如下: + *

+ * // nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝 + * int len = removeElement(nums, val); + *

+ * // 在函数里修改输入数组对于调用者是可见的。 + * // 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。 + * for (int i = 0; i < len; i++) { + * print(nums[i]); + * } + * + * @see remove-element + */ +public class _27_removeElement { + + public static void main(String[] args) { + _27_removeElement element = new _27_removeElement(); + System.out.println(element.removeElement(new int[]{3, 2, 2, 3}, 3)); + System.out.println(element.removeElement(new int[]{0, 1, 2, 2, 3, 0, 4, 2}, 2)); + System.out.println(element.removeElement(new int[]{3, 1, 0}, 11)); + } + + /** + * 解题思路: + * 难点在O(1)的空间复杂度,需要原地修改 + * 1、先对数组进行排序 + * 2、找到==val的起始位置和终止位置 + * 3、将终止位置后的数字前移至起始位置 + * + * @param nums + * @param val + * @return + */ + public int removeElement(int[] nums, int val) { + //1、排序 + Arrays.sort(nums); + //2、找到起始和结束位置 + int len = nums.length; + int si = 0, ei = len - 1; + while (si <= ei) { + if (nums[si] == val && nums[ei] == val) { + //3、前移 + int temp = si; + for (int i = ei + 1; i < len; i++) { + nums[temp] = nums[i]; + temp++; + } + return len - ei + si - 1; + } + if (nums[si] != val) { + si++; + } + if (nums[ei] != val) { + ei--; + } + } + if (len % 2 == 0) { + return len - ei + si - 1; + } else { + return len - ei + si - 2; + } + } +} From b2dbdc1d0f0252ff993e9dafa7b1833a88f7930f Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 15 Apr 2019 14:56:40 +0800 Subject: [PATCH 010/308] docs: add _27_removeElement --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fbf4c0e..fa39b5a 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ - 网址:https://leetcode-cn.com/ ## 20190415-20190422待解题目列表 -- [ ] [27. 移除元素](https://leetcode-cn.com/problems/remove-element) +- [x] [27. 移除元素-Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_27_removeElement.java) - [ ] [28. 实现strStr()](https://leetcode-cn.com/problems/implement-strstr) - [ ] [29. 两数相除](https://leetcode-cn.com/problems/divide-two-integers) - [ ] [32. 最长有效括号-Hard](https://leetcode-cn.com/problems/longest-valid-parentheses/) @@ -82,6 +82,7 @@ | #24 | [两两交换链表中的节点](https://leetcode-cn.com/problems/swap-nodes-in-pairs/) | [SwapPairs](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_24_SwapPairs.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | | #25 | [k个一组翻转链表](https://leetcode-cn.com/problems/reverse-nodes-in-k-group/) | [ReverseKGroup](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_25_reverseKGroup.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Hard | | | #26 | [删除排序数组中的重复项](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/) | [RemoveDuplicates](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_26_removeDuplicates.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Easy | | +| #27 | [移除元素](https://leetcode-cn.com/problems/remove-element/) | [RemoveElement](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_27_removeElement.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Easy | | | #33 | [搜索旋转排序数组](https://leetcode-cn.com/problems/search-in-rotated-sorted-array/) | [Search](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_33_search.java) | [数组]()、[二分查找]() | Medium | | | #34 | [在排序数组中查找元素的第一个和最后一个位置](https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/) | [SearchRange](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_34_searchRange.java) | [数组]()、[二分查找]() | Medium | | | #35 | [搜索插入位置](https://leetcode-cn.com/problems/search-insert-position/) | [SearchInsert](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_35_searchInsert.java) | [数组]()、[二分查找]() | Easy | | From e14abdf86457636eb53283755430c43358ecdc91 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 15 Apr 2019 15:14:38 +0800 Subject: [PATCH 011/308] =?UTF-8?q?refactor:=20=E6=9B=B4=E6=96=B0=5F27=5Fr?= =?UTF-8?q?emoveElement=E8=A7=A3=E6=B3=95=E4=BA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../leetcode/_27_removeElement.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/pp/arithmetic/leetcode/_27_removeElement.java b/src/pp/arithmetic/leetcode/_27_removeElement.java index a61ca67..b7eaab9 100644 --- a/src/pp/arithmetic/leetcode/_27_removeElement.java +++ b/src/pp/arithmetic/leetcode/_27_removeElement.java @@ -55,6 +55,10 @@ public static void main(String[] args) { System.out.println(element.removeElement(new int[]{3, 2, 2, 3}, 3)); System.out.println(element.removeElement(new int[]{0, 1, 2, 2, 3, 0, 4, 2}, 2)); System.out.println(element.removeElement(new int[]{3, 1, 0}, 11)); + //解法二 + System.out.println(element.removeElement2(new int[]{3, 2, 2, 3}, 3)); + System.out.println(element.removeElement2(new int[]{0, 1, 2, 2, 3, 0, 4, 2}, 2)); + System.out.println(element.removeElement2(new int[]{3, 1, 0}, 11)); } /** @@ -63,6 +67,8 @@ public static void main(String[] args) { * 1、先对数组进行排序 * 2、找到==val的起始位置和终止位置 * 3、将终止位置后的数字前移至起始位置 + *

+ * 更新一个更简洁的写法 {@link _27_removeElement#removeElement2(int[], int)} * * @param nums * @param val @@ -97,4 +103,26 @@ public int removeElement(int[] nums, int val) { return len - ei + si - 2; } } + + /** + * 解法二,写法更简洁 + * + * @param nums + * @param val + * @return + */ + public int removeElement2(int[] nums, int val) { + + int retLen = 0; + int insertIndex = 0; + for (int i = 0; i < nums.length; i++) { + if (nums[i] == val) { + continue; + } + nums[insertIndex++] = nums[i]; + retLen++; + } + + return retLen; + } } From e49ad6937af995fd6be1f660b8a6859b05d4e449 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 15 Apr 2019 16:40:08 +0800 Subject: [PATCH 012/308] feat(EASY): add _28_strStr --- src/pp/arithmetic/leetcode/_28_strStr.java | 73 ++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_28_strStr.java diff --git a/src/pp/arithmetic/leetcode/_28_strStr.java b/src/pp/arithmetic/leetcode/_28_strStr.java new file mode 100644 index 0000000..437aeae --- /dev/null +++ b/src/pp/arithmetic/leetcode/_28_strStr.java @@ -0,0 +1,73 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-04-15. + * 28. 实现strStr() + *

+ * 实现 strStr() 函数。 + *

+ * 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。 + *

+ * 示例 1: + *

+ * 输入: haystack = "hello", needle = "ll" + * 输出: 2 + * 示例 2: + *

+ * 输入: haystack = "aaaaa", needle = "bba" + * 输出: -1 + * 说明: + *

+ * 当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。 + *

+ * 对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。 + * + * @see implement-strstr + */ +public class _28_strStr { + public static void main(String[] args) { + _28_strStr str = new _28_strStr(); + System.out.println(str.strStr("hello", "ll")); + System.out.println(str.strStr("aaaaa", "aab")); + System.out.println(str.strStr("a", "a")); + System.out.println(str.strStr("babbbbbabb", "bbab")); + } + + /** + * 解题思路 + * 本题是实现Java字符串中的 {@link String#indexOf(String)}方法 + * 1、开始遍历 haystack,找到和 needle 相同的起始下标si + * 2、从si开始同时遍历 haystack和needle + * 3、如遍历过程中一直相同,则返回si,否则si后移1位 + * + * @param haystack + * @param needle + * @return + */ + public int strStr(String haystack, String needle) { + if (needle.length() == 0) { + return 0; + } + if (haystack.length() < needle.length()) { + return -1; + } + int ei; + for (int i = 0; i < haystack.length() - needle.length() + 1; i++) { + if (haystack.charAt(i) == needle.charAt(0)) { + ei = i; + for (int j = 1; j < needle.length(); j++) { + if (haystack.charAt(++ei) != needle.charAt(j)) { + break; + } + } + if (haystack.charAt(ei) == needle.charAt(ei - i)) { + //找到了 + return i; + } + } + } + + + return -1; + } +} From a5b17060a2b48d48761e6373aaf46723d5264c29 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 15 Apr 2019 16:43:01 +0800 Subject: [PATCH 013/308] docs: add _28_strStr --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fa39b5a..39de701 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ ## 20190415-20190422待解题目列表 - [x] [27. 移除元素-Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_27_removeElement.java) -- [ ] [28. 实现strStr()](https://leetcode-cn.com/problems/implement-strstr) +- [x] [28. 实现strStr()-Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_28_strStr.java) - [ ] [29. 两数相除](https://leetcode-cn.com/problems/divide-two-integers) - [ ] [32. 最长有效括号-Hard](https://leetcode-cn.com/problems/longest-valid-parentheses/) - [ ] [301. 删除无效的括号-Hard](https://leetcode-cn.com/problems/remove-invalid-parentheses/) @@ -82,7 +82,8 @@ | #24 | [两两交换链表中的节点](https://leetcode-cn.com/problems/swap-nodes-in-pairs/) | [SwapPairs](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_24_SwapPairs.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | | #25 | [k个一组翻转链表](https://leetcode-cn.com/problems/reverse-nodes-in-k-group/) | [ReverseKGroup](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_25_reverseKGroup.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Hard | | | #26 | [删除排序数组中的重复项](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/) | [RemoveDuplicates](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_26_removeDuplicates.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Easy | | -| #27 | [移除元素](https://leetcode-cn.com/problems/remove-element/) | [RemoveElement](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_27_removeElement.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Easy | | +| #27 | [移除元素](https://leetcode-cn.com/problems/remove-element/) | [RemoveElement](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_27_removeElement.java) | [数组]()、[双指针]() | Easy | | +| #28 | [实现strStr()](https://leetcode-cn.com/problems/implement-strstr/) | [StrStr](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_28_strStr.java) | [双指针]()、[字符串]() | Easy | | | #33 | [搜索旋转排序数组](https://leetcode-cn.com/problems/search-in-rotated-sorted-array/) | [Search](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_33_search.java) | [数组]()、[二分查找]() | Medium | | | #34 | [在排序数组中查找元素的第一个和最后一个位置](https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/) | [SearchRange](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_34_searchRange.java) | [数组]()、[二分查找]() | Medium | | | #35 | [搜索插入位置](https://leetcode-cn.com/problems/search-insert-position/) | [SearchInsert](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_35_searchInsert.java) | [数组]()、[二分查找]() | Easy | | From a15e6fadba0cfe105a1802923e42e76c256b932c Mon Sep 17 00:00:00 2001 From: wangpeng Date: Tue, 16 Apr 2019 11:46:13 +0800 Subject: [PATCH 014/308] feat(MEDIUM): add _29_divide --- src/pp/arithmetic/leetcode/_29_divide.java | 131 +++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_29_divide.java diff --git a/src/pp/arithmetic/leetcode/_29_divide.java b/src/pp/arithmetic/leetcode/_29_divide.java new file mode 100644 index 0000000..4ac6ce6 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_29_divide.java @@ -0,0 +1,131 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-04-15. + * 29. 两数相除 + *

+ * 给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。 + *

+ * 返回被除数 dividend 除以除数 divisor 得到的商。 + *

+ * 示例 1: + *

+ * 输入: dividend = 10, divisor = 3 + * 输出: 3 + * 示例 2: + *

+ * 输入: dividend = 7, divisor = -3 + * 输出: -2 + * 说明: + *

+ * 被除数和除数均为 32 位有符号整数。 + * 除数不为 0。 + * 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−2^31, 2^31 − 1]。本题中,如果除法结果溢出,则返回 2^31 − 1。 + * + * @see divide-two-integers + */ +public class _29_divide { + + public static void main(String[] args) { + _29_divide divide = new _29_divide(); + System.out.println(divide.divide2(10, 3)); + System.out.println(divide.divide2(7, -3)); + System.out.println(divide.divide2(-7, -3)); + System.out.println(divide.divide2(-2147483648, -1)); + System.out.println(divide.divide2(-2, 2)); + System.out.println(divide.divide2(2, 2)); + System.out.println(divide.divide2(Integer.MAX_VALUE, 2)); + } + + /** + * 解法二 + * 除法的本质起始是看除数中包含多少个被除数,可以利用乘法或者位移使被除数不断变大,直到大于除数 + * 由于题目中不允许使用乘法,所以考虑用位移的方式进行计算 <<1 <==> *2 + * 1.divisor << 1,直至 > dividend,得到cnt + * 2.dividend = dividend-divisor<<(cnt-1) + * 3.重复第一步拿到最终结果 + * 要注意正负值和边界情况 + * 时间复杂度O(logn) + * + * @param dividend + * @param divisor + * @return + */ + public int divide2(int dividend, int divisor) { + if (dividend == 0) return 0; + if (divisor == 1) return dividend; + if (divisor == -1) { + if (dividend == Integer.MIN_VALUE) { + return Integer.MAX_VALUE; + } + if (dividend == Integer.MAX_VALUE) { + return Integer.MIN_VALUE; + } + return -dividend; + } + int ret = 0; + long absDividend = Math.abs((long)dividend); + long absDivisor = Math.abs((long)divisor); + while (absDividend >= absDivisor) { + int cnt = 1; + while ((absDivisor << cnt) <= absDividend) + cnt++; + ret += 1 << (cnt - 1); + absDividend -= absDivisor << (cnt - 1); + } + return ((dividend ^ divisor) < 0) ? -ret : ret; + } + + /** + * 解题思路: + * 1、不使用乘法、除法和 mod 运算符,那就只能使用加减法了 + * 2、for循环不断相减得到结果 + * 要注意正负值和边界情况 + *

+ * 此种解法,对于超级大的dividend和超级小的divisor的话,耗时会很长=>O(n) + * 见解法二 {@link _29_divide#divide2(int, int)} + * + * @param dividend + * @param divisor + * @return + */ + public int divide(int dividend, int divisor) { + if (divisor == 1) { + return dividend; + } + if (divisor == -1) { + if (dividend == Integer.MIN_VALUE) { + return Integer.MAX_VALUE; + } + if (dividend == Integer.MAX_VALUE) { + return Integer.MIN_VALUE; + } + return -dividend; + } + + int ret = 0; + //异或 + int xor = dividend ^ divisor; + if (xor == 0) { + return 1; + } else if (xor > 0) { + //相同运算符 + while ((dividend ^ divisor) > 0) { + dividend -= divisor; + if ((dividend ^ divisor) >= 0 || dividend == 0) { + ret++; + } + } + } else { + //不同运算符 + while ((dividend ^ divisor) < 0) { + dividend += divisor; + if ((dividend ^ divisor) <= 0 || dividend == 0) { + ret--; + } + } + } + + return ret; + } +} From 8e713b1a1ce25342c3e811fb127cf6f3c58df650 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Tue, 16 Apr 2019 11:52:12 +0800 Subject: [PATCH 015/308] docs: add _29_divide --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 39de701..3369d2d 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,17 @@ ## 20190415-20190422待解题目列表 - [x] [27. 移除元素-Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_27_removeElement.java) + - [x] [28. 实现strStr()-Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_28_strStr.java) -- [ ] [29. 两数相除](https://leetcode-cn.com/problems/divide-two-integers) + +- [x] [29. 两数相除-Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_29_divide.java) + +- [ ] [30. 串联所有单词的子串-Hard](https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words/) + +- [ ] [31. 下一个排列-Medium](https://leetcode-cn.com/problems/next-permutation/) + - [ ] [32. 最长有效括号-Hard](https://leetcode-cn.com/problems/longest-valid-parentheses/) + - [ ] [301. 删除无效的括号-Hard](https://leetcode-cn.com/problems/remove-invalid-parentheses/) ## 已解题目 @@ -84,6 +92,7 @@ | #26 | [删除排序数组中的重复项](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/) | [RemoveDuplicates](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_26_removeDuplicates.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Easy | | | #27 | [移除元素](https://leetcode-cn.com/problems/remove-element/) | [RemoveElement](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_27_removeElement.java) | [数组]()、[双指针]() | Easy | | | #28 | [实现strStr()](https://leetcode-cn.com/problems/implement-strstr/) | [StrStr](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_28_strStr.java) | [双指针]()、[字符串]() | Easy | | +| #29 | [两数相除](https://leetcode-cn.com/problems/divide-two-integers/) | [Divide](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_29_divide.java) | [数学]()、[二分查找]() | Medium | | | #33 | [搜索旋转排序数组](https://leetcode-cn.com/problems/search-in-rotated-sorted-array/) | [Search](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_33_search.java) | [数组]()、[二分查找]() | Medium | | | #34 | [在排序数组中查找元素的第一个和最后一个位置](https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/) | [SearchRange](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_34_searchRange.java) | [数组]()、[二分查找]() | Medium | | | #35 | [搜索插入位置](https://leetcode-cn.com/problems/search-insert-position/) | [SearchInsert](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_35_searchInsert.java) | [数组]()、[二分查找]() | Easy | | From 72788326280759597759ca43a9c6b6b3ff7f61bb Mon Sep 17 00:00:00 2001 From: wangpeng Date: Wed, 17 Apr 2019 15:57:29 +0800 Subject: [PATCH 016/308] feat(HARD): add _30_findSubstring --- .../leetcode/_30_findSubstring.java | 157 ++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_30_findSubstring.java diff --git a/src/pp/arithmetic/leetcode/_30_findSubstring.java b/src/pp/arithmetic/leetcode/_30_findSubstring.java new file mode 100644 index 0000000..ac459a4 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_30_findSubstring.java @@ -0,0 +1,157 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by wangpeng on 2019-04-17. + * 30. 串联所有单词的子串 + *

+ * 给定一个字符串 s 和一些长度相同的单词 words。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。 + *

+ * 注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。 + *

+ *

+ *

+ * 示例 1: + *

+ * 输入: + * s = "barfoothefoobarman", + * words = ["foo","bar"] + * 输出:[0,9] + * 解释: + * 从索引 0 和 9 开始的子串分别是 "barfoor" 和 "foobar" 。 + * 输出的顺序不重要, [9,0] 也是有效答案。 + * 示例 2: + *

+ * 输入: + * s = "wordgoodgoodgoodbestword", + * words = ["word","good","best","word"] + * 输出:[] + * + * @see substring-with-concatenation-of-all-words + */ +public class _30_findSubstring { + + public static void main(String[] args) { + _30_findSubstring findSubstring = new _30_findSubstring(); + List list = findSubstring.findSubstring("barfoothefoobarman", new String[]{"foo", "bar"}); + Util.printList(list); + List list1 = findSubstring.findSubstring2("wordgoodgoodgoodbestword", new String[]{"word", "good", "best", "good"}); + Util.printList(list1); + } + + /** + * 解题思路: + * 这是一道字符串中找单词的问题,需要找到单词的位置,不可能每次都循环遍历,由于是字符串的问题可以考虑用哈希表 + * 1、遍历单词,哈希表储存每个单词出现的次数 + * 2、遍历字符串,按单词长度跳跃,找到每个单词出现的次数 + * 3、次数超过对于单词或者未找到相应匹配,则跳过 + *

+ * 执行用时 : 242 ms, 在Substring with Concatenation of All Words的Java提交中击败了45.27% 的用户 + * 内存消耗 : 63.2 MB, 在Substring with Concatenation of All Words的Java提交中击败了33.24% 的用户 + *

+ * 通过提交leetcode来看,效率并不是很高,分析下时间复杂度在O(n^2) + *

+ * 优化方案 {@link _30_findSubstring#findSubstring2(String, String[])} + * + * @param s + * @param words + * @return + */ + public List findSubstring(String s, String[] words) { + List retList = new ArrayList<>(); + if (words.length == 0) { + return retList; + } + int wordLen = words[0].length(); + HashMap map = new HashMap<>(); + for (int i = 0; i < words.length; i++) { + map.put(words[i], map.getOrDefault(words[i], 0) + 1); + } + int si = 0, ei; + HashMap iteMap = new HashMap<>(); + int forLen = s.length() - words.length * wordLen; + while (si <= forLen) { + ei = si; + while (ei <= s.length() - wordLen) { + String item = s.substring(ei, ei + wordLen); + if (map.getOrDefault(item, 0) == 0) { + si++; + iteMap.clear(); + break; + } + //遍历次数 + int iteCount = iteMap.getOrDefault(item, 0); + iteMap.put(item, ++iteCount); + if (iteCount > map.get(item)) { + //出现次数已超过 + si++; + iteMap.clear(); + break; + } + ei += wordLen; + if (ei - si == words.length * wordLen) { + //找到满足条件的 + retList.add(si); + si++; + iteMap.clear(); + break; + } + } + } + + return retList; + } + + + /** + * 优化方案二:leetcode解题 + * + * 执行用时 : 27 ms, 在Substring with Concatenation of All Words的Java提交中击败了93.31% 的用户 + * 内存消耗 : 44.8 MB, 在Substring with Concatenation of All Words的Java提交中击败了78.98% 的用户 + * + * 大体思路和方案一一致,优化的点是减少了无效的循环次数fori,重复利用了forj不满足条件后的平移 + * + * + * @param s + * @param words + * @return + */ + public List findSubstring2(String s, String[] words) { + if (words.length == 0) + return new ArrayList<>(); + int num = 0; + List res = new ArrayList<>(); + Map wordsCount = new HashMap<>(); + Map usedWords = new HashMap<>(); + for (String w : words) + wordsCount.put(w, wordsCount.getOrDefault(w, 0) + 1); + int wlen = words[0].length(); + for (int i = 0; i < wlen; i++, num = 0, usedWords.clear()) { + for (int j = i; j + wlen <= s.length(); j += wlen) { + String sub = s.substring(j, j + wlen); + if (wordsCount.containsKey(sub)) { + num++; + usedWords.put(sub, usedWords.getOrDefault(sub, 0) + 1); + while (usedWords.get(sub) > wordsCount.get(sub)) { + String rem = s.substring(j - (num - 1) * wlen, j - (num - 2) * wlen); + usedWords.put(rem, usedWords.get(rem) - 1); + num--; + } + } else { + num = 0; + usedWords.clear(); + } + if (num == words.length) { + res.add(j - (num - 1) * wlen); + } + } + } + return res; + } +} From a5c0a52701b3356062e6c552db50cb8868b40cfd Mon Sep 17 00:00:00 2001 From: wangpeng Date: Wed, 17 Apr 2019 16:23:34 +0800 Subject: [PATCH 017/308] docs: add _30_findSubstring --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3369d2d..bba7679 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ - [x] [29. 两数相除-Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_29_divide.java) -- [ ] [30. 串联所有单词的子串-Hard](https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words/) +- [x] [30. 串联所有单词的子串-Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_30_findSubstring.java) - [ ] [31. 下一个排列-Medium](https://leetcode-cn.com/problems/next-permutation/) @@ -93,6 +93,7 @@ | #27 | [移除元素](https://leetcode-cn.com/problems/remove-element/) | [RemoveElement](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_27_removeElement.java) | [数组]()、[双指针]() | Easy | | | #28 | [实现strStr()](https://leetcode-cn.com/problems/implement-strstr/) | [StrStr](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_28_strStr.java) | [双指针]()、[字符串]() | Easy | | | #29 | [两数相除](https://leetcode-cn.com/problems/divide-two-integers/) | [Divide](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_29_divide.java) | [数学]()、[二分查找]() | Medium | | +| #30 | [串联所有单词的子串](https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words/) | [FindSubstring](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_30_findSubstring.java) | [哈希表]()、[双指针]()、[字符串]() | Hard | | | #33 | [搜索旋转排序数组](https://leetcode-cn.com/problems/search-in-rotated-sorted-array/) | [Search](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_33_search.java) | [数组]()、[二分查找]() | Medium | | | #34 | [在排序数组中查找元素的第一个和最后一个位置](https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/) | [SearchRange](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_34_searchRange.java) | [数组]()、[二分查找]() | Medium | | | #35 | [搜索插入位置](https://leetcode-cn.com/problems/search-insert-position/) | [SearchInsert](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_35_searchInsert.java) | [数组]()、[二分查找]() | Easy | | From a48e7cf78dedb75cc5d0c470626fc4a5b89bcd7a Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 18 Apr 2019 11:18:43 +0800 Subject: [PATCH 018/308] feat(MEDIUM): add _31_nextPermutation --- .../leetcode/_31_nextPermutation.java | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_31_nextPermutation.java diff --git a/src/pp/arithmetic/leetcode/_31_nextPermutation.java b/src/pp/arithmetic/leetcode/_31_nextPermutation.java new file mode 100644 index 0000000..68a6e1c --- /dev/null +++ b/src/pp/arithmetic/leetcode/_31_nextPermutation.java @@ -0,0 +1,82 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +import java.util.Arrays; + +/** + * Created by wangpeng on 2019-04-18. + * 31. 下一个排列 + *

+ * 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。 + *

+ * 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。 + *

+ * 必须原地修改,只允许使用额外常数空间。 + *

+ * 以下是一些例子,输入位于左侧列,其相应输出位于右侧列。 + * 1,2,3 → 1,3,2 + * 3,2,1 → 1,2,3 + * 1,1,5 → 1,5,1 + * + * @see next-permutation + */ +public class _31_nextPermutation { + + public static void main(String[] args) { + _31_nextPermutation permutation = new _31_nextPermutation(); + int[] nums = new int[]{1, 2, 3, 4, 7, 5, 6}; + Util.printArray(nums); + permutation.nextPermutation(nums); + Util.printArray(nums); + permutation.nextPermutation(nums); + Util.printArray(nums); + } + + /** + * 解题思路: + * 必须原地修改,代表只能数组内替换,而不能借助新的数组 + * 如:1 2 4 5 3 + * 1、从尾部开始遍历,找到刚开始递减的数字 4 + * 2、从 4 后面找比4最小的数字 5 + * 3、将 4 和 5 替换 + * 4、后续数组升序排列 1 2 5 3 4 + * + * @param nums + */ + public void nextPermutation(int[] nums) { + if (nums.length <= 1) { + return; + } + int pNum = nums[nums.length - 1]; + //找到开始递减的index + int cIndex = -1; + for (int i = nums.length - 2; i >= 0; i--) { + int cNum = nums[i]; + if (cNum < pNum) { + cIndex = i; + break; + } + pNum = cNum; + } + if (cIndex == -1) { + //没有找到,全数组重新升序排列 + Arrays.sort(nums); + return; + } + //找满足条件的替换值 + int rIndex = cIndex + 1; + for (int i = cIndex + 1; i < nums.length; i++) { + if (nums[i] <= nums[cIndex]) { + break; + } + rIndex = i; + } + //替换 + int temp = nums[cIndex]; + nums[cIndex] = nums[rIndex]; + nums[rIndex] = temp; + //剩下的重新排序 + Arrays.sort(nums, cIndex + 1, nums.length); + } +} From e129876c74fbdf3db0c577eef9718247cccb42be Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 18 Apr 2019 11:21:18 +0800 Subject: [PATCH 019/308] docs: add _31_nextPermutation --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bba7679..4aa4f7a 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ - [x] [30. 串联所有单词的子串-Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_30_findSubstring.java) -- [ ] [31. 下一个排列-Medium](https://leetcode-cn.com/problems/next-permutation/) +- [x] [31. 下一个排列-Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_31_nextPermutation.java) - [ ] [32. 最长有效括号-Hard](https://leetcode-cn.com/problems/longest-valid-parentheses/) @@ -94,6 +94,7 @@ | #28 | [实现strStr()](https://leetcode-cn.com/problems/implement-strstr/) | [StrStr](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_28_strStr.java) | [双指针]()、[字符串]() | Easy | | | #29 | [两数相除](https://leetcode-cn.com/problems/divide-two-integers/) | [Divide](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_29_divide.java) | [数学]()、[二分查找]() | Medium | | | #30 | [串联所有单词的子串](https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words/) | [FindSubstring](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_30_findSubstring.java) | [哈希表]()、[双指针]()、[字符串]() | Hard | | +| #31 | [下一个排列](https://leetcode-cn.com/problems/next-permutation/) | [NextPermutation](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_31_nextPermutation.java) | [数组]() | Medium | | | #33 | [搜索旋转排序数组](https://leetcode-cn.com/problems/search-in-rotated-sorted-array/) | [Search](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_33_search.java) | [数组]()、[二分查找]() | Medium | | | #34 | [在排序数组中查找元素的第一个和最后一个位置](https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/) | [SearchRange](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_34_searchRange.java) | [数组]()、[二分查找]() | Medium | | | #35 | [搜索插入位置](https://leetcode-cn.com/problems/search-insert-position/) | [SearchInsert](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_35_searchInsert.java) | [数组]()、[二分查找]() | Easy | | From c5e60ea8dff60decd5baa11a6a39d4bdaf4a8244 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Fri, 19 Apr 2019 14:40:15 +0800 Subject: [PATCH 020/308] feat(HARD): add _32_longestValidParentheses --- .../leetcode/_32_longestValidParentheses.java | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_32_longestValidParentheses.java diff --git a/src/pp/arithmetic/leetcode/_32_longestValidParentheses.java b/src/pp/arithmetic/leetcode/_32_longestValidParentheses.java new file mode 100644 index 0000000..c790749 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_32_longestValidParentheses.java @@ -0,0 +1,119 @@ +package pp.arithmetic.leetcode; + +import java.util.Stack; + +/** + * Created by wangpeng on 2019-04-12. + * 32. 最长有效括号 + *

+ * 给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。 + *

+ * 示例 1: + *

+ * 输入: "(()" + * 输出: 2 + * 解释: 最长有效括号子串为 "()" + * 示例 2: + *

+ * 输入: ")()())" + * 输出: 4 + * 解释: 最长有效括号子串为 "()()" + * + * @see longest-valid-parentheses + */ +public class _32_longestValidParentheses { + + public static void main(String[] args) { + _32_longestValidParentheses parentheses = new _32_longestValidParentheses(); + System.out.println(parentheses.longestValidParentheses("(()")); + System.out.println(parentheses.longestValidParentheses(")()())")); + System.out.println(parentheses.longestValidParentheses("()()")); + System.out.println(parentheses.longestValidParentheses2(")()())()()(")); + } + + /** + * 解题思路: + * 参考 {@link _20_isValid#isValid(String)},但和其不同的是,求有效长度 + * 难度在于,你不知道什么时候才是有效长度结束,每个括号都有可能是后续某个括号的匹配 + * 1、使用Stack存储,(则入栈,)则在栈中进行寻找是否有对于的( + * 2、找到对应的(则将(出栈,将数字2入栈 + * 3、如在找(的过程中遇到了数字,就将其累加到最大值中并使其出栈 + *

+ * 执行用时 : 22 ms, 在Longest Valid Parentheses的Java提交中击败了41.51% 的用户 + * 内存消耗 : 36.9 MB, 在Longest Valid Parentheses的Java提交中击败了86.21% 的用户 + *

+ * 提交结果并不是很棒,看话题关联有动态规划,于是再考虑一个动态规划的计算 + * 解法二 {@link _32_longestValidParentheses#longestValidParentheses2(String)} + * + * @param s + * @return + */ + public int longestValidParentheses(String s) { + int retCount = 0; + Stack stack = new Stack(); + int count; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '(') { + stack.push(c); + } else { + count = 0; + boolean isMatch = false; + while (!stack.isEmpty()) { + Object peek = stack.peek(); + if (peek instanceof Integer) { + count += (Integer) peek; + stack.pop(); + } else { + char peekC = (char) peek; + if (peekC == ')' || isMatch) break; + isMatch = true; + count += 2; + stack.pop(); + } + } + retCount = Math.max(retCount, count); + stack.push(count); + if (!isMatch) { + stack.push(c); + } + } + } + return retCount; + } + + /** + * 解法二: + * 动态规划四步走 + * - 确认原问题与子问题: 原问题为求s中最长有效括号,子问题可拆解为前i个中最长有效括号。 + * - 确认状态: 本题的动态规划状态单一,第i个状态即为前i个字符串中最长括号数。 + * - 确认边界状态的值: dp[1]=0,从1开始 + * - 确定状态转移方程: 对于(())适用dp[i] = dp[i - 1] + 2;对于()()适用 dp[i] += dp[i - dp[i]]; + * 两者结合一起判断,防止()()(())这种情况 + *

+ * 执行用时 : 4 ms, 在Longest Valid Parentheses的Java提交中击败了98.68% 的用户 + * 内存消耗 : 37.6 MB, 在Longest Valid Parentheses的Java提交中击败了82.01% 的用户 + * + * @param s + * @return + */ + public int longestValidParentheses2(String s) { + if (s == null || s.equals("")) + return 0; + int maxlen = 0; + //当前对于的最大的连续括号数 + int[] dp = new int[s.length()]; + for (int i = 1; i < s.length(); i++) { + if (s.charAt(i) == ')') { + if (i - dp[i - 1] - 1 >= 0 && s.charAt(i - dp[i - 1] - 1) == '(') { + dp[i] = dp[i - 1] + 2; + } + if (i - dp[i] >= 0 && dp[i - dp[i]] > 0) { + dp[i] += dp[i - dp[i]]; + } + maxlen = dp[i] > maxlen ? dp[i] : maxlen; + } + } + return maxlen; + } +} From c0cb35a9a77efebef49d96aa569502fd80386002 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Fri, 19 Apr 2019 14:48:05 +0800 Subject: [PATCH 021/308] docs: add _32_longestValidParentheses --- README.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4aa4f7a..89cff12 100644 --- a/README.md +++ b/README.md @@ -23,10 +23,17 @@ - [x] [31. 下一个排列-Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_31_nextPermutation.java) -- [ ] [32. 最长有效括号-Hard](https://leetcode-cn.com/problems/longest-valid-parentheses/) +- [x] [32. 最长有效括号-Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_32_longestValidParentheses.java) - [ ] [301. 删除无效的括号-Hard](https://leetcode-cn.com/problems/remove-invalid-parentheses/) +> 预告:下周的题目会是和动态规划相关的,动态规划解题四部曲,可供参考 +> +> - 确认**原问题与子问题**: +> - 确认**状态**: +> - 确认**边界状态的值**: +> - 确定**状态转移方程**: + ## 已解题目 > 20190404# leetcode目前已有题目1020道,免费852道 @@ -60,7 +67,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中) +### 题目列表(更新中--已完成143) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -95,6 +102,7 @@ | #29 | [两数相除](https://leetcode-cn.com/problems/divide-two-integers/) | [Divide](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_29_divide.java) | [数学]()、[二分查找]() | Medium | | | #30 | [串联所有单词的子串](https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words/) | [FindSubstring](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_30_findSubstring.java) | [哈希表]()、[双指针]()、[字符串]() | Hard | | | #31 | [下一个排列](https://leetcode-cn.com/problems/next-permutation/) | [NextPermutation](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_31_nextPermutation.java) | [数组]() | Medium | | +| #32 | [最长有效括号](https://leetcode-cn.com/problems/longest-valid-parentheses/) | [LongestValidParentheses](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_32_longestValidParentheses.java) | [字符串]()、[动态规划]() | Hard | | | #33 | [搜索旋转排序数组](https://leetcode-cn.com/problems/search-in-rotated-sorted-array/) | [Search](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_33_search.java) | [数组]()、[二分查找]() | Medium | | | #34 | [在排序数组中查找元素的第一个和最后一个位置](https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/) | [SearchRange](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_34_searchRange.java) | [数组]()、[二分查找]() | Medium | | | #35 | [搜索插入位置](https://leetcode-cn.com/problems/search-insert-position/) | [SearchInsert](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_35_searchInsert.java) | [数组]()、[二分查找]() | Easy | | From 7995808a5f888484a2e12bfb03b53175fa8647ff Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 22 Apr 2019 09:56:20 +0800 Subject: [PATCH 022/308] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B020190422?= =?UTF-8?q?=E5=91=A8=E9=A2=98=E7=9B=AE=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 89cff12..aa31817 100644 --- a/README.md +++ b/README.md @@ -11,29 +11,23 @@ - 欢迎star、fork、交流,一起互勉 - 微信号:pp_hdsny(备注leetcode) - 网址:https://leetcode-cn.com/ -## 20190415-20190422待解题目列表 +## 20190422-20190428待解题目列表(动态规划) -- [x] [27. 移除元素-Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_27_removeElement.java) - -- [x] [28. 实现strStr()-Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_28_strStr.java) - -- [x] [29. 两数相除-Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_29_divide.java) - -- [x] [30. 串联所有单词的子串-Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_30_findSubstring.java) - -- [x] [31. 下一个排列-Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_31_nextPermutation.java) - -- [x] [32. 最长有效括号-Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_32_longestValidParentheses.java) - -- [ ] [301. 删除无效的括号-Hard](https://leetcode-cn.com/problems/remove-invalid-parentheses/) - -> 预告:下周的题目会是和动态规划相关的,动态规划解题四部曲,可供参考 +> 动态规划解题四部曲,可供参考 > > - 确认**原问题与子问题**: > - 确认**状态**: > - 确认**边界状态的值**: > - 确定**状态转移方程**: +- [ ] [746. 使用最小花费爬楼梯 -EASY](https://leetcode-cn.com/problems/min-cost-climbing-stairs) +- [ ] [1025. 除数博弈 -EASY](https://leetcode-cn.com/problems/divisor-game) +- [ ] [91. 解码方法 -MEDIUM](https://leetcode-cn.com/problems/decode-ways) +- [ ] [95. 不同的二叉搜索树 II -MEDIUM](https://leetcode-cn.com/problems/unique-binary-search-trees-ii) +- [ ] [139. 单词拆分 -MEDIUM](https://leetcode-cn.com/problems/word-break) +- [ ] [44. 通配符匹配 -HARD](https://leetcode-cn.com/problems/wildcard-matching) +- [ ] [72. 编辑距离 -HARD](https://leetcode-cn.com/problems/edit-distance) + ## 已解题目 > 20190404# leetcode目前已有题目1020道,免费852道 From 68e6a0b0797306c8a1d9cacca54db01dbbfdfa36 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 22 Apr 2019 11:16:26 +0800 Subject: [PATCH 023/308] feat(EASY): add _746_minCostClimbingStairs --- .../leetcode/_746_minCostClimbingStairs.java | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_746_minCostClimbingStairs.java diff --git a/src/pp/arithmetic/leetcode/_746_minCostClimbingStairs.java b/src/pp/arithmetic/leetcode/_746_minCostClimbingStairs.java new file mode 100644 index 0000000..44b6d18 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_746_minCostClimbingStairs.java @@ -0,0 +1,61 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-04-22. + * 746. 使用最小花费爬楼梯 + *

+ * 数组的每个索引做为一个阶梯,第 i个阶梯对应着一个非负数的体力花费值 cost[i](索引从0开始)。 + *

+ * 每当你爬上一个阶梯你都要花费对应的体力花费值,然后你可以选择继续爬一个阶梯或者爬两个阶梯。 + *

+ * 您需要找到达到楼层顶部的最低花费。在开始时,你可以选择从索引为 0 或 1 的元素作为初始阶梯。 + *

+ * 示例 1: + *

+ * 输入: cost = [10, 15, 20] + * 输出: 15 + * 解释: 最低花费是从cost[1]开始,然后走两步即可到阶梯顶,一共花费15。 + * 示例 2: + *

+ * 输入: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] + * 输出: 6 + * 解释: 最低花费方式是从cost[0]开始,逐个经过那些1,跳过cost[3],一共花费6。 + * 注意: + *

+ * cost 的长度将会在 [2, 1000]。 + * 每一个 cost[i] 将会是一个Integer类型,范围为 [0, 999]。 + * + * @see min-cost-climbing-stairs + */ +public class _746_minCostClimbingStairs { + + public static void main(String[] args) { + _746_minCostClimbingStairs stairs = new _746_minCostClimbingStairs(); + System.out.println(stairs.minCostClimbingStairs(new int[]{10, 15, 20})); + System.out.println(stairs.minCostClimbingStairs(new int[]{1, 100, 1, 1, 1, 100, 1, 1, 100, 1})); + System.out.println(stairs.minCostClimbingStairs(new int[]{2, 1000})); + } + + /** + * 解题思路: + * 动态规划解题四部曲,可供参考 + *

+ * - 确认原问题与子问题=>原问题:走完楼梯花费的最小体力,子问题:第i步花的最小体力 + * - 确认状态=>本题的动态规划状态单一,第i个状态即为i阶台阶的所花费的最小体力 + * - 确认边界状态的值=>第1步=cost[0],第2步=min(cost[0],cost[1]) + * - 确定状态转移方程=>dp[i] = Math.min(dp[i - 2] + cost[i - 2], dp[i - 1] + cost[i - 1]); + * + * @param cost + * @return + */ + public int minCostClimbingStairs(int[] cost) { + int length = cost.length + 1; + int[] dp = new int[length]; + dp[0] = 0; + dp[1] = 0; + for (int i = 2; i < length; i++) { + dp[i] = Math.min(dp[i - 2] + cost[i - 2], dp[i - 1] + cost[i - 1]); + } + return dp[length - 1]; + } +} From a2c619221f09a0962c7155c7d72e4b2112135748 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 22 Apr 2019 11:20:10 +0800 Subject: [PATCH 024/308] docs: add _746_minCostClimbingStairs --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index aa31817..dc90b7b 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ > - 确认**边界状态的值**: > - 确定**状态转移方程**: -- [ ] [746. 使用最小花费爬楼梯 -EASY](https://leetcode-cn.com/problems/min-cost-climbing-stairs) +- [x] [746. 使用最小花费爬楼梯 -EASY](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_746_minCostClimbingStairs.java) - [ ] [1025. 除数博弈 -EASY](https://leetcode-cn.com/problems/divisor-game) - [ ] [91. 解码方法 -MEDIUM](https://leetcode-cn.com/problems/decode-ways) - [ ] [95. 不同的二叉搜索树 II -MEDIUM](https://leetcode-cn.com/problems/unique-binary-search-trees-ii) @@ -201,6 +201,7 @@ | #653 | [两数之和 IV - 输入 BST](https://leetcode-cn.com/problems/two-sum-iv-input-is-a-bst/) | [FindTarget](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_653_findTarget.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | | #674 | [最长连续递增序列](https://leetcode-cn.com/problems/longest-continuous-increasing-subsequence/) | [FindLengthOfLCIS](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_674_findLengthOfLCIS_e.java) | [数组]() | Easy | | | #695 | [岛屿的最大面积](https://leetcode-cn.com/problems/max-area-of-island/) | [MaxAreaOfIsland](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_695_maxAreaOfIsland.java) | [DFS](https://leetcode-cn.com/tag/depth-first-search/)、[数组]() | Medium | | +| #746 | [使用最小花费爬楼梯](https://leetcode-cn.com/problems/min-cost-climbing-stairs/) | [MinCostClimbingStairs](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_746_minCostClimbingStairs.java) | [数组]()、[动态规划]() | Easy | | | #978 | [最长湍流子数组](https://leetcode-cn.com/problems/longest-turbulent-subarray/) | [MaxTurbulenceSize](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_978_maxTurbulenceSize.java) | [数组]()、[动态规划]()、[sliding window]() | Medium | | | #1004 | [最大连续1的个数 III](https://leetcode-cn.com/problems/max-consecutive-ones-iii/) | [LongestOnes](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1004_longestOnes.java) | [双指针]()、[sliding window]() | Medium | | From f625906e6a5bdc618d9283b346eb04406224713e Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 22 Apr 2019 19:17:46 +0800 Subject: [PATCH 025/308] feat(EASY): add _1025_divisorGame --- .../leetcode/_1025_divisorGame.java | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_1025_divisorGame.java diff --git a/src/pp/arithmetic/leetcode/_1025_divisorGame.java b/src/pp/arithmetic/leetcode/_1025_divisorGame.java new file mode 100644 index 0000000..b37d388 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_1025_divisorGame.java @@ -0,0 +1,78 @@ +package pp.arithmetic.leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wangpeng on 2019-04-22. + * 1025. 除数博弈 + *

+ * 爱丽丝和鲍勃一起玩游戏,他们轮流行动。爱丽丝先手开局。 + *

+ * 最初,黑板上有一个数字 N 。在每个玩家的回合,玩家需要执行以下操作: + *

+ * 选出任一 x,满足 0 < x < N 且 N % x == 0 。 + * 用 N - x 替换黑板上的数字 N 。 + * 如果玩家无法执行这些操作,就会输掉游戏。 + *

+ * 只有在爱丽丝在游戏中取得胜利时才返回 True,否则返回 false。假设两个玩家都以最佳状态参与游戏。 + *

+ *

+ *

+ * 示例 1: + *

+ * 输入:2 + * 输出:true + * 解释:爱丽丝选择 1,鲍勃无法进行操作。 + * 示例 2: + *

+ * 输入:3 + * 输出:false + * 解释:爱丽丝选择 1,鲍勃也选择 1,然后爱丽丝无法进行操作。 + *

+ *

+ * 提示: + *

+ * 1 <= N <= 1000 + * + * @see divisor-game + */ +public class _1025_divisorGame { + public static void main(String[] args) { + _1025_divisorGame divisorGame = new _1025_divisorGame(); + System.out.println(divisorGame.divisorGame(3)); + System.out.println(divisorGame.divisorGame(4)); + } + + /** + * 解题思路: + * 爱丽丝可能有多种结局么?论证发现只要N给定了,结局也就定了,偶数爱丽丝必胜 + * 但是我们为了练习动态规划(DP),还是从动态规划的角度来思考下 + * 动态规划解题四部曲,可供参考 + *

+ * - 确认原问题与子问题=>原问题:对于N来说爱丽丝是否能赢,子问题:对于i来说爱丽丝是否会赢 + * - 确认状态=> + * - 确认边界状态的值=>dp[1]=false;dp[2]=true + * - 确定状态转移方程=>dp[i]=!dp[i-1] + * + * 没看明白题目,没意思 + * + * @param N + * @return + */ + public boolean divisorGame(int N) { + //把偶数留给自己, 把奇数留给对手, 最后剩2的时候选择1即可赢得比赛. + //若己方拿到的是偶数, 每次选择 1, 就可以把奇数留给对手, 己方赢. + //若己方拿到的是奇数, 一定不能选择偶数, 留给对手的一定是偶数, 对手可以留给你奇数, 对手赢. + //动态规划,初始值。 + if (N == 1) return false; + + boolean[] dp = new boolean[N + 1]; + dp[1] = false; + + for (int i = 2; i <= N; i++) { + dp[i] = !dp[i - 1]; + } + return dp[N]; + } +} From 5bb3e153992d8e31ba6932a8e0e299bcc33602a0 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 22 Apr 2019 19:20:59 +0800 Subject: [PATCH 026/308] docs: add _1025_divisorGame --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dc90b7b..0bb5210 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ > - 确定**状态转移方程**: - [x] [746. 使用最小花费爬楼梯 -EASY](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_746_minCostClimbingStairs.java) -- [ ] [1025. 除数博弈 -EASY](https://leetcode-cn.com/problems/divisor-game) +- [x] [1025. 除数博弈 -EASY](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1025_divisorGame.java) - [ ] [91. 解码方法 -MEDIUM](https://leetcode-cn.com/problems/decode-ways) - [ ] [95. 不同的二叉搜索树 II -MEDIUM](https://leetcode-cn.com/problems/unique-binary-search-trees-ii) - [ ] [139. 单词拆分 -MEDIUM](https://leetcode-cn.com/problems/word-break) @@ -61,7 +61,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成143) +### 题目列表(更新中--已完成145) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -204,6 +204,7 @@ | #746 | [使用最小花费爬楼梯](https://leetcode-cn.com/problems/min-cost-climbing-stairs/) | [MinCostClimbingStairs](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_746_minCostClimbingStairs.java) | [数组]()、[动态规划]() | Easy | | | #978 | [最长湍流子数组](https://leetcode-cn.com/problems/longest-turbulent-subarray/) | [MaxTurbulenceSize](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_978_maxTurbulenceSize.java) | [数组]()、[动态规划]()、[sliding window]() | Medium | | | #1004 | [最大连续1的个数 III](https://leetcode-cn.com/problems/max-consecutive-ones-iii/) | [LongestOnes](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1004_longestOnes.java) | [双指针]()、[sliding window]() | Medium | | +| #1025 | [除数博弈](https://leetcode-cn.com/problems/divisor-game/) | [DivisorGame](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1025_divisorGame.java) | [数学]()、[动态规划]() | Easy | | From b5aac4bfe7bc082355673704b400d5e15b81121e Mon Sep 17 00:00:00 2001 From: wangpeng Date: Tue, 23 Apr 2019 15:08:20 +0800 Subject: [PATCH 027/308] feat(MEDIUM): add _91_numDecodings --- .../arithmetic/leetcode/_91_numDecodings.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_91_numDecodings.java diff --git a/src/pp/arithmetic/leetcode/_91_numDecodings.java b/src/pp/arithmetic/leetcode/_91_numDecodings.java new file mode 100644 index 0000000..11918f5 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_91_numDecodings.java @@ -0,0 +1,63 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-04-23. + * 91. 解码方法 + *

+ * 一条包含字母 A-Z 的消息通过以下方式进行了编码: + *

+ * 'A' -> 1 + * 'B' -> 2 + * ... + * 'Z' -> 26 + * 给定一个只包含数字的非空字符串,请计算解码方法的总数。 + *

+ * 示例 1: + *

+ * 输入: "12" + * 输出: 2 + * 解释: 它可以解码为 "AB"(1 2)或者 "L"(12)。 + * 示例 2: + *

+ * 输入: "226" + * 输出: 3 + * 解释: 它可以解码为 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 。 + * + * @see decode-ways + */ +public class _91_numDecodings { + public static void main(String[] args) { + _91_numDecodings numDecodings = new _91_numDecodings(); + System.out.println(numDecodings.numDecodings("100")); + System.out.println(numDecodings.numDecodings("101")); + System.out.println(numDecodings.numDecodings("110")); + System.out.println(numDecodings.numDecodings("230")); + System.out.println(numDecodings.numDecodings("226")); + System.out.println(numDecodings.numDecodings("2261")); + } + + /** + * 解题思路: + * 字符可以1个或者2个对应字母,2个最大是26,一个最小是1 + * dp代表当前i可以解码的个数 + *

+ * 题目很坑,注意异常数字(0)非常多 + * 理清楚递推逻辑还是很难的。 + * + * @param s + * @return + */ + public int numDecodings(String s) { + if (s.length() == 0 || (s.charAt(0) == '0')) return 0; + if (s.length() == 1) return 1; + int[] dp = new int[s.length() + 1]; + dp[0] = 1; + for (int i = 0; i < s.length(); ++i) { + dp[i + 1] = s.charAt(i) == '0' ? 0 : dp[i]; + if (i > 0 && (s.charAt(i - 1) == '1' || (s.charAt(i - 1) == '2' && s.charAt(i) <= '6'))) { + dp[i + 1] += dp[i - 1]; + } + } + return dp[s.length()]; + } +} From f7f88d879b2fe84ea7619f47e31556d28899861d Mon Sep 17 00:00:00 2001 From: wangpeng Date: Tue, 23 Apr 2019 15:10:29 +0800 Subject: [PATCH 028/308] docs: add _91_numDecodings --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0bb5210..e8a85c4 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ - [x] [746. 使用最小花费爬楼梯 -EASY](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_746_minCostClimbingStairs.java) - [x] [1025. 除数博弈 -EASY](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1025_divisorGame.java) -- [ ] [91. 解码方法 -MEDIUM](https://leetcode-cn.com/problems/decode-ways) +- [x] [91. 解码方法 -MEDIUM](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_91_numDecodings.java) - [ ] [95. 不同的二叉搜索树 II -MEDIUM](https://leetcode-cn.com/problems/unique-binary-search-trees-ii) - [ ] [139. 单词拆分 -MEDIUM](https://leetcode-cn.com/problems/word-break) - [ ] [44. 通配符匹配 -HARD](https://leetcode-cn.com/problems/wildcard-matching) @@ -61,7 +61,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成145) +### 题目列表(更新中--已完成146) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -122,6 +122,7 @@ | #80 | [删除排序数组中的重复项 II](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array-ii/) | [RemoveDuplicates](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_80_removeDuplicates.java) | [数组]()、[双指针]() | Medium | | | #86 | [分隔链表](https://leetcode-cn.com/problems/partition-list/) | [Partition](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_86_Partition.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Medium | | | #90 | [子集 II](https://leetcode-cn.com/problems/subsets-ii/) | [SubsetsWithDup](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_90_subsetsWithDup.java) | [数组]()、[回溯算法]() | Medium | | +| #91 | [解码方法](https://leetcode-cn.com/problems/decode-ways/) | [NumDecodings](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_91_numDecodings.java) | [字符串]()、[动态规划]() | Medium | | | #92 | [反转链表 II](https://leetcode-cn.com/problems/reverse-linked-list-ii/) | [ReverseBetween](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_92_ReverseBetween.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | | #93 | [复原IP地址](https://leetcode-cn.com/problems/restore-ip-addresses/) | [RestoreIpAddresses](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_93_restoreIpAddresses.java) | [字符串]()、[回溯算法]() | Medium | | | #103 | [二叉树的锯齿形层次遍历](https://leetcode-cn.com/problems/binary-tree-zigzag-level-order-traversal/) | [ZigzagLevelOrder](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_103_zigzagLevelOrder.java) | [栈](https://leetcode-cn.com/tag/stack/)、[树](https://leetcode-cn.com/tag/tree/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Medium | | From a34a91b635bc5312fc923c958efa4cd525375e63 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Wed, 24 Apr 2019 16:51:09 +0800 Subject: [PATCH 029/308] feat(MEDIUM): add _95_generateTrees --- .../leetcode/_95_generateTrees.java | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_95_generateTrees.java diff --git a/src/pp/arithmetic/leetcode/_95_generateTrees.java b/src/pp/arithmetic/leetcode/_95_generateTrees.java new file mode 100644 index 0000000..23958d2 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_95_generateTrees.java @@ -0,0 +1,88 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; +import pp.arithmetic.model.TreeNode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wangpeng on 2019-04-24. + * 95. 不同的二叉搜索树 II + *

+ * 给定一个整数 n,生成所有由 1 ... n 为节点所组成的二叉搜索树。 + *

+ * 示例: + *

+ * 输入: 3 + * 输出: + * [ + * [1,null,3,2], + * [3,2,null,1], + * [3,1,null,null,2], + * [2,1,3], + * [1,null,2,null,3] + * ] + * 解释: + * 以上的输出对应以下 5 种不同结构的二叉搜索树: + *

+ * 1 3 3 2 1 + * \ / / / \ \ + * 3 2 1 1 3 2 + * / / \ \ + * 2 1 2 3 + * + * @see unique-binary-search-trees-ii + */ +public class _95_generateTrees { + public static void main(String[] args) { + _95_generateTrees trees = new _95_generateTrees(); + List treeNodes = trees.generateTrees(3); + for (int i = 0; i < treeNodes.size(); i++) { + Util.printTree(treeNodes.get(i)); + } + } + + /** + * 二叉搜索树(二叉查找树):根节点,比左子树大,比右子树小 + * 解题思路: + * 1、确定根节点 + * 2、确定左子树列表(list) + * 3、确定右子树列表(list) + * 4、循环左右子树,拿到树的list + * + * 对于树的题目,最根本的解题方案就是递归左右子树 + * + * @param n + * @return + */ + public List generateTrees(int n) { + if (n == 0) return new ArrayList<>(); + return generateNodeList(1, n); + } + + private List generateNodeList(int si, int ei) { + List res = new ArrayList<>(); + if (si > ei) { + res.add(null); + return res; + } + if (si == ei) { + res.add(new TreeNode(si)); + return res; + } + for (int i = si; i <= ei; i++) { + List leftSubTrees = generateNodeList(si, i - 1); + List rightSubTrees = generateNodeList(i + 1, ei); + for (TreeNode left : leftSubTrees) { + for (TreeNode right : rightSubTrees) { + TreeNode node = new TreeNode(i); + node.left = left; + node.right = right; + res.add(node); + } + } + } + return res; + } +} From 9d5906da83ffe7fafcc78ce02cccaf97cac75dc0 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Wed, 24 Apr 2019 16:54:32 +0800 Subject: [PATCH 030/308] docs: add _95_generateTrees --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e8a85c4..30a4c73 100644 --- a/README.md +++ b/README.md @@ -21,13 +21,21 @@ > - 确定**状态转移方程**: - [x] [746. 使用最小花费爬楼梯 -EASY](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_746_minCostClimbingStairs.java) + - [x] [1025. 除数博弈 -EASY](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1025_divisorGame.java) + - [x] [91. 解码方法 -MEDIUM](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_91_numDecodings.java) -- [ ] [95. 不同的二叉搜索树 II -MEDIUM](https://leetcode-cn.com/problems/unique-binary-search-trees-ii) + +- [x] [95. 不同的二叉搜索树 II -MEDIUM](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_95_generateTrees.java) + - [ ] [139. 单词拆分 -MEDIUM](https://leetcode-cn.com/problems/word-break) + - [ ] [44. 通配符匹配 -HARD](https://leetcode-cn.com/problems/wildcard-matching) + - [ ] [72. 编辑距离 -HARD](https://leetcode-cn.com/problems/edit-distance) +- [ ] [639. 解码方法 2-HARD](https://leetcode-cn.com/problems/decode-ways-ii/) + ## 已解题目 > 20190404# leetcode目前已有题目1020道,免费852道 @@ -125,6 +133,7 @@ | #91 | [解码方法](https://leetcode-cn.com/problems/decode-ways/) | [NumDecodings](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_91_numDecodings.java) | [字符串]()、[动态规划]() | Medium | | | #92 | [反转链表 II](https://leetcode-cn.com/problems/reverse-linked-list-ii/) | [ReverseBetween](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_92_ReverseBetween.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | | #93 | [复原IP地址](https://leetcode-cn.com/problems/restore-ip-addresses/) | [RestoreIpAddresses](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_93_restoreIpAddresses.java) | [字符串]()、[回溯算法]() | Medium | | +| #95 | [不同的二叉搜索树 II](https://leetcode-cn.com/problems/unique-binary-search-trees-ii/) | [GenerateTrees](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_95_generateTrees.java) | [树](https://leetcode-cn.com/tag/tree/)、[动态规划]() | Medium | DP实现未想到 | | #103 | [二叉树的锯齿形层次遍历](https://leetcode-cn.com/problems/binary-tree-zigzag-level-order-traversal/) | [ZigzagLevelOrder](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_103_zigzagLevelOrder.java) | [栈](https://leetcode-cn.com/tag/stack/)、[树](https://leetcode-cn.com/tag/tree/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Medium | | | #104 | [二叉树的最大深度](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/) | [MaxDepth](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_104_maxDepth.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | | #108 | [将有序数组转换为二叉搜索树](https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/) | [SortedArrayToBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_108_sortedArrayToBST.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | From 50e3566135bc5bf28a764029d3830fc5d1336993 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 25 Apr 2019 14:58:20 +0800 Subject: [PATCH 031/308] feat(MEDIUM): add _139_wordBreak --- .../arithmetic/leetcode/_139_wordBreak.java | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_139_wordBreak.java diff --git a/src/pp/arithmetic/leetcode/_139_wordBreak.java b/src/pp/arithmetic/leetcode/_139_wordBreak.java new file mode 100644 index 0000000..789136c --- /dev/null +++ b/src/pp/arithmetic/leetcode/_139_wordBreak.java @@ -0,0 +1,118 @@ +package pp.arithmetic.leetcode; + +import java.util.*; + +/** + * Created by wangpeng on 2019-04-25. + * 139. 单词拆分 + *

+ * 给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。 + *

+ * 说明: + *

+ * 拆分时可以重复使用字典中的单词。 + * 你可以假设字典中没有重复的单词。 + * 示例 1: + *

+ * 输入: s = "leetcode", wordDict = ["leet", "code"] + * 输出: true + * 解释: 返回 true 因为 "leetcode" 可以被拆分成 "leet code"。 + * 示例 2: + *

+ * 输入: s = "applepenapple", wordDict = ["apple", "pen"] + * 输出: true + * 解释: 返回 true 因为 "applepenapple" 可以被拆分成 "apple pen apple"。 + * 注意你可以重复使用字典中的单词。 + * 示例 3: + *

+ * 输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"] + * 输出: false + * + * @see word-break + */ +public class _139_wordBreak { + public static void main(String[] args) { + _139_wordBreak wordBreak = new _139_wordBreak(); + System.out.println(wordBreak.wordBreak("leetcode", Arrays.asList("leet", "code"))); + System.out.println(wordBreak.wordBreak("applepenapple", Arrays.asList("apple", "pen"))); + System.out.println(wordBreak.wordBreak("catsandog", Arrays.asList("cats", "dog", "sand", "and", "cat"))); + System.out.println(wordBreak.wordBreak2("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab", Arrays.asList("a","aa","aaa","aaaa","aaaaa","aaaaaa","aaaaaaa","aaaaaaaa","aaaaaaaaa","aaaaaaaaaa"))); + } + + /** + * 解题思路:回溯实现 + * 0、用hashmap保存字典,减少匹配的耗时 + * 1、按位逐个遍历字符串,看是否和字典中匹配,匹配上再后移截取 + * 2、如果后续没有匹配上,直到字符串结束,那么上个字符串截取位置再向后寻找 + *

+ * 可解题,但是提交超时,超时用例如下 + * "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab" + * ["a","aa","aaa","aaaa","aaaaa","aaaaaa","aaaaaaa","aaaaaaaa","aaaaaaaaa","aaaaaaaaaa"] + * 超时分析:对于上述测试用例,有大量重复的反复比较 + *

+ * 解法二:{@link _139_wordBreak#wordBreak2(String, List)} + * + * @param s + * @param wordDict + * @return + */ + public boolean wordBreak(String s, List wordDict) { + HashMap map = new HashMap<>(); + for (int i = 0; i < wordDict.size(); i++) { + map.put(wordDict.get(i), true); + } + LinkedList findList = new LinkedList<>(); + boolean lastMatch = false; + int si = 0, ei = 1; + while (si < s.length()) { + if (ei > s.length()) { + if (lastMatch) break; //完全匹配成功 + if (findList.size() == 0) break; //完全未找到 + //si回到上个位置 + ei = si + 1; + String lastStr = findList.removeLast(); + si = si - lastStr.length(); + continue; + } + String substring = s.substring(si, ei); + if (map.getOrDefault(substring, false)) {//匹配上了 + si = ei; + ei++; + lastMatch = true; + findList.add(substring); + } else { + ei++; + lastMatch = false; + } + } + + return lastMatch; + } + + /** + * 解法二: + * 看了下题目关联的话题只有`动态规划`,那朝着动态规划的方向思考下 + * - 确认原问题与子问题=>原问题:字符串s能否拆分成功,子问题:字符串s的前i个字符能否拆分成wordDict + * - 确认状态=>dp[i]表示字符串s的前i个字符能否拆分成wordDict + * - 确认边界状态的值=>dp[0]=true + * - 确定状态转移方程=>dp[i]=dp[j] && wordDict.contains(s.substring(j, i)),(0<=j wordDict) { + int n = s.length(); + boolean[] dp = new boolean[n + 1]; + dp[0] = true; + for (int i = 1; i <= n; i++) { + for (int j = 0; j < i; j++) { + if (dp[j] && wordDict.contains(s.substring(j, i))) { + dp[i] = true; + break; + } + } + } + return dp[n]; + } +} From 18d48fbdc8e414e4f05467952b1ecc98d05405ff Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 25 Apr 2019 15:00:49 +0800 Subject: [PATCH 032/308] docs: add _139_wordBreak --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 30a4c73..8721801 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ - [x] [95. 不同的二叉搜索树 II -MEDIUM](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_95_generateTrees.java) -- [ ] [139. 单词拆分 -MEDIUM](https://leetcode-cn.com/problems/word-break) +- [x] [139. 单词拆分 -MEDIUM](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_139_wordBreak.java) - [ ] [44. 通配符匹配 -HARD](https://leetcode-cn.com/problems/wildcard-matching) @@ -69,7 +69,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成146) +### 题目列表(更新中--已完成147) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -148,6 +148,7 @@ | #127 | [单词接龙](https://leetcode-cn.com/problems/word-ladder/) | [LadderLength](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_127_ladderLength_2.java) | [BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Medium | [自己原始解法](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_127_ladderLength.java) | | #128 | [最长连续序列](https://leetcode-cn.com/problems/longest-consecutive-sequence/) | [LongestConsecutive](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_128_longestConsecutive.java) | [并查集](https://leetcode-cn.com/tag/union-find/)、[数组]() | Hard | | | #138 | [复制带随机指针的链表](https://leetcode-cn.com/problems/copy-list-with-random-pointer/) | [CopyRandomList](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_138_CopyRandomList.java) | [哈希表]()、[链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | +| #139 | [单词拆分](https://leetcode-cn.com/problems/word-break/) | [WordBreak](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_139_wordBreak.java) | [动态规划]() | Medium | 回溯实现耗时 | | #141 | [环形链表](https://leetcode-cn.com/problems/linked-list-cycle/) | [HasCycle](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_141_HasCycle.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Easy | | | #142 | [环形链表 II](https://leetcode-cn.com/problems/linked-list-cycle-ii/) | [DetectCycle](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_142_DetectCycle.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Medium | | | #146 | [LRU缓存机制](https://leetcode-cn.com/problems/lru-cache/) | [LRUCache](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_146_LRUCache.java) | [设计](https://leetcode-cn.com/tag/design/) | Hard | | From 8ff31fafdbe325de352c07d899b741cb9f0b4fd0 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Sun, 28 Apr 2019 17:07:50 +0800 Subject: [PATCH 033/308] feat(HARD): add _639_numDecodings --- README.md | 2 +- .../leetcode/_639_numDecodings.java | 102 ++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 src/pp/arithmetic/leetcode/_639_numDecodings.java diff --git a/README.md b/README.md index 8721801..9191985 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道 +- leetcode练习,坚持每天一道,目前已完成147道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 diff --git a/src/pp/arithmetic/leetcode/_639_numDecodings.java b/src/pp/arithmetic/leetcode/_639_numDecodings.java new file mode 100644 index 0000000..f57ca69 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_639_numDecodings.java @@ -0,0 +1,102 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-04-26. + * 639. 解码方法 2 + *

+ * 一条包含字母 A-Z 的消息通过以下的方式进行了编码: + *

+ * 'A' -> 1 + * 'B' -> 2 + * ... + * 'Z' -> 26 + * 除了上述的条件以外,现在加密字符串可以包含字符 '*'了,字符'*'可以被当做1到9当中的任意一个数字。 + *

+ * 给定一条包含数字和字符'*'的加密信息,请确定解码方法的总数。 + *

+ * 同时,由于结果值可能会相当的大,所以你应当对10^9 + 7取模。(翻译者标注:此处取模主要是为了防止溢出) + *

+ * 示例 1 : + *

+ * 输入: "*" + * 输出: 9 + * 解释: 加密的信息可以被解密为: "A", "B", "C", "D", "E", "F", "G", "H", "I". + * 示例 2 : + *

+ * 输入: "1*" + * 输出: 9 + 9 = 18(翻译者标注:这里1*可以分解为1,* 或者当做1*来处理,所以结果是9+9=18) + * 说明 : + *

+ * 输入的字符串长度范围是 [1, 10^5]。 + * 输入的字符串只会包含字符 '*' 和 数字'0' - '9'。 + * + * @see decode-ways-ii + */ +public class _639_numDecodings { + + public static void main(String[] args) { + _639_numDecodings numDecodings = new _639_numDecodings(); + System.out.println(numDecodings.numDecodings("1*")); + } + + public static final int mod = (int) Math.pow(10, 9) + 7; + + /** + * LO上优秀解法 + * 解题关键点,理清楚各种情况下的个数可能性 + * + * @param s + * @return + */ + public int numDecodings(String s) { + if (s == null || s.length() == 0) { + return 0; + } + char[] str = s.toCharArray(); + + long[] dp = new long[str.length + 1]; + dp[str.length] = 1; + for (int i = str.length - 1; i >= 0; i--) { + if (str[i] == '0') { + dp[i] = 0; + } else { + long res = dp[i + 1]; + if (str[i] == '*') { + res = (9 * res) % mod; + } + if (i + 1 < str.length) { + long tmp = dp[i + 2]; + if (str[i] != '*') { + if (str[i + 1] != '*') { + if ((str[i] - '0') * 10 + str[i + 1] - '0' < 27) { + res = (res + tmp) % mod; + } + } else { + if (str[i] < '3') { + if (str[i] == '1') { + res = (res + 9 * tmp) % mod; + } else if (str[i] == '2') { + res = (res + 6 * (tmp)) % mod; + } + } + } + } else { + if (str[i + 1] != '*') { + if (10 + str[i + 1] - '0' < 27) { + res = (res + tmp) % mod; + } + if (20 + str[i + 1] - '0' < 27) { + res = (res + tmp) % mod; + } + } else { + res = (res + 15 * tmp) % mod; + } + } + } + dp[i] = res; + } + } + + return (int) (dp[0]); + } +} From 415c0990554225fd11ccd3fdfc86620c9d3df24c Mon Sep 17 00:00:00 2001 From: wangpeng Date: Sun, 28 Apr 2019 17:10:08 +0800 Subject: [PATCH 034/308] docs: add _639_numDecodings --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9191985..1239343 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成147道 +- leetcode练习,坚持每天一道,目前已完成148道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -34,7 +34,7 @@ - [ ] [72. 编辑距离 -HARD](https://leetcode-cn.com/problems/edit-distance) -- [ ] [639. 解码方法 2-HARD](https://leetcode-cn.com/problems/decode-ways-ii/) +- [x] [639. 解码方法 2-HARD](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_639_numDecodings.java) ## 已解题目 @@ -69,7 +69,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成147) +### 题目列表(更新中--已完成148) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -209,6 +209,7 @@ | #547 | [朋友圈](https://leetcode-cn.com/problems/friend-circles/) | [FindCircleNum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_547_findCircleNum_2.java) | [DFS](https://leetcode-cn.com/tag/depth-first-search/)、[并查集](https://leetcode-cn.com/tag/union-find/) | Medium | | | #563 | [二叉树的坡度](https://leetcode-cn.com/problems/binary-tree-tilt/) | [FindTilt](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_563_findTilt.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | | #567 | [字符串的排列](https://leetcode-cn.com/problems/permutation-in-string/) | [CheckInclusion](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_567_checkInclusion.java) | [双指针]() | Medium | | +| #639 | [解码方法 2](https://leetcode-cn.com/problems/decode-ways-ii/) | [NumDecodings](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_639_numDecodings.java) | [动态规划]() | Hard | | | #653 | [两数之和 IV - 输入 BST](https://leetcode-cn.com/problems/two-sum-iv-input-is-a-bst/) | [FindTarget](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_653_findTarget.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | | #674 | [最长连续递增序列](https://leetcode-cn.com/problems/longest-continuous-increasing-subsequence/) | [FindLengthOfLCIS](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_674_findLengthOfLCIS_e.java) | [数组]() | Easy | | | #695 | [岛屿的最大面积](https://leetcode-cn.com/problems/max-area-of-island/) | [MaxAreaOfIsland](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_695_maxAreaOfIsland.java) | [DFS](https://leetcode-cn.com/tag/depth-first-search/)、[数组]() | Medium | | From 8e832436cbb53fd70758ec63acd2c1d200709495 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Tue, 30 Apr 2019 13:16:18 +0800 Subject: [PATCH 035/308] feat(HARD): add _44_isMatch --- src/pp/arithmetic/leetcode/_44_isMatch.java | 119 ++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_44_isMatch.java diff --git a/src/pp/arithmetic/leetcode/_44_isMatch.java b/src/pp/arithmetic/leetcode/_44_isMatch.java new file mode 100644 index 0000000..1144510 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_44_isMatch.java @@ -0,0 +1,119 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-04-28. + * 44. 通配符匹配 + *

+ * 给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配。 + *

+ * '?' 可以匹配任何单个字符。 + * '*' 可以匹配任意字符串(包括空字符串)。 + * 两个字符串完全匹配才算匹配成功。 + *

+ * 说明: + *

+ * s 可能为空,且只包含从 a-z 的小写字母。 + * p 可能为空,且只包含从 a-z 的小写字母,以及字符 ? 和 *。 + * 示例 1: + *

+ * 输入: + * s = "aa" + * p = "a" + * 输出: false + * 解释: "a" 无法匹配 "aa" 整个字符串。 + * 示例 2: + *

+ * 输入: + * s = "aa" + * p = "*" + * 输出: true + * 解释: '*' 可以匹配任意字符串。 + * 示例 3: + *

+ * 输入: + * s = "cb" + * p = "?a" + * 输出: false + * 解释: '?' 可以匹配 'c', 但第二个 'a' 无法匹配 'b'。 + * 示例 4: + *

+ * 输入: + * s = "adceb" + * p = "*a*b" + * 输出: true + * 解释: 第一个 '*' 可以匹配空字符串, 第二个 '*' 可以匹配字符串 "dce". + * 示例 5: + *

+ * 输入: + * s = "acdcb" + * p = "a*c?b" + * 输入: false + * + * @see wildcard-matching + */ +public class _44_isMatch { + public static void main(String[] args) { + _44_isMatch isMatch = new _44_isMatch(); + //解法一 + System.out.println(isMatch.isMatch("aa","a")); + System.out.println(isMatch.isMatch("aa","*")); + System.out.println(isMatch.isMatch("cb","?a")); + System.out.println(isMatch.isMatch("adceb","*a*b")); + System.out.println(isMatch.isMatch("acdcb","a*c?b")); + } + + /** + * 这是一道贪心+回溯+动态规划的难题,可以考虑用几种方式实现下 + * 解题1(动态规划): + * 存在一个匹配的问题,用一个二维的数组进行保存匹配结果 + * 1. p.charAt(j) == '?' || s.charAt(i) == p.charAt(j)。 + * 含义是如果p为此处字符为?或者p此处的字符与s此处的字符相同, + * 则显然dp[i+1][j+1] = dp[i][j] + * 2. p.charAt(j) == '*'。这种情况较为复杂。分情况讨论。 + * A. *代表0个字符,则此时dp[i+1][j+1]=dp[i+1][j] + * B. *代表1个字符,则此时dp[i+1][j+1]=dp[i][j] + * C. *代表2个字符,则此时dp[i+1][j+1]=dp[i-1][j] + * D. *代表3个字符,则此时dp[i+1][j+1]=dp[i-2][j] + * ... + * 因此,最后的统一结果为 + * dp[i+1][j+1]=dp[i+1][j] || dp[i][j] || dp[i-1][j] || + * dp[i-2][j] || ... || dp[0][j] + * 需要注意的是按照上述公式,可以得到 + * dp[i][j+1] = dp[i][j] || dp[i-1][j] || dp[i-2][j] || + * dp[i-3][j] || ... || dp[0][j] + * 因此dp[i+1][j+1] = dp[i+1][j] || dp[i][j+1] + * 3. s.charAt(i) != p.charAt(j) 不匹配 + * dp[i+1][j+1] = false; + * + * @param s + * @param p + * @return + */ + public boolean isMatch(String s, String p) { + int sLen = s.length(), pLen = p.length(); + boolean[][] dp = new boolean[sLen + 1][pLen + 1]; + dp[0][0] = true; + for (int j = 0; j < pLen; j++) { + //初始化第一行数据 + dp[0][j + 1] = dp[0][j] && (p.charAt(j) == '*'); + + for (int i = 0; i < sLen; i++) { + //情况1 + if (p.charAt(j) == '?' || p.charAt(j) == s.charAt(i)) { + dp[i + 1][j + 1] = dp[i][j]; + } + //情况2 + else if (p.charAt(j) == '*') { + dp[i + 1][j + 1] = (dp[i][j + 1] || dp[i + 1][j]); + } + //not match + else { + dp[i + 1][j + 1] = false; + } + } + } + + return dp[sLen][pLen]; + } + +} From fbe510b56b41ec92a0865a6b53e519232549f9be Mon Sep 17 00:00:00 2001 From: wangpeng Date: Tue, 30 Apr 2019 13:19:11 +0800 Subject: [PATCH 036/308] docs: add _44_isMatch --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1239343..c769f00 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成148道 +- leetcode练习,坚持每天一道,目前已完成149道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -30,7 +30,7 @@ - [x] [139. 单词拆分 -MEDIUM](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_139_wordBreak.java) -- [ ] [44. 通配符匹配 -HARD](https://leetcode-cn.com/problems/wildcard-matching) +- [x] [44. 通配符匹配 -HARD](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_44_isMatch.java) - [ ] [72. 编辑距离 -HARD](https://leetcode-cn.com/problems/edit-distance) @@ -69,7 +69,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成148) +### 题目列表(更新中--已完成149) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -111,6 +111,7 @@ | #40 | [组合总和 II](https://leetcode-cn.com/problems/combination-sum-ii/) | [CombinationSum2](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_40_combinationSum2.java) | [数组]()、[回溯算法]() | Medium | | | #42 | [接雨水](https://leetcode-cn.com/problems/trapping-rain-water/) | [Trap](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_42_trap.java) | [栈](https://leetcode-cn.com/tag/stack/)、[数组]()、[双指针]() | Hard | | | #43 | [字符串相乘](https://leetcode-cn.com/problems/multiply-strings/) | [Multiply](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_43_multiply.java) | [数学]()、[字符串]() | Medium | | +| #44 | [通配符匹配](https://leetcode-cn.com/problems/wildcard-matching/) | [IsMatch](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_44_isMatch.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[字符串]()、[动态规划]()、[回溯算法]() | Hard | | | #45 | [跳跃游戏 II](https://leetcode-cn.com/problems/jump-game-ii/) | [Jump](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_45_jump.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Hard | | | #49 | [字母异位词分组](https://leetcode-cn.com/problems/group-anagrams/) | [GroupAnagrams](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_49_groupAnagrams.java) | [哈希表]()、[字符串]() | Medium | | | #51 | [N皇后](https://leetcode-cn.com/problems/n-queens/) | [SolveNQueens](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_51_solveNQueens_2.java) | [回溯算法]() | Hard | [自己原始解法](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_51_solveNQueens.java) | From 1aa8233a4f6f01bbee98077811073446706d66ce Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 6 May 2019 12:16:54 +0800 Subject: [PATCH 037/308] feat(HARD): add _72_minDistance --- .../arithmetic/leetcode/_72_minDistance.java | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_72_minDistance.java diff --git a/src/pp/arithmetic/leetcode/_72_minDistance.java b/src/pp/arithmetic/leetcode/_72_minDistance.java new file mode 100644 index 0000000..82e0e57 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_72_minDistance.java @@ -0,0 +1,82 @@ +package pp.arithmetic.leetcode; + +import static java.lang.Math.min; + +/** + * Created by wangpeng on 2019-05-05. + * 72. 编辑距离 + *

+ * 给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 。 + *

+ * 你可以对一个单词进行如下三种操作: + *

+ * 插入一个字符 + * 删除一个字符 + * 替换一个字符 + * 示例 1: + *

+ * 输入: word1 = "horse", word2 = "ros" + * 输出: 3 + * 解释: + * horse -> rorse (将 'h' 替换为 'r') + * rorse -> rose (删除 'r') + * rose -> ros (删除 'e') + * 示例 2: + *

+ * 输入: word1 = "intention", word2 = "execution" + * 输出: 5 + * 解释: + * intention -> inention (删除 't') + * inention -> enention (将 'i' 替换为 'e') + * enention -> exention (将 'n' 替换为 'x') + * exention -> exection (将 'n' 替换为 'c') + * exection -> execution (插入 'u') + * + * @see edit-distance + */ +public class _72_minDistance { + + public static void main(String[] args) { + _72_minDistance distance = new _72_minDistance(); + System.out.println(distance.minDistance("horse", "ros")); + System.out.println(distance.minDistance("intention", "execution")); + } + + /** + * 解题思路: + * 二维数组保存一一配对的所需的步数,int[][] dp + * w1 = "horse", w2 = "ros" + * 如果遍历的两个字符串相等,则步数不改变 + * 如果不相等则步数一定+1 + * 替换 dp[i-1][j-1] + * 插入 dp[i][j-1] + * 删除 dp[i-1][j] + * 取上面三个操作中的最小的一个 + * + * @param word1 + * @param word2 + * @return + */ + public int minDistance(String word1, String word2) { + int l1 = word1.length(); + int l2 = word2.length(); + int[][] dp = new int[l1 + 1][l2 + 1]; + //初始化 + for (int i = 0; i <= l1; i++) { + dp[i][0] = i; + } + for (int i = 0; i <= l2; i++) { + dp[0][i] = i; + } + for (int i = 1; i <= l1; i++) { + for (int j = 1; j <= l2; j++) { + if (word1.charAt(i - 1) == word2.charAt(j - 1)) + dp[i][j] = dp[i - 1][j - 1]; + else { + dp[i][j] = min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i][j - 1])) + 1; + } + } + } + return dp[l1][l2]; + } +} From ba93f9fa62a1d1309bf66687725bef4b71ef3c11 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 6 May 2019 12:19:48 +0800 Subject: [PATCH 038/308] docs: add _72_minDistance --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c769f00..eca9785 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成149道 +- leetcode练习,坚持每天一道,目前已完成150道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -32,7 +32,7 @@ - [x] [44. 通配符匹配 -HARD](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_44_isMatch.java) -- [ ] [72. 编辑距离 -HARD](https://leetcode-cn.com/problems/edit-distance) +- [x] [72. 编辑距离 -HARD](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_72_minDistance.java) - [x] [639. 解码方法 2-HARD](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_639_numDecodings.java) @@ -69,7 +69,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成149) +### 题目列表(更新中--已完成150) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -126,6 +126,7 @@ | #69 | [x 的平方根](https://leetcode-cn.com/problems/sqrtx/) | [MySqrt](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_69_mySqrt.java) | [数学]()、[二分查找]() | Easy | | | #70 | [爬楼梯](https://leetcode-cn.com/problems/climbing-stairs/) | [ClimbStairs](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_70_climbStairs.java) | [动态规划]() | Easy | 经典题 | | #71 | [简化路径](https://leetcode-cn.com/problems/simplify-path/) | [SimplifyPath](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_71_simplifyPath.java) | [栈](https://leetcode-cn.com/tag/stack/)、[字符串]() | Medium | | +| #72 | [编辑距离](https://leetcode-cn.com/problems/edit-distance/) | [MinDistance](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_72_minDistance.java) | [字符串]()、[动态规划]() | Hard | | | #76 | [最小覆盖子串](https://leetcode-cn.com/problems/minimum-window-substring/) | [MinWindow](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_76_minWindow.java) | [哈希表]()、[双指针]()、[字符串]()、[sliding window]() | Hard | | | #78 | [子集](https://leetcode-cn.com/problems/subsets/) | [Subsets](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_78_subsets.java) | [位运算](https://leetcode-cn.com/tag/bit-manipulation/)、[数组]()、[回溯算法]() | Medium | | | #80 | [删除排序数组中的重复项 II](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array-ii/) | [RemoveDuplicates](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_80_removeDuplicates.java) | [数组]()、[双指针]() | Medium | | From e51c28f6ff3add18dafdc57b7c8186c393ff8999 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Wed, 8 May 2019 09:48:04 +0800 Subject: [PATCH 039/308] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0201905056?= =?UTF-8?q?=E5=91=A8=E9=A2=98=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index eca9785..afd3c11 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ - 欢迎star、fork、交流,一起互勉 - 微信号:pp_hdsny(备注leetcode) - 网址:https://leetcode-cn.com/ -## 20190422-20190428待解题目列表(动态规划) +## 20190506-20190512待解题目列表(动态规划) > 动态规划解题四部曲,可供参考 > @@ -20,21 +20,21 @@ > - 确认**边界状态的值**: > - 确定**状态转移方程**: -- [x] [746. 使用最小花费爬楼梯 -EASY](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_746_minCostClimbingStairs.java) +鉴于上周做的动态规划Hard的太难了,这周全是Medium的练练手,习惯动态规划的解题思路 -- [x] [1025. 除数博弈 -EASY](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1025_divisorGame.java) +- [ ] [152. 乘积最大子序列](https://leetcode-cn.com/problems/maximum-product-subarray/) -- [x] [91. 解码方法 -MEDIUM](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_91_numDecodings.java) +- [ ] [213. 打家劫舍 II](https://leetcode-cn.com/problems/house-robber-ii/) -- [x] [95. 不同的二叉搜索树 II -MEDIUM](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_95_generateTrees.java) +- [ ] [264. 丑数 II](https://leetcode-cn.com/problems/ugly-number-ii/) -- [x] [139. 单词拆分 -MEDIUM](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_139_wordBreak.java) +- [ ] [279. 完全平方数](https://leetcode-cn.com/problems/perfect-squares/) -- [x] [44. 通配符匹配 -HARD](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_44_isMatch.java) +- [ ] [309. 最佳买卖股票时机含冷冻期](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) -- [x] [72. 编辑距离 -HARD](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_72_minDistance.java) +- [ ] [338. 比特位计数](https://leetcode-cn.com/problems/counting-bits/) -- [x] [639. 解码方法 2-HARD](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_639_numDecodings.java) +- [ ] [343. 整数拆分](https://leetcode-cn.com/problems/integer-break/) ## 已解题目 From 1b5532d0376c7b1606a9183fe357313b9669bfb1 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Wed, 8 May 2019 18:32:36 +0800 Subject: [PATCH 040/308] feat(MEDIUM): add _152_maxProduct --- .../arithmetic/leetcode/_152_maxProduct.java | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_152_maxProduct.java diff --git a/src/pp/arithmetic/leetcode/_152_maxProduct.java b/src/pp/arithmetic/leetcode/_152_maxProduct.java new file mode 100644 index 0000000..5c887f7 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_152_maxProduct.java @@ -0,0 +1,82 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-05-08. + * 152. 乘积最大子序列 + *

+ * 给定一个整数数组 nums ,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数)。 + *

+ * 示例 1: + *

+ * 输入: [2,3,-2,4] + * 输出: 6 + * 解释: 子数组 [2,3] 有最大乘积 6。 + * 示例 2: + *

+ * 输入: [-2,0,-1] + * 输出: 0 + * 解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。 + * + * @see maximum-product-subarray + */ +public class _152_maxProduct { + + public static void main(String[] args) { + _152_maxProduct maxProduct = new _152_maxProduct(); + System.out.println(maxProduct.maxProduct(new int[]{2, 3, 2, -1, 0})); + System.out.println(maxProduct.maxProduct(new int[]{-2, 0, -1})); + System.out.println(maxProduct.maxProduct(new int[]{-2, 3, -4})); + System.out.println(maxProduct.maxProduct(new int[]{0, 2})); + } + + /** + * 解题思路: + * 最暴力的方式当然是遍历到i,都和i之前的再循环一遍,找到最大值,双重遍历 + * 上面的解题时间会超,所以得考虑利用之前的遍历结果,==>动态规划 + *

+ * 求积的最大值,最麻烦的就是 + * 当遇到0的时候,整个乘积会变成0;当遇到负数的时候,当前的最大乘积会变成最小乘积,最小乘积会变成最大乘积 + *

+ * 所以用两个数组进行保存最大值和最小值 + *

+ * 当前的最大值等于已知的最大值、最小值和当前值的乘积,当前值,这三个数的最大值。 + * 当前的最小值等于已知的最大值、最小值和当前值的乘积,当前值,这三个数的最小值。 + * 结果是最大值数组中的最大值。 + *

+ * 数组可以进一步优化成int,空间复杂度从O(n)->O(1){@link _152_maxProduct#maxProduct2(int[])} + * + * @param nums + * @return + */ + public int maxProduct(int[] nums) { + if (nums.length == 0) return 0; + if (nums.length == 1) return nums[0]; + int[] max = new int[nums.length]; + int[] min = new int[nums.length]; + int retVal; + retVal = max[0] = min[0] = nums[0]; + for (int i = 1; i < nums.length; i++) { + max[i] = Math.max(nums[i], Math.max(nums[i] * max[i - 1], nums[i] * min[i - 1])); + min[i] = Math.min(nums[i], Math.min(nums[i] * max[i - 1], nums[i] * min[i - 1])); + retVal = Math.max(retVal, max[i]); + } + + return retVal; + } + + public int maxProduct2(int[] nums) { + if (nums.length == 0) return 0; + if (nums.length == 1) return nums[0]; + int max, min, retVal, preMax, preMin; + retVal = max = min = nums[0]; + for (int i = 1; i < nums.length; i++) { + preMax = max; + preMin = min; + max = Math.max(nums[i], Math.max(nums[i] * preMax, nums[i] * preMin)); + min = Math.min(nums[i], Math.min(nums[i] * preMax, nums[i] * preMin)); + retVal = Math.max(retVal, max); + } + + return retVal; + } +} From 1db0cb26784b0a36fb9afac7c5d2449738a00e9c Mon Sep 17 00:00:00 2001 From: wangpeng Date: Wed, 8 May 2019 18:38:27 +0800 Subject: [PATCH 041/308] docs: add _152_maxProduct --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index afd3c11..de2f992 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成150道 +- leetcode练习,坚持每天一道,目前已完成152道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -22,7 +22,7 @@ 鉴于上周做的动态规划Hard的太难了,这周全是Medium的练练手,习惯动态规划的解题思路 -- [ ] [152. 乘积最大子序列](https://leetcode-cn.com/problems/maximum-product-subarray/) +- [x] [152. 乘积最大子序列](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_152_maxProduct.java) - [ ] [213. 打家劫舍 II](https://leetcode-cn.com/problems/house-robber-ii/) @@ -69,7 +69,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成150) +### 题目列表(更新中--已完成152) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -157,6 +157,7 @@ | #147 | [对链表进行插入排序](https://leetcode-cn.com/problems/insertion-sort-list/) | [InsertionSortList](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_147_insertionSortList.java) | [排序](https://leetcode-cn.com/tag/sort/)、[链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | | #148 | [排序链表](https://leetcode-cn.com/problems/sort-list/) | [SortList.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_148_sortList.java) | [排序](https://leetcode-cn.com/tag/sort/)、[链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | | #151 | [翻转字符串里的单词](https://leetcode-cn.com/problems/reverse-words-in-a-string/) | [ReverseWords](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_151_reverseWords_2.java) | [字符串]() | Medium | [自己原始解法](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_151_reverseWords.java) | +| #152 | [乘积最大子序列](https://leetcode-cn.com/problems/maximum-product-subarray/) | [MaxProduct](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_152_maxProduct.java) | [数组]()、[动态规划]() | Medium | | | #155 | [最小栈](https://leetcode-cn.com/problems/min-stack/) | [MinStack](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_155_MinStack.java) | [栈](https://leetcode-cn.com/tag/stack/)、[设计](https://leetcode-cn.com/tag/design/) | Easy | | | #160 | [相交链表](https://leetcode-cn.com/problems/intersection-of-two-linked-lists/) | [GetIntersectionNode](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_160_GetIntersectionNode.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Easy | | | #167 | [两数之和 II - 输入有序数组](https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/) | [TwoSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_167_twoSum.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]()、[二分查找]() | Easy | | From dabb4aabf3a4dc8d4e4f6cb73dd458f140f8cce6 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 9 May 2019 10:40:04 +0800 Subject: [PATCH 042/308] feat(MEDIUM): add _213_rob --- src/pp/arithmetic/leetcode/_213_rob.java | 64 ++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_213_rob.java diff --git a/src/pp/arithmetic/leetcode/_213_rob.java b/src/pp/arithmetic/leetcode/_213_rob.java new file mode 100644 index 0000000..2dd4da6 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_213_rob.java @@ -0,0 +1,64 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-05-09. + * 213. 打家劫舍 II + * + * 你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 + * + * 给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。 + * + * 示例 1: + * + * 输入: [2,3,2] + * 输出: 3 + * 解释: 你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。 + * 示例 2: + * + * 输入: [1,2,3,1] + * 输出: 4 + * 解释: 你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。 + * 偷窃到的最高金额 = 1 + 3 = 4 。 + * + * @see house-robber-ii + */ +public class _213_rob { + public static void main(String[] args) { + _213_rob rob = new _213_rob(); + System.out.println(rob.rob(new int[]{2, 3, 2})); + System.out.println(rob.rob(new int[]{1, 2, 3, 1})); + } + + /** + * 解题思路: + * 难点->最后一个既然是和第一个相连的,不然一个动态规划等式就能解决了 + * dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]); + * 突破这个难点,使用两个规划数组,一个从0开始,n-1结束,另一个从1开始,n结束 + * 求出两个数组的最大值 + * + * @param nums + * @return + */ + public int rob(int[] nums) { + int length = nums.length; + if (length == 0) return 0; + if (length == 1) return nums[0]; + if (length == 2) return Math.max(nums[0], nums[1]); + //0->n-1 + int[] dp = new int[length - 1]; + dp[0] = nums[0]; + dp[1] = Math.max(nums[0], nums[1]); + for (int i = 2; i < length - 1; i++) { + dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]); + } + //1->n + int[] dp1 = new int[length - 1]; + dp1[0] = nums[1]; + dp1[1] = Math.max(nums[1], nums[2]); + for (int i = 3; i < length; i++) { + dp1[i - 1] = Math.max(dp1[i - 3] + nums[i], dp1[i - 2]); + } + + return Math.max(dp[length - 2], dp1[length - 2]); + } +} From 7c89483eb5622af0cb293de98961aab2f5dcc618 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 9 May 2019 10:42:25 +0800 Subject: [PATCH 043/308] docs: add _213_rob --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index de2f992..854451f 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成152道 +- leetcode练习,坚持每天一道,目前已完成153道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -24,7 +24,7 @@ - [x] [152. 乘积最大子序列](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_152_maxProduct.java) -- [ ] [213. 打家劫舍 II](https://leetcode-cn.com/problems/house-robber-ii/) +- [x] [213. 打家劫舍 II](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_213_rob.java) - [ ] [264. 丑数 II](https://leetcode-cn.com/problems/ugly-number-ii/) @@ -69,7 +69,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成152) +### 题目列表(更新中--已完成153) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -173,6 +173,7 @@ | #207 | [课程表](https://leetcode-cn.com/problems/course-schedule/) | [CanFinish](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_207_canFinish.java) | [BFS](https://leetcode-cn.com/tag/breadth-first-search/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/)、[图](https://leetcode-cn.com/tag/graph/)、[拓扑排序](https://leetcode-cn.com/tag/topological-sort/) | Medium | | | #208 | [实现 Trie (前缀树)](https://leetcode-cn.com/problems/implement-trie-prefix-tree/) | [Trie](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_208_Trie.java) | [设计](https://leetcode-cn.com/tag/design/)、[字典树](https://leetcode-cn.com/tag/trie/) | Medium | | | #211 | [添加与搜索单词 - 数据结构设计](https://leetcode-cn.com/problems/add-and-search-word-data-structure-design/) | [WordDictionary](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_211_wordDictionary.java) | [设计](https://leetcode-cn.com/tag/design/)、[字典树](https://leetcode-cn.com/tag/trie/)、[回溯算法]() | Medium | | +| #213 | [打家劫舍 II](https://leetcode-cn.com/problems/house-robber-ii/) | [Rob](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_213_rob.java) | [动态规划]() | Medium | | | #214 | [最短回文串](https://leetcode-cn.com/problems/shortest-palindrome/) | [ShortestPalindrome](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_214_shortestPalindrome_2.java) | [字符串]() | Hard | | | #215 | [数组中的第K个最大元素](https://leetcode-cn.com/problems/kth-largest-element-in-an-array/) | [FindKthLargest](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_215_findKthLargest_2.java) | [堆](https://leetcode-cn.com/tag/heap/)、[分治算法]() | Medium | | | #221 | [最大正方形](https://leetcode-cn.com/problems/maximal-square/) | [MaximalSquare](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_221_maximalSquare.java) | [动态规划]() | Medium | | From f52fc35658d1e10951fba34f41e59a0e6a1b670b Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 9 May 2019 15:23:12 +0800 Subject: [PATCH 044/308] feat(MEDIUM): add _264_nthUglyNumber --- .../leetcode/_264_nthUglyNumber.java | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_264_nthUglyNumber.java diff --git a/src/pp/arithmetic/leetcode/_264_nthUglyNumber.java b/src/pp/arithmetic/leetcode/_264_nthUglyNumber.java new file mode 100644 index 0000000..86eb030 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_264_nthUglyNumber.java @@ -0,0 +1,109 @@ +package pp.arithmetic.leetcode; + +import java.util.HashMap; + +/** + * Created by wangpeng on 2019-05-09. + * 264. 丑数 II + *

+ * 编写一个程序,找出第 n 个丑数。 + *

+ * 丑数就是只包含质因数 2, 3, 5 的正整数。 + *

+ * 示例: + *

+ * 输入: n = 10 + * 输出: 12 + * 解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。 + * 说明: + *

+ * 1 是丑数。 + * n 不超过1690。 + * + * @see ugly-number-ii + */ +public class _264_nthUglyNumber { + + public static void main(String[] args) { + _264_nthUglyNumber nthUglyNumber = new _264_nthUglyNumber(); + System.out.println(nthUglyNumber.nthUglyNumber(10)); + long start = System.currentTimeMillis(); + System.out.println(nthUglyNumber.nthUglyNumber(431)); + long end = System.currentTimeMillis(); + System.out.println("循环法计算431耗时:" + (end - start)); + start = System.currentTimeMillis(); + System.out.println(nthUglyNumber.nthUglyNumber2(431)); + end = System.currentTimeMillis(); + System.out.println("三指针法计算431耗时:" + (end - start)); + } + + /** + * 解题二:动态规划+三指针 + * dp保存按序排列的丑数,三指针分别是*2,*3,*5,找出下一个丑数 + * + * @param n + * @return + */ + public int nthUglyNumber2(int n) { + int[] dp = new int[n]; + dp[0] = 1; + int i2 = 0, i3 = 0, i5 = 0; + for (int i = 1; i < n; i++) { + int min = Math.min(dp[i2] * 2, Math.min(dp[i3] * 3, dp[i5] * 5)); + if (min == dp[i2] * 2) i2++; + if (min == dp[i3] * 3) i3++; + if (min == dp[i5] * 5) i5++; + dp[i] = min; + } + + return dp[n - 1]; + } + + private HashMap map = new HashMap<>(); + + /** + * 丑数求解过程:首先除2,直到不能整除为止,然后除5到不能整除为止,然后除3直到不能整除为止。 + * 最终判断剩余的数字是否为1,如果是1则为丑数,否则不是丑数 + *

+ * 解题思路: + * 从1开始遍历,按丑数求解过程找出满足条件的第n个丑数(提交超时) + * 思路优化(如何利用之前的计算) + * + * @param n + * @return + */ + public int nthUglyNumber(int n) { + map.put(1, true); + int uglyCount = 1; + int retVal = 1; + for (int i = 2; i < Integer.MAX_VALUE; i++) { + if (uglyCount >= n) { + break; + } + boolean isUgly = isUglyNumber(i); + if (isUgly) { + map.put(i, true); + uglyCount++; + retVal = i; + } + } + + return retVal; + } + + private boolean isUglyNumber(int num) { + while (num % 2 == 0) { + num = num / 2; + if (map.containsKey(num)) return true; + } + while (num % 5 == 0) { + num = num / 5; + if (map.containsKey(num)) return true; + } + while (num % 3 == 0) { + num = num / 3; + if (map.containsKey(num)) return true; + } + return num == 1; + } +} From b6d17320f693c817331d9a6166fcabb5dc1fe708 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 9 May 2019 15:29:11 +0800 Subject: [PATCH 045/308] docs: add _264_nthUglyNumber --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 854451f..4a5e061 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成153道 +- leetcode练习,坚持每天一道,目前已完成154道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -26,7 +26,7 @@ - [x] [213. 打家劫舍 II](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_213_rob.java) -- [ ] [264. 丑数 II](https://leetcode-cn.com/problems/ugly-number-ii/) +- [x] [264. 丑数 II](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_264_nthUglyNumber.java) - [ ] [279. 完全平方数](https://leetcode-cn.com/problems/perfect-squares/) @@ -69,7 +69,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成153) +### 题目列表(更新中--已完成154) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -183,6 +183,7 @@ | #236 | [二叉树的最近公共祖先](https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/) | [LowestCommonAncestor](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_236_lowestCommonAncestor.java) | [树](https://leetcode-cn.com/tag/tree/) | Medium | | | #237 | [删除链表中的节点](https://leetcode-cn.com/problems/delete-node-in-a-linked-list/) | [DeleteNode](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_237_deleteNode.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Easy | | | #239 | [滑动窗口最大值](https://leetcode-cn.com/problems/sliding-window-maximum/) | [MaxSlidingWindow](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_239_maxSlidingWindow.java) | [堆](https://leetcode-cn.com/tag/heap/)、[sliding window]() | Hard | | +| #264 | [丑数 II](https://leetcode-cn.com/problems/ugly-number-ii/) | [NthUglyNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_264_nthUglyNumber.java) | [堆](https://leetcode-cn.com/tag/heap/)、[数学]()、[动态规划]() | Medium | | | #290 | [单词模式](https://leetcode-cn.com/problems/word-pattern/) | [WordPattern](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_290_wordPattern.java) | [哈希表]() | Easy | | | #300 | [最长上升子序列](https://leetcode-cn.com/problems/longest-increasing-subsequence/) | [LengthOfLIS](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_300_lengthOfLIS.java) | [二分查找]()、[动态规划]() | Medium | | | #303 | [区域和检索 - 数组不可变](https://leetcode-cn.com/problems/range-sum-query-immutable/) | [NumArray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_303_NumArray.java) | [动态规划]() | Easy | | From b3207197a3f649e4fc62e90f0baff38c36fa4b3a Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 9 May 2019 19:41:58 +0800 Subject: [PATCH 046/308] feat(MEDIUM): add _279_numSquares --- .../arithmetic/leetcode/_279_numSquares.java | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_279_numSquares.java diff --git a/src/pp/arithmetic/leetcode/_279_numSquares.java b/src/pp/arithmetic/leetcode/_279_numSquares.java new file mode 100644 index 0000000..60ecfe4 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_279_numSquares.java @@ -0,0 +1,58 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-05-09. + * 279. 完全平方数 + *

+ * 给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。 + *

+ * 示例 1: + *

+ * 输入: n = 12 + * 输出: 3 + * 解释: 12 = 4 + 4 + 4. + * 示例 2: + *

+ * 输入: n = 13 + * 输出: 2 + * 解释: 13 = 4 + 9. + * + * @see perfect-squares + */ +public class _279_numSquares { + + public static void main(String[] args) { + _279_numSquares numSquares = new _279_numSquares(); + System.out.println(numSquares.numSquares(12)); + System.out.println(numSquares.numSquares(13)); + } + + /** + * 直接思路:找出N最接近的平方数,再循环找出剩余最接近的平方数集合(结果可能不是最优) + * 比如:12->9+1+1+1,最优的是12->4+4+4 + * 所以,上面的思路还得把所有的情况都求出来,再选出最少的,性能较差 + *

+ * 优化思路:利用之前计算的步数,转换为动态规划方程 + * dp[i]代表第i需要的最少步骤,遍历所有的情况,从而找出最优解 + * for (int j = 1; i - j * j >= 0; j++) { + * dp[i] = Math.min(dp[i], dp[i - j * j] + 1); + * } + * + * + * @param n + * @return + */ + public int numSquares(int n) { + //利用动态规划 定义长度为n+1的数组 对应索引所对应的数装最少的步数 + int[] dp = new int[n + 1]; + dp[0] = 0; + for (int i = 1; i <= n; i++) { + dp[i] = i; //先假设到这一步的最大的步数为每次+1 + for (int j = 1; i - j * j >= 0; j++) { //i-j*j>=0 找到最大的j j*j就是i里面最大的完全平方数 + //dp[i-j*j]+1 表示d[i-j*j]的步数+1 1即j*j这个完全平方数只需要一步 + dp[i] = Math.min(dp[i], dp[i - j * j] + 1); + } + } + return dp[n]; + } +} From c376d05dfe3f9a0e8302c8a585ae7a718c2cf267 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 9 May 2019 19:44:46 +0800 Subject: [PATCH 047/308] docs: add _279_numSquares --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4a5e061..1ebd312 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成154道 +- leetcode练习,坚持每天一道,目前已完成155道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -28,7 +28,7 @@ - [x] [264. 丑数 II](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_264_nthUglyNumber.java) -- [ ] [279. 完全平方数](https://leetcode-cn.com/problems/perfect-squares/) +- [x] [279. 完全平方数](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_279_numSquares.java) - [ ] [309. 最佳买卖股票时机含冷冻期](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) @@ -69,7 +69,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成154) +### 题目列表(更新中--已完成155) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -184,6 +184,7 @@ | #237 | [删除链表中的节点](https://leetcode-cn.com/problems/delete-node-in-a-linked-list/) | [DeleteNode](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_237_deleteNode.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Easy | | | #239 | [滑动窗口最大值](https://leetcode-cn.com/problems/sliding-window-maximum/) | [MaxSlidingWindow](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_239_maxSlidingWindow.java) | [堆](https://leetcode-cn.com/tag/heap/)、[sliding window]() | Hard | | | #264 | [丑数 II](https://leetcode-cn.com/problems/ugly-number-ii/) | [NthUglyNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_264_nthUglyNumber.java) | [堆](https://leetcode-cn.com/tag/heap/)、[数学]()、[动态规划]() | Medium | | +| #279 | [完全平方数](https://leetcode-cn.com/problems/perfect-squares/) | [NumSquares](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_279_numSquares.java) | [BFS](https://leetcode-cn.com/tag/breadth-first-search/)、[数学]()、[动态规划]() | Medium | | | #290 | [单词模式](https://leetcode-cn.com/problems/word-pattern/) | [WordPattern](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_290_wordPattern.java) | [哈希表]() | Easy | | | #300 | [最长上升子序列](https://leetcode-cn.com/problems/longest-increasing-subsequence/) | [LengthOfLIS](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_300_lengthOfLIS.java) | [二分查找]()、[动态规划]() | Medium | | | #303 | [区域和检索 - 数组不可变](https://leetcode-cn.com/problems/range-sum-query-immutable/) | [NumArray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_303_NumArray.java) | [动态规划]() | Easy | | From c93c36efe1628b8a67e1d983b6ee79e70309a893 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Fri, 10 May 2019 10:40:11 +0800 Subject: [PATCH 048/308] feat(MEDIUM): add _309_maxProfit --- .../arithmetic/leetcode/_309_maxProfit.java | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_309_maxProfit.java diff --git a/src/pp/arithmetic/leetcode/_309_maxProfit.java b/src/pp/arithmetic/leetcode/_309_maxProfit.java new file mode 100644 index 0000000..9825f20 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_309_maxProfit.java @@ -0,0 +1,101 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-05-10. + * 309. 最佳买卖股票时机含冷冻期 + *

+ * 给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。​ + *

+ * 设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票): + *

+ * 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。 + * 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。 + * 示例: + *

+ * 输入: [1,2,3,0,2] + * 输出: 3 + * 解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出] + * + * @see best-time-to-buy-and-sell-stock-with-cooldown + */ +public class _309_maxProfit { + public static void main(String[] args) { + _309_maxProfit maxProfit = new _309_maxProfit(); + System.out.println(maxProfit.maxProfit(new int[]{1, 2, 3, 0, 2})); + System.out.println(maxProfit.maxProfit2(new int[]{1, 2, 3, 0, 2})); + } + + /** + * 解题思路(动态规划): + * 可以将问题拆解为前i天获利最大,如果股票在手上没有卖出去,获利应该算亏本吧? + * 第i+1天的获利最大情况:第i天买入,第i-1天买入...第1天买入,求出个最大值 + * 假设第i天买入,此时上一次买入时间必须是i-2天,可以用此次的获利+dp[i-2]得到总获利值(注意i>=2) + * 得出状态转移方程 + * if (j >= 2) { + * dp[i] = Math.max(diffPrice + dp[j - 2], dp[i]); + * } else { + * dp[i] = Math.max(diffPrice, dp[i]); + * } + * 提交结果: + * 执行用时 : 52 ms, 在Best Time to Buy and Sell Stock with Cooldown的Java提交中击败了5.67% 的用户 + * 内存消耗 : 34.5 MB, 在Best Time to Buy and Sell Stock with Cooldown的Java提交中击败了87.95% 的用户 + * 执行耗时并不是很理想,思考耗时在哪? + * 综合分析,整体时间复杂度在O(n^2)级别,待优化{@link _309_maxProfit#maxProfit(int[])} + * + * @param prices + * @return + */ + public int maxProfit(int[] prices) { + if (prices.length <= 1) return 0; + if (prices.length == 2) return Math.max(prices[1] - prices[0], 0); + + int[] dp = new int[prices.length]; + dp[0] = 0; + for (int i = 1; i < prices.length; i++) { + //当前不执行任何操作 + dp[i] = dp[i - 1]; + //当前执行卖出操作 + for (int j = i - 1; j >= 0; j--) { + int diffPrice = prices[i] - prices[j]; + if (diffPrice <= 0) continue; + //如果j买入的话,上一次卖出获利必须是j-2日 + if (j >= 2) { + dp[i] = Math.max(diffPrice + dp[j - 2], dp[i]); + } else { + dp[i] = Math.max(diffPrice, dp[i]); + } + } + } + + return dp[prices.length - 1]; + } + + /** + * 解题二: + * 优化{@link _309_maxProfit#maxProfit(int[])}中的问题 + * 使用两个数组进行存储,一个是持有成本,一个是卖出获利 + * + * @param prices + * @return + */ + public int maxProfit2(int[] prices) { + if (prices == null || prices.length <= 1) { + return 0; + } + //持有成本 + int[] hold = new int[prices.length]; + //卖出获利 + int[] profit = new int[prices.length]; + hold[0] = -prices[0]; + for (int i = 1; i < prices.length; i++) { + if (i == 1) { + hold[i] = Math.max(hold[i - 1], -prices[1]); + } else { + hold[i] = Math.max(hold[i - 1], profit[i - 2] - prices[i]); + } + //当前不卖出,或者卖出,取最大值 + profit[i] = Math.max(profit[i - 1], hold[i - 1] + prices[i]); + } + return profit[prices.length - 1]; + } +} From 3df63394d450d07288a00c7f8220574306cffe91 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Fri, 10 May 2019 10:45:13 +0800 Subject: [PATCH 049/308] docs: add _309_maxProfit --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1ebd312..a99d7a3 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成155道 +- leetcode练习,坚持每天一道,目前已完成156道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -30,7 +30,7 @@ - [x] [279. 完全平方数](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_279_numSquares.java) -- [ ] [309. 最佳买卖股票时机含冷冻期](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) +- [x] [309. 最佳买卖股票时机含冷冻期](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_309_maxProfit.java) - [ ] [338. 比特位计数](https://leetcode-cn.com/problems/counting-bits/) @@ -69,7 +69,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成155) +### 题目列表(更新中--已完成156) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -190,6 +190,7 @@ | #303 | [区域和检索 - 数组不可变](https://leetcode-cn.com/problems/range-sum-query-immutable/) | [NumArray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_303_NumArray.java) | [动态规划]() | Easy | | | #304 | [二维区域和检索 - 矩阵不可变](https://leetcode-cn.com/problems/range-sum-query-2d-immutable/) | [NumMatrix](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_304_NumMatrix.java) | [动态规划]() | Medium | | | #307 | [区域和检索 - 数组可修改](https://leetcode-cn.com/problems/range-sum-query-mutable/) | [NumArray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_307_NumArray_2.java) | [树状数组](https://leetcode-cn.com/tag/binary-indexed-tree/)、[线段树](https://leetcode-cn.com/tag/segment-tree/) | Medium | | +| #309 | [最佳买卖股票时机含冷冻期](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) | [MaxProfit](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_309_maxProfit.java) | [动态规划]() | Medium | | | #315 | [计算右侧小于当前元素的个数](https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self/) | [CountSmaller](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_315_countSmaller_2.java) | [树状数组](https://leetcode-cn.com/tag/binary-indexed-tree/)、[线段树](https://leetcode-cn.com/tag/segment-tree/)、[二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)、[分治算法]() | Hard | | | #322 | [零钱兑换](https://leetcode-cn.com/problems/coin-change/) | [CoinChange](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_322_coinChange.java) | [动态规划]() | Medium | | | #328 | [奇偶链表](https://leetcode-cn.com/problems/odd-even-linked-list/) | [OddEvenList](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_328_OddEvenList.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | From c5b1791c82ba38276fb75844c5ebe99a0c38bc8b Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 13 May 2019 11:03:48 +0800 Subject: [PATCH 050/308] feat(MEDIUM): add _338_countBits --- .../arithmetic/leetcode/_338_countBits.java | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_338_countBits.java diff --git a/src/pp/arithmetic/leetcode/_338_countBits.java b/src/pp/arithmetic/leetcode/_338_countBits.java new file mode 100644 index 0000000..cc33ee2 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_338_countBits.java @@ -0,0 +1,72 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +/** + * Created by wangpeng on 2019-05-13. + * 338. 比特位计数 + *

+ * 给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。 + *

+ * 示例 1: + *

+ * 输入: 2 + * 输出: [0,1,1] + * 示例 2: + *

+ * 输入: 5 + * 输出: [0,1,1,2,1,2] + * 进阶: + *

+ * 给出时间复杂度为O(n*sizeof(integer))的解答非常容易。但你可以在线性时间O(n)内用一趟扫描做到吗? + * 要求算法的空间复杂度为O(n)。 + * 你能进一步完善解法吗?要求在C++或任何其他语言中不使用任何内置函数(如 C++ 中的 __builtin_popcount)来执行此操作。 + * + * @see counting-bits + */ +public class _338_countBits { + public static void main(String[] args) { + _338_countBits countBits = new _338_countBits(); + Util.printArray(countBits.countBits(2)); + Util.printArray(countBits.countBits(5)); + } + + /** + * 题目已经强调了需要O(n)的复杂度,只能遍历一遍,可以考虑动态规划 + * 根据题目意思,先手动画一下数字和2进制的具体映射关系 + * 数字 0 1 2 3 4 5 6 7 8 + * 二进 0 1 10 11 100 101 110 111 1000 + * 1个数 0 1 1 2 1 2 2 3 1 + * 根据递推效果,看着好像没有什么规律 + * 但是仔细思考下,10进制转2进制必须要除以2,有些能整除,有些不能整除 + * 不能整除的3的1个数=3/1=数字1的1个数+1 + * 能整除的4的的1个数=4/2=数字2的1个数 + * 拿其他数字验证后发现的确是这个规律,得到动态规划状态转移方程: + * int d = i / 2; + * int m = i % 2; + * if (m == 0) { + * dp[i] = dp[d]; + * } else { + * dp[i] = dp[d] + 1; + * } + * + * @param num + * @return + */ + public int[] countBits(int num) { + if (num < 0) return new int[0]; + int[] dp = new int[num + 1]; + dp[0] = 0; + for (int i = 1; i <= num; i++) { + int d = i / 2; + int m = i % 2; + if (m == 0) { + dp[i] = dp[d]; + } else { + dp[i] = dp[d] + 1; + } + } + + return dp; + } +} From 043d31218fd7f39365844497a78a2c16e4a950d8 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 13 May 2019 11:06:52 +0800 Subject: [PATCH 051/308] docs: add _338_countBits --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a99d7a3..fb94628 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成156道 +- leetcode练习,坚持每天一道,目前已完成157道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -32,7 +32,7 @@ - [x] [309. 最佳买卖股票时机含冷冻期](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_309_maxProfit.java) -- [ ] [338. 比特位计数](https://leetcode-cn.com/problems/counting-bits/) +- [x] [338. 比特位计数](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_338_countBits.java) - [ ] [343. 整数拆分](https://leetcode-cn.com/problems/integer-break/) @@ -69,7 +69,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成156) +### 题目列表(更新中--已完成157) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -195,6 +195,7 @@ | #322 | [零钱兑换](https://leetcode-cn.com/problems/coin-change/) | [CoinChange](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_322_coinChange.java) | [动态规划]() | Medium | | | #328 | [奇偶链表](https://leetcode-cn.com/problems/odd-even-linked-list/) | [OddEvenList](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_328_OddEvenList.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | | #336 | [回文对](https://leetcode-cn.com/problems/palindrome-pairs/) | [PalindromePairs](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_336_palindromePairs_2.java) | [字典树](https://leetcode-cn.com/tag/trie/)、[哈希表]()、[字符串]() | Hard | | +| #338 | [比特位计数](https://leetcode-cn.com/problems/counting-bits/) | [CountBits](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_338_countBits.java) | [位运算](https://leetcode-cn.com/tag/bit-manipulation/)、[动态规划]() | Medium | | | #354 | [俄罗斯套娃信封问题](https://leetcode-cn.com/problems/russian-doll-envelopes/) | [MaxEnvelopes.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_354_maxEnvelopes_2.java) | [二分查找]()、[动态规划]() | Hard | | | #376 | [摆动序列](https://leetcode-cn.com/problems/wiggle-subsequence/) | [WiggleMaxLength](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_376_wiggleMaxLength.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[动态规划]() | Medium | | | #402 | [移掉K位数字](https://leetcode-cn.com/problems/remove-k-digits/) | [RemoveKdigits](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_402_removeKdigits.java) | [堆](https://leetcode-cn.com/tag/heap/)、[贪心算法](https://leetcode-cn.com/tag/greedy/) | Medium | | From 649047948132c55c6f6814d3bd5a686dfa131178 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 13 May 2019 18:02:19 +0800 Subject: [PATCH 052/308] feat(MEDIUM): add _343_integerBreak --- .../leetcode/_343_integerBreak.java | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_343_integerBreak.java diff --git a/src/pp/arithmetic/leetcode/_343_integerBreak.java b/src/pp/arithmetic/leetcode/_343_integerBreak.java new file mode 100644 index 0000000..50ec972 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_343_integerBreak.java @@ -0,0 +1,61 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-05-13. + * 343. 整数拆分 + *

+ * 给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。 + *

+ * 示例 1: + *

+ * 输入: 2 + * 输出: 1 + * 解释: 2 = 1 + 1, 1 × 1 = 1。 + * 示例 2: + *

+ * 输入: 10 + * 输出: 36 + * 解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。 + * 说明: 你可以假设 n 不小于 2 且不大于 58。 + * + * @see integer-break + */ +public class _343_integerBreak { + public static void main(String[] args) { + _343_integerBreak integerBreak = new _343_integerBreak(); + System.out.println(integerBreak.integerBreak(8)); + System.out.println(integerBreak.integerBreak(10)); + System.out.println(integerBreak.integerBreak(14)); + } + + /** + * 解题思路: + * 手动模拟了从2-10的最大乘积数字拆解,发现了一个现象: + * 对于数字n,n一直除以2到1为止,得到的数字就是最大的乘积,举例如下: + * 数字n 2 3 4 5 6 7 8 9 10 + * 乘积 1,1 1,2 2,2 2,3 3,3 3,4(2,2) 4(2,2),4(2,2) 4,5(2,3) 5(2,3),5(2,3) + * 发现到了后面的最大乘积可以利用之前的计算好的结果,从而得出动态规划转移方程 + * dp[i]=dp[i/2]*dp[i-i/2](i>3) + * 上面有问题,例如8的最大值不是除以2得到4*4=16,而是3*2*3=18,所以得双重循环取所有情况的最大值 + * for (int j = 1; j <= i / 2; j++) { + * dp[i] = Math.max(dp[i], dp[j] * dp[i - j]); + * } + * + * @param n + * @return + */ + public int integerBreak(int n) { + if (n <= 3) return n - 1; + int[] dp = new int[n + 1]; + //初始化,1,2,3特殊处理 + dp[1] = 1; + dp[2] = 2; + dp[3] = 3; + for (int i = 4; i <= n; i++) { + for (int j = 1; j <= i / 2; j++) { + dp[i] = Math.max(dp[i], dp[j] * dp[i - j]); + } + } + return dp[n]; + } +} From bde9862f8827d5e8d46fdfb33875e3a1e666fe4d Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 13 May 2019 18:08:49 +0800 Subject: [PATCH 053/308] docs: add _343_integerBreak --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fb94628..53cad42 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成157道 +- leetcode练习,坚持每天一道,目前已完成158道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -34,7 +34,7 @@ - [x] [338. 比特位计数](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_338_countBits.java) -- [ ] [343. 整数拆分](https://leetcode-cn.com/problems/integer-break/) +- [x] [343. 整数拆分](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_343_integerBreak.java) ## 已解题目 @@ -69,7 +69,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成157) +### 题目列表(更新中--已完成158) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -196,6 +196,7 @@ | #328 | [奇偶链表](https://leetcode-cn.com/problems/odd-even-linked-list/) | [OddEvenList](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_328_OddEvenList.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | | #336 | [回文对](https://leetcode-cn.com/problems/palindrome-pairs/) | [PalindromePairs](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_336_palindromePairs_2.java) | [字典树](https://leetcode-cn.com/tag/trie/)、[哈希表]()、[字符串]() | Hard | | | #338 | [比特位计数](https://leetcode-cn.com/problems/counting-bits/) | [CountBits](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_338_countBits.java) | [位运算](https://leetcode-cn.com/tag/bit-manipulation/)、[动态规划]() | Medium | | +| #343 | [整数拆分](https://leetcode-cn.com/problems/integer-break/) | [IntegerBreak](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_343_integerBreak.java) | [数学]()、[动态规划]() | Medium | | | #354 | [俄罗斯套娃信封问题](https://leetcode-cn.com/problems/russian-doll-envelopes/) | [MaxEnvelopes.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_354_maxEnvelopes_2.java) | [二分查找]()、[动态规划]() | Hard | | | #376 | [摆动序列](https://leetcode-cn.com/problems/wiggle-subsequence/) | [WiggleMaxLength](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_376_wiggleMaxLength.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[动态规划]() | Medium | | | #402 | [移掉K位数字](https://leetcode-cn.com/problems/remove-k-digits/) | [RemoveKdigits](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_402_removeKdigits.java) | [堆](https://leetcode-cn.com/tag/heap/)、[贪心算法](https://leetcode-cn.com/tag/greedy/) | Medium | | From fdb9fb7d8140c7fe8438669071aeb11c2a92789e Mon Sep 17 00:00:00 2001 From: wangpeng Date: Tue, 14 May 2019 11:28:56 +0800 Subject: [PATCH 054/308] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E9=A2=98?= =?UTF-8?q?=E7=9B=AE=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 53cad42..3d32752 100644 --- a/README.md +++ b/README.md @@ -11,30 +11,15 @@ - 欢迎star、fork、交流,一起互勉 - 微信号:pp_hdsny(备注leetcode) - 网址:https://leetcode-cn.com/ -## 20190506-20190512待解题目列表(动态规划) +## 20190513-20190519待解题目列表 -> 动态规划解题四部曲,可供参考 -> -> - 确认**原问题与子问题**: -> - 确认**状态**: -> - 确认**边界状态的值**: -> - 确定**状态转移方程**: +开始一道道的刷题了,如有期望刷特定题目的,欢迎提issue。这周出去浪4天,所以只刷三道题目了 -鉴于上周做的动态规划Hard的太难了,这周全是Medium的练练手,习惯动态规划的解题思路 +- [ ] [36. 有效的数独-Medium](https://leetcode-cn.com/problems/valid-sudoku/) -- [x] [152. 乘积最大子序列](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_152_maxProduct.java) +- [ ] [37. 解数独-Hard](https://leetcode-cn.com/problems/sudoku-solver/) -- [x] [213. 打家劫舍 II](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_213_rob.java) - -- [x] [264. 丑数 II](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_264_nthUglyNumber.java) - -- [x] [279. 完全平方数](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_279_numSquares.java) - -- [x] [309. 最佳买卖股票时机含冷冻期](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_309_maxProfit.java) - -- [x] [338. 比特位计数](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_338_countBits.java) - -- [x] [343. 整数拆分](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_343_integerBreak.java) +- [ ] [38. 报数-Easy](https://leetcode-cn.com/problems/count-and-say/) ## 已解题目 From 42617eb6bdb7483d6dee2ce9ca2034de847626dc Mon Sep 17 00:00:00 2001 From: wangpeng Date: Tue, 14 May 2019 13:29:26 +0800 Subject: [PATCH 055/308] feat(EASY): add _38_countAndSay --- .../arithmetic/leetcode/_38_countAndSay.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_38_countAndSay.java diff --git a/src/pp/arithmetic/leetcode/_38_countAndSay.java b/src/pp/arithmetic/leetcode/_38_countAndSay.java new file mode 100644 index 0000000..5ca7e49 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_38_countAndSay.java @@ -0,0 +1,75 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-05-14. + * 38. 报数 + *

+ * 报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下: + *

+ * 1. 1 + * 2. 11 + * 3. 21 + * 4. 1211 + * 5. 111221 + * 1 被读作 "one 1" ("一个一") , 即 11。 + * 11 被读作 "two 1s" ("两个一"), 即 21。 + * 21 被读作 "one 2", "one 1" ("一个二" , "一个一") , 即 1211。 + *

+ * 给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。 + *

+ * 注意:整数顺序将表示为一个字符串。 + *

+ *

+ *

+ * 示例 1: + *

+ * 输入: 1 + * 输出: "1" + * 示例 2: + *

+ * 输入: 4 + * 输出: "1211" + * + * @see count-and-say + */ +public class _38_countAndSay { + + public static void main(String[] args) { + _38_countAndSay countAndSay = new _38_countAndSay(); + System.out.println(countAndSay.countAndSay(4)); + System.out.println(countAndSay.countAndSay(5)); + System.out.println(countAndSay.countAndSay(6)); + } + + /** + * 解题思路: + * 本题的难点在于:报数的概念理解,至少我从题意中没有很清晰的理解,但是感觉像是个递推式 + * 从4->5分析,将4个每一位拆开看(个数+数字),4=1211 => 1=11,2=12,11=21,所以5=111221 + * 所以解题用循环,从1->n可求解出来 + * + * @param n + * @return + */ + public String countAndSay(int n) { + String str = "1"; + for (int i = 2; i <= n; i++) { + StringBuilder builder = new StringBuilder(); + char pre = str.charAt(0); + int count = 1; + for (int j = 1; j < str.length(); j++) { + char c = str.charAt(j); + if (c == pre) { + count++; + } else { + builder.append(count).append(pre); + pre = c; + count = 1; + } + } + builder.append(count).append(pre); + str = builder.toString(); + } + + return str; + } +} From f4d9071712bcac8abe1c9914e51d3a5ecc73365c Mon Sep 17 00:00:00 2001 From: wangpeng Date: Tue, 14 May 2019 13:31:28 +0800 Subject: [PATCH 056/308] docs: add _38_countAndSay --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3d32752..de1cf41 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成158道 +- leetcode练习,坚持每天一道,目前已完成159道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -19,7 +19,7 @@ - [ ] [37. 解数独-Hard](https://leetcode-cn.com/problems/sudoku-solver/) -- [ ] [38. 报数-Easy](https://leetcode-cn.com/problems/count-and-say/) +- [x] [38. 报数-Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_38_countAndSay.java) ## 已解题目 @@ -54,7 +54,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成158) +### 题目列表(更新中--已完成159) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -93,6 +93,7 @@ | #33 | [搜索旋转排序数组](https://leetcode-cn.com/problems/search-in-rotated-sorted-array/) | [Search](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_33_search.java) | [数组]()、[二分查找]() | Medium | | | #34 | [在排序数组中查找元素的第一个和最后一个位置](https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/) | [SearchRange](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_34_searchRange.java) | [数组]()、[二分查找]() | Medium | | | #35 | [搜索插入位置](https://leetcode-cn.com/problems/search-insert-position/) | [SearchInsert](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_35_searchInsert.java) | [数组]()、[二分查找]() | Easy | | +| #38 | [报数](https://leetcode-cn.com/problems/count-and-say/) | [CountAndSay](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_38_countAndSay.java) | [字符串]() | Easy | | | #40 | [组合总和 II](https://leetcode-cn.com/problems/combination-sum-ii/) | [CombinationSum2](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_40_combinationSum2.java) | [数组]()、[回溯算法]() | Medium | | | #42 | [接雨水](https://leetcode-cn.com/problems/trapping-rain-water/) | [Trap](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_42_trap.java) | [栈](https://leetcode-cn.com/tag/stack/)、[数组]()、[双指针]() | Hard | | | #43 | [字符串相乘](https://leetcode-cn.com/problems/multiply-strings/) | [Multiply](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_43_multiply.java) | [数学]()、[字符串]() | Medium | | From 035fdea687bad61709f0f1de9999bbd638d10430 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Wed, 15 May 2019 10:17:47 +0800 Subject: [PATCH 057/308] feat(MEDIUM): add _36_isValidSudoku --- .../leetcode/_36_isValidSudoku.java | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_36_isValidSudoku.java diff --git a/src/pp/arithmetic/leetcode/_36_isValidSudoku.java b/src/pp/arithmetic/leetcode/_36_isValidSudoku.java new file mode 100644 index 0000000..245ec9c --- /dev/null +++ b/src/pp/arithmetic/leetcode/_36_isValidSudoku.java @@ -0,0 +1,118 @@ +package pp.arithmetic.leetcode; + +import java.util.HashMap; + +/** + * Created by wangpeng on 2019-05-14. + * 36. 有效的数独 + * + * 判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。 + * + * 数字 1-9 在每一行只能出现一次。 + * 数字 1-9 在每一列只能出现一次。 + * 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。 + * + * + * 上图是一个部分填充的有效的数独。 + * + * 数独部分空格内已填入了数字,空白格用 '.' 表示。 + * + * 示例 1: + * + * 输入: + * [ + * ["5","3",".",".","7",".",".",".","."], + * ["6",".",".","1","9","5",".",".","."], + * [".","9","8",".",".",".",".","6","."], + * ["8",".",".",".","6",".",".",".","3"], + * ["4",".",".","8",".","3",".",".","1"], + * ["7",".",".",".","2",".",".",".","6"], + * [".","6",".",".",".",".","2","8","."], + * [".",".",".","4","1","9",".",".","5"], + * [".",".",".",".","8",".",".","7","9"] + * ] + * 输出: true + * 示例 2: + * + * 输入: + * [ + * ["8","3",".",".","7",".",".",".","."], + * ["6",".",".","1","9","5",".",".","."], + * [".","9","8",".",".",".",".","6","."], + * ["8",".",".",".","6",".",".",".","3"], + * ["4",".",".","8",".","3",".",".","1"], + * ["7",".",".",".","2",".",".",".","6"], + * [".","6",".",".",".",".","2","8","."], + * [".",".",".","4","1","9",".",".","5"], + * [".",".",".",".","8",".",".","7","9"] + * ] + * 输出: false + * 解释: 除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。 + * 但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。 + * 说明: + * + * 一个有效的数独(部分已被填充)不一定是可解的。 + * 只需要根据以上规则,验证已经填入的数字是否有效即可。 + * 给定数独序列只包含数字 1-9 和字符 '.' 。 + * 给定数独永远是 9x9 形式的。 + */ +public class _36_isValidSudoku { + + public static void main(String[] args) { + char[][] board = new char[][]{ + {'5', '3', '.', '.', '7', '.', '.', '.', '.'}, + {'6', '.', '.', '1', '9', '5', '.', '.', '.'}, + {'.', '9', '8', '.', '.', '.', '.', '6', '.'}, + {'8', '.', '.', '.', '6', '.', '.', '.', '3'}, + {'4', '.', '.', '8', '.', '3', '.', '.', '1'}, + {'7', '.', '.', '.', '2', '.', '.', '.', '6'}, + {'.', '6', '.', '.', '.', '.', '2', '8', '.'}, + {'.', '.', '.', '4', '1', '9', '.', '.', '5'}, + {'.', '.', '.', '.', '8', '.', '.', '7', '9'} + }; + _36_isValidSudoku isValidSudoku = new _36_isValidSudoku(); + System.out.println(isValidSudoku.isValidSudoku(board)); + } + + /** + * 解题思路: + * 首先必须理解有效数独的定义 + * 要知道是否满足数独的要求,肯定所有的点都得遍历到,所以得双重遍历 + * 在双重遍历中得匹配之前的遍历结果,看是否有重复的数字,考虑用hashmap报错遍历结果 + * hashmap中存储的key是有三种:行的index+数字、列的index+数字、3*3宫格的index+数字 + * + * 提交结果: + * 执行用时 : 16 ms, 在Valid Sudoku的Java提交中击败了62.19% 的用户 + * 内存消耗 : 42.4 MB, 在Valid Sudoku的Java提交中击败了81.42% 的用户 + * 结果并不是很出色,看了其他优秀解法,发现他们存储是固定大小三个数组, + * 仔细想想也是,HashMap虽然查找是O(1),但是扩容的时候是有时间消耗的,对于这种固定大小的可以考虑用数组进行优化 + * 官方解题,是分了三个HashMap,估计也是为了减少扩容的时间消耗吧 + * + * @param board + * @return + */ + public boolean isValidSudoku(char[][] board) { + HashMap map = new HashMap<>(); + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[i].length; j++) { + char num = board[i][j]; + if (num == '.') continue; + String rowKey = i + "row" + num; + String colKey = j + "col" + num; + int groupIndex = i / 3 + j / 3 * 3; + String groupKey = groupIndex + "group" + num; + //寻找是否有重复的数字 + if (map.getOrDefault(rowKey, false) + || map.getOrDefault(colKey, false) + || map.getOrDefault(groupKey, false)) { + return false; + } + //更新遍历记录 + map.put(rowKey, true); + map.put(colKey, true); + map.put(groupKey, true); + } + } + return true; + } +} From 1886844d44a0e0d81167e93d5afa75f6d8ccbbe5 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Wed, 15 May 2019 11:36:24 +0800 Subject: [PATCH 058/308] feat(HARD): add _37_solveSudoku --- .../arithmetic/leetcode/_37_solveSudoku.java | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_37_solveSudoku.java diff --git a/src/pp/arithmetic/leetcode/_37_solveSudoku.java b/src/pp/arithmetic/leetcode/_37_solveSudoku.java new file mode 100644 index 0000000..9051719 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_37_solveSudoku.java @@ -0,0 +1,131 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-05-15. + * 37. 解数独 + * + * 编写一个程序,通过已填充的空格来解决数独问题。 + * + * 一个数独的解法需遵循如下规则: + * + * 数字 1-9 在每一行只能出现一次。 + * 数字 1-9 在每一列只能出现一次。 + * 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。 + * 空白格用 '.' 表示。 + * + * + * + * 一个数独。 + * + * + * + * 答案被标成红色。 + * + * Note: + * + * 给定的数独序列只包含数字 1-9 和字符 '.' 。 + * 你可以假设给定的数独只有唯一解。 + * 给定数独永远是 9x9 形式的。 + * + * @see sudoku-solver + */ +public class _37_solveSudoku { + + public static void main(String[] args) { + char[][] board = new char[][]{ + {'5', '3', '.', '.', '7', '.', '.', '.', '.'}, + {'6', '.', '.', '1', '9', '5', '.', '.', '.'}, + {'.', '9', '8', '.', '.', '.', '.', '6', '.'}, + {'8', '.', '.', '.', '6', '.', '.', '.', '3'}, + {'4', '.', '.', '8', '.', '3', '.', '.', '1'}, + {'7', '.', '.', '.', '2', '.', '.', '.', '6'}, + {'.', '6', '.', '.', '.', '.', '2', '8', '.'}, + {'.', '.', '.', '4', '1', '9', '.', '.', '5'}, + {'.', '.', '.', '.', '8', '.', '.', '7', '9'} + }; + _37_solveSudoku solveSudoku = new _37_solveSudoku(); + solveSudoku.solveSudoku(board); + print(board); + } + + private static void print(char[][] board){ + for (int i = 0; i < 9; i++) { + for (int j = 0; j < 9; j++) { + System.out.print(board[i][j] + " "); + } + System.out.println(); + } + } + + /** + * 解题思路: + * 数独的解法就是通过填空,不断的试,可以考虑回溯算法解决 + * 本题是他人解法,回溯挺绕的 + * + * @param board + */ + public void solveSudoku(char[][] board) { + /** + * 记录某行,某位数字是否已经被摆放 + */ + boolean[][] row = new boolean[9][10]; + /** + * 记录某列,某位数字是否已经被摆放 + */ + boolean[][] col = new boolean[9][10]; + /** + * 记录某 3x3 宫格内,某位数字是否已经被摆放 + */ + boolean[][] block = new boolean[9][10]; + + for (int i = 0; i < 9; i++) { + for (int j = 0; j < 9; j++) { + if (board[i][j] != '.') { + int num = board[i][j] - '0'; + row[i][num] = true; + col[j][num] = true; + // blockIndex = i / 3 * 3 + j / 3,取整 + block[i / 3 * 3 + j / 3][num] = true; + } + } + } + dfs(board, row, col, block, 0, 0); + } + + private boolean dfs(char[][] board, + boolean[][] row, + boolean[][] col, + boolean[][] block, + int i, int j) { + // 找寻空位置 + while (board[i][j] != '.') { + if (++j >= 9) { + i++; + j = 0; + } + if (i >= 9) { + return true; + } + } + for (int num = 1; num <= 9; num++) { + int blockIndex = i / 3 * 3 + j / 3; + if (!row[i][num] && !col[j][num] && !block[blockIndex][num]) { + // 递归 + board[i][j] = (char) ('0' + num); + row[i][num] = true; + col[j][num] = true; + block[blockIndex][num] = true; + if (dfs(board, row, col, block, i, j)) { + return true; + } else { + // 回溯 + row[i][num] = false; + col[j][num] = false; + block[blockIndex][num] = false; + board[i][j] = '.'; + } + } + } + return false; + } +} From ba990265dc604a1a690e339613eb1f61ca23cb03 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Wed, 15 May 2019 13:34:21 +0800 Subject: [PATCH 059/308] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B036&37?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index de1cf41..c000eea 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成159道 +- leetcode练习,坚持每天一道,目前已完成161道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -15,12 +15,12 @@ 开始一道道的刷题了,如有期望刷特定题目的,欢迎提issue。这周出去浪4天,所以只刷三道题目了 -- [ ] [36. 有效的数独-Medium](https://leetcode-cn.com/problems/valid-sudoku/) - -- [ ] [37. 解数独-Hard](https://leetcode-cn.com/problems/sudoku-solver/) - +- [x] [36. 有效的数独-Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_36_isValidSudoku.java) +- [x] [37. 解数独-Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_37_solveSudoku.java) - [x] [38. 报数-Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_38_countAndSay.java) +下周题目预告:回溯相关题解 + ## 已解题目 > 20190404# leetcode目前已有题目1020道,免费852道 @@ -54,7 +54,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成159) +### 题目列表(更新中--已完成161) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -93,6 +93,8 @@ | #33 | [搜索旋转排序数组](https://leetcode-cn.com/problems/search-in-rotated-sorted-array/) | [Search](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_33_search.java) | [数组]()、[二分查找]() | Medium | | | #34 | [在排序数组中查找元素的第一个和最后一个位置](https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/) | [SearchRange](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_34_searchRange.java) | [数组]()、[二分查找]() | Medium | | | #35 | [搜索插入位置](https://leetcode-cn.com/problems/search-insert-position/) | [SearchInsert](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_35_searchInsert.java) | [数组]()、[二分查找]() | Easy | | +| #36 | [有效的数独](https://leetcode-cn.com/problems/valid-sudoku/) | [IsValidSudoku](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_36_isValidSudoku.java) | [哈希表]() | Medium | | +| #37 | [解数独](https://leetcode-cn.com/problems/sudoku-solver/) | [SolveSudoku](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_37_solveSudoku.java) | [哈希表]()、[回溯算法]() | Hard | | | #38 | [报数](https://leetcode-cn.com/problems/count-and-say/) | [CountAndSay](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_38_countAndSay.java) | [字符串]() | Easy | | | #40 | [组合总和 II](https://leetcode-cn.com/problems/combination-sum-ii/) | [CombinationSum2](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_40_combinationSum2.java) | [数组]()、[回溯算法]() | Medium | | | #42 | [接雨水](https://leetcode-cn.com/problems/trapping-rain-water/) | [Trap](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_42_trap.java) | [栈](https://leetcode-cn.com/tag/stack/)、[数组]()、[双指针]() | Hard | | From 74888a2929e03d1078ea408eb1fc4dc521a1b45f Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 20 May 2019 09:53:43 +0800 Subject: [PATCH 060/308] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0090520?= =?UTF-8?q?=E5=91=A8=E9=A2=98=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index c000eea..9b30ac8 100644 --- a/README.md +++ b/README.md @@ -11,15 +11,19 @@ - 欢迎star、fork、交流,一起互勉 - 微信号:pp_hdsny(备注leetcode) - 网址:https://leetcode-cn.com/ -## 20190513-20190519待解题目列表 +## 20190520-20190526待解题目列表 -开始一道道的刷题了,如有期望刷特定题目的,欢迎提issue。这周出去浪4天,所以只刷三道题目了 +回溯算法 -- [x] [36. 有效的数独-Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_36_isValidSudoku.java) -- [x] [37. 解数独-Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_37_solveSudoku.java) -- [x] [38. 报数-Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_38_countAndSay.java) +- [ ] [39. 组合总和 - Medium](https://leetcode-cn.com/problems/combination-sum/) -下周题目预告:回溯相关题解 +- [ ] [46. 全排列 - Medium](https://leetcode-cn.com/problems/permutations/) + +- [ ] [47. 全排列 II - Medium](https://leetcode-cn.com/problems/permutations-ii/) + +- [ ] [52. N皇后 II - Hard](https://leetcode-cn.com/problems/n-queens-ii/) + +- [ ] [77. 组合 - Medium](https://leetcode-cn.com/problems/combinations/) ## 已解题目 From 5c96c207c1ef723ffb4e3f187e2f64cb0313e58f Mon Sep 17 00:00:00 2001 From: wangpeng Date: Tue, 28 May 2019 10:27:59 +0800 Subject: [PATCH 061/308] feat(MEDIUM): add _39_combinationSum --- .../leetcode/_39_combinationSum.java | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_39_combinationSum.java diff --git a/src/pp/arithmetic/leetcode/_39_combinationSum.java b/src/pp/arithmetic/leetcode/_39_combinationSum.java new file mode 100644 index 0000000..75ee288 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_39_combinationSum.java @@ -0,0 +1,104 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Created by wangpeng on 2019-05-20. + * 39. 组合总和 + *

+ * 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 + *

+ * candidates 中的数字可以无限制重复被选取。 + *

+ * 说明: + *

+ * 所有数字(包括 target)都是正整数。 + * 解集不能包含重复的组合。 + * 示例 1: + *

+ * 输入: candidates = [2,3,6,7], target = 7, + * 所求解集为: + * [ + * [7], + * [2,2,3] + * ] + * 示例 2: + *

+ * 输入: candidates = [2,3,5], target = 8, + * 所求解集为: + * [ + * [2,2,2,2], + * [2,3,3], + * [3,5] + * ] + * + * @see combination-sum + */ +public class _39_combinationSum { + + public static void main(String[] args) { + _39_combinationSum combinationSum = new _39_combinationSum(); +// List> lists = combinationSum.combinationSum(new int[]{1,2}, 2); + List> lists = combinationSum.combinationSum(new int[]{2, 3, 5}, 8); + for (int i = 0; i < lists.size(); i++) { + Util.printList(lists.get(i)); + } + } + + /** + * 解题思路: + * 1.先对数组进行排序 + * 2.循环数组,从第0位开始取数,不断叠加直到(c[i]/target的除数) + * 3.如 == target,则保存下来 + * 4.如 > target,则--当前数的个数,循环步骤2 + * 5.如 < target,则取下一位 + * + * @param candidates + * @param target + * @return + */ + public List> combinationSum(int[] candidates, int target) { + List> retList = new ArrayList<>(); + //排序 + Arrays.sort(candidates); + //递归循环 + combinationSum(candidates, target, 0, retList, new ArrayList<>(), 0); + + return retList; + } + + private void combinationSum(int[] candidates, + int target, + int index, + List> retList, + List addList, + int addSum) { + if (index >= candidates.length) return; + int n = (target - addSum) / candidates[index]; + if (n == 0) return; + //全部添加到队列中 + for (int i = 0; i <= n; i++) { + addList.add(candidates[index]); + } + int nSum = (n+1) * candidates[index]; + for (int i = n; i >= 0; i--) { + //每次减-后,更新sum和list + nSum -= candidates[index]; + addList.remove(addList.size() - 1); + if (nSum + addSum == target) { + //等于,添加到队列中 + retList.add(new ArrayList<>(addList)); + } else if (nSum + addSum > target) { + //大于,--i + } else { + //小于,向后取数 + combinationSum(candidates, target, index + 1, retList, addList, addSum + nSum); + } + } + } +} From 62f693fb12e979eea0221011a3010c33f628a03d Mon Sep 17 00:00:00 2001 From: wangpeng Date: Tue, 28 May 2019 10:30:52 +0800 Subject: [PATCH 062/308] docs: add _39_combinationSum --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9b30ac8..01e0cc4 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成161道 +- leetcode练习,坚持每天一道,目前已完成162道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -11,11 +11,11 @@ - 欢迎star、fork、交流,一起互勉 - 微信号:pp_hdsny(备注leetcode) - 网址:https://leetcode-cn.com/ -## 20190520-20190526待解题目列表 +## 本周待解题目列表 回溯算法 -- [ ] [39. 组合总和 - Medium](https://leetcode-cn.com/problems/combination-sum/) +- [x] [39. 组合总和 - Medium](https://leetcode-cn.com/problems/combination-sum/) - [ ] [46. 全排列 - Medium](https://leetcode-cn.com/problems/permutations/) @@ -58,7 +58,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成161) +### 题目列表(更新中--已完成162) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -100,6 +100,7 @@ | #36 | [有效的数独](https://leetcode-cn.com/problems/valid-sudoku/) | [IsValidSudoku](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_36_isValidSudoku.java) | [哈希表]() | Medium | | | #37 | [解数独](https://leetcode-cn.com/problems/sudoku-solver/) | [SolveSudoku](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_37_solveSudoku.java) | [哈希表]()、[回溯算法]() | Hard | | | #38 | [报数](https://leetcode-cn.com/problems/count-and-say/) | [CountAndSay](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_38_countAndSay.java) | [字符串]() | Easy | | +| #39 | [组合总和](https://leetcode-cn.com/problems/combination-sum/) | [CombinationSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_39_combinationSum.java) | [数组]()、[回溯算法]() | Medium | | | #40 | [组合总和 II](https://leetcode-cn.com/problems/combination-sum-ii/) | [CombinationSum2](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_40_combinationSum2.java) | [数组]()、[回溯算法]() | Medium | | | #42 | [接雨水](https://leetcode-cn.com/problems/trapping-rain-water/) | [Trap](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_42_trap.java) | [栈](https://leetcode-cn.com/tag/stack/)、[数组]()、[双指针]() | Hard | | | #43 | [字符串相乘](https://leetcode-cn.com/problems/multiply-strings/) | [Multiply](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_43_multiply.java) | [数学]()、[字符串]() | Medium | | From f9a1d57e3ff424d1ae93324ff2d979e243023e53 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Wed, 29 May 2019 10:33:27 +0800 Subject: [PATCH 063/308] feat(MEDIUM): add _46_permute --- src/pp/arithmetic/leetcode/_46_permute.java | 81 +++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_46_permute.java diff --git a/src/pp/arithmetic/leetcode/_46_permute.java b/src/pp/arithmetic/leetcode/_46_permute.java new file mode 100644 index 0000000..0d5a95e --- /dev/null +++ b/src/pp/arithmetic/leetcode/_46_permute.java @@ -0,0 +1,81 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wangpeng on 2019-05-29. + * 46. 全排列 + *

+ * 给定一个没有重复数字的序列,返回其所有可能的全排列。 + *

+ * 示例: + *

+ * 输入: [1,2,3] + * 输出: + * [ + * [1,2,3], + * [1,3,2], + * [2,1,3], + * [2,3,1], + * [3,1,2], + * [3,2,1] + * ] + * + * @see permutations + */ +public class _46_permute { + public static void main(String[] args) { + _46_permute permute = new _46_permute(); + List> list = permute.permute(new int[]{1, 2, 3}); + for (int i = 0; i < list.size(); i++) { + Util.printList(list.get(i)); + } + } + + /** + * 解题思路(回溯算法): + * 根据题意,数组中的每一个数字,都可能出现在排列中的任何位置,所以一个个的去试着放 + * 1、将数组转换成一个list,再定义一个itemList保存遍历结果,retList保存返回结果 + * 2、循环list下标index,取index的数加入itemList,将其移除list + * 3、再将剩余的list重复第2步 + * 4、当itemList的大小==数组大小,添加到retList + * 5、回退第2步,将之前移除的数组添加到list中,并从itemList中移除 + * + * @param nums + * @return + */ + public List> permute(int[] nums) { + List> retList = new ArrayList<>(); + List numList = toList(nums); + dfs(numList, retList, new ArrayList<>(), nums.length); + return retList; + } + + private void dfs(List numList, + List> retList, + List itemList, + int n) { + if (itemList.size() == n) { + retList.add(new ArrayList<>(itemList)); + return; + } + for (int i = 0; i < numList.size(); i++) { + Integer item = numList.remove(i); + itemList.add(item); + dfs(numList, retList, itemList, n); + itemList.remove(item); + numList.add(i, item); + } + } + + private List toList(int[] nums) { + List retList = new ArrayList<>(); + for (int i = 0; i < nums.length; i++) { + retList.add(nums[i]); + } + return retList; + } +} From 12a17e998ac077cfe08cd50ddee8f4eda26d4e83 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Wed, 29 May 2019 10:37:20 +0800 Subject: [PATCH 064/308] docs: add _46_permute --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 01e0cc4..ca32acd 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成162道 +- leetcode练习,坚持每天一道,目前已完成163道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -17,7 +17,7 @@ - [x] [39. 组合总和 - Medium](https://leetcode-cn.com/problems/combination-sum/) -- [ ] [46. 全排列 - Medium](https://leetcode-cn.com/problems/permutations/) +- [x] [46. 全排列 - Medium](https://leetcode-cn.com/problems/permutations/) - [ ] [47. 全排列 II - Medium](https://leetcode-cn.com/problems/permutations-ii/) @@ -58,7 +58,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成162) +### 题目列表(更新中--已完成163) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -106,6 +106,7 @@ | #43 | [字符串相乘](https://leetcode-cn.com/problems/multiply-strings/) | [Multiply](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_43_multiply.java) | [数学]()、[字符串]() | Medium | | | #44 | [通配符匹配](https://leetcode-cn.com/problems/wildcard-matching/) | [IsMatch](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_44_isMatch.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[字符串]()、[动态规划]()、[回溯算法]() | Hard | | | #45 | [跳跃游戏 II](https://leetcode-cn.com/problems/jump-game-ii/) | [Jump](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_45_jump.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Hard | | +| #46 | [全排列](https://leetcode-cn.com/problems/permutations/) | [Permute](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_46_permute.java) | [回溯算法]() | Medium | | | #49 | [字母异位词分组](https://leetcode-cn.com/problems/group-anagrams/) | [GroupAnagrams](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_49_groupAnagrams.java) | [哈希表]()、[字符串]() | Medium | | | #51 | [N皇后](https://leetcode-cn.com/problems/n-queens/) | [SolveNQueens](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_51_solveNQueens_2.java) | [回溯算法]() | Hard | [自己原始解法](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_51_solveNQueens.java) | | #53 | [最大子序和](https://leetcode-cn.com/problems/maximum-subarray/) | [MaxSubArray.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_53_maxSubArray.java) | [数组]()、[分治算法]()、[动态规划]() | Easy | | From 1ec70eb4a012c3a8e834684c3b71c26c194239a0 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 30 May 2019 10:35:58 +0800 Subject: [PATCH 065/308] feat(MEDIUM): add _47_permuteUnique --- .../leetcode/_47_permuteUnique.java | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_47_permuteUnique.java diff --git a/src/pp/arithmetic/leetcode/_47_permuteUnique.java b/src/pp/arithmetic/leetcode/_47_permuteUnique.java new file mode 100644 index 0000000..2573db1 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_47_permuteUnique.java @@ -0,0 +1,84 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Created by wangpeng on 2019-05-30. + * 47. 全排列 II + *

+ * 给定一个可包含重复数字的序列,返回所有不重复的全排列。 + *

+ * 示例: + *

+ * 输入: [1,1,2] + * 输出: + * [ + * [1,1,2], + * [1,2,1], + * [2,1,1] + * ] + * + * @see permutations-ii + */ +public class _47_permuteUnique { + public static void main(String[] args) { + _47_permuteUnique permuteUnique = new _47_permuteUnique(); + List> lists = permuteUnique.permuteUnique(new int[]{1, 1, 2, 2}); + for (int i = 0; i < lists.size(); i++) { + Util.printList(lists.get(i)); + } + } + + /** + * 解题思路: + * 整体思路类似 {@link _46_permute},其中需要注意的一点是,重复数字再取的时候得跳过 + * 1.先对数组进行排序 + * 2.采用回溯算法进行取数,当即将取到的数和之前回退回来的数一致的时候,再向上一层回溯 + * + * @param nums + * @return + */ + public List> permuteUnique(int[] nums) { + List> retList = new ArrayList<>(); + Arrays.sort(nums); + List numList = toList(nums); + dfs(numList, retList, new ArrayList<>(), nums.length); + return retList; + } + + //递归回溯 + private void dfs(List numList, + List> retList, + List itemList, + int n) { + if (itemList.size() == n) { + retList.add(new ArrayList<>(itemList)); + return; + } + Integer preNum = null; + for (int i = 0; i < numList.size(); i++) { + if (preNum != null && preNum.equals(numList.get(i))) { + //重复数字,不重复取 + continue; + } + Integer item = numList.remove(i); + itemList.add(item); + dfs(numList, retList, itemList, n); + itemList.remove(itemList.size() - 1); + numList.add(i, item); + preNum = item; + } + } + + private List toList(int[] nums) { + List retList = new ArrayList<>(); + for (int i = 0; i < nums.length; i++) { + retList.add(nums[i]); + } + return retList; + } +} From 10ea01bb22bcba18d35c91e29e764d34c1060b21 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 30 May 2019 10:38:35 +0800 Subject: [PATCH 066/308] docs: add _47_permuteUnique --- README.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ca32acd..62b574c 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成163道 +- leetcode练习,坚持每天一道,目前已完成164道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -15,11 +15,11 @@ 回溯算法 -- [x] [39. 组合总和 - Medium](https://leetcode-cn.com/problems/combination-sum/) +- [x] [39. 组合总和 - Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_39_combinationSum.java) -- [x] [46. 全排列 - Medium](https://leetcode-cn.com/problems/permutations/) +- [x] [46. 全排列 - Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_46_permute.java) -- [ ] [47. 全排列 II - Medium](https://leetcode-cn.com/problems/permutations-ii/) +- [x] [47. 全排列 II - Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_47_permuteUnique.java) - [ ] [52. N皇后 II - Hard](https://leetcode-cn.com/problems/n-queens-ii/) @@ -58,7 +58,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成163) +### 题目列表(更新中--已完成164) + +[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -107,6 +109,7 @@ | #44 | [通配符匹配](https://leetcode-cn.com/problems/wildcard-matching/) | [IsMatch](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_44_isMatch.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[字符串]()、[动态规划]()、[回溯算法]() | Hard | | | #45 | [跳跃游戏 II](https://leetcode-cn.com/problems/jump-game-ii/) | [Jump](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_45_jump.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Hard | | | #46 | [全排列](https://leetcode-cn.com/problems/permutations/) | [Permute](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_46_permute.java) | [回溯算法]() | Medium | | +| #47 | [全排列 II](https://leetcode-cn.com/problems/permutations-ii/) | [PermuteUnique](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_47_permuteUnique.java) | [回溯算法]() | Medium | | | #49 | [字母异位词分组](https://leetcode-cn.com/problems/group-anagrams/) | [GroupAnagrams](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_49_groupAnagrams.java) | [哈希表]()、[字符串]() | Medium | | | #51 | [N皇后](https://leetcode-cn.com/problems/n-queens/) | [SolveNQueens](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_51_solveNQueens_2.java) | [回溯算法]() | Hard | [自己原始解法](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_51_solveNQueens.java) | | #53 | [最大子序和](https://leetcode-cn.com/problems/maximum-subarray/) | [MaxSubArray.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_53_maxSubArray.java) | [数组]()、[分治算法]()、[动态规划]() | Easy | | From 474fce2e09f38cce1d783b4444941ddeb3a29679 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Fri, 31 May 2019 10:49:25 +0800 Subject: [PATCH 067/308] feat(HARD): add _52_totalNQueens --- .../arithmetic/leetcode/_52_totalNQueens.java | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_52_totalNQueens.java diff --git a/src/pp/arithmetic/leetcode/_52_totalNQueens.java b/src/pp/arithmetic/leetcode/_52_totalNQueens.java new file mode 100644 index 0000000..aeaf857 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_52_totalNQueens.java @@ -0,0 +1,90 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-05-31. + * 52. N皇后 II + *

+ * n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。 + * + * + *

+ * 上图为 8 皇后问题的一种解法。 + *

+ * 给定一个整数 n,返回 n 皇后不同的解决方案的数量。 + *

+ * 示例: + *

+ * 输入: 4 + * 输出: 2 + * 解释: 4 皇后问题存在如下两个不同的解法。 + * [ + * [".Q..", // 解法 1 + * "...Q", + * "Q...", + * "..Q."], + *

+ * ["..Q.", // 解法 2 + * "Q...", + * "...Q", + * ".Q.."] + * ] + * + * @see n-queens-ii + */ +public class _52_totalNQueens { + public static void main(String[] args) { + _52_totalNQueens totalNQueens = new _52_totalNQueens(); + System.out.println(totalNQueens.totalNQueens(5)); + } + + //运算结果 + private int resultCount = 0; + + /** + * 解题思路(回溯算法): + * 1.创建一个大小为n的数组,保存摆放皇后的位置 + * 2.从第一位开始尝试,一直取到N,每一次摆放皇后都得判断是否满足条件 + * 3.如摆放过程中发现没有满足条件的位置,则回溯上一位并寻找下一个可放置的位置 + * 4.如n个皇后都正确摆放,则结果+1,回溯上一位寻找下一个可放置的位置 + * + * @param n + * @return + */ + public int totalNQueens(int n) { + int[] positions = new int[n]; + dfs(positions, 0, n); + return resultCount; + } + + private void dfs(int[] positions, int index, int n) { + if (index >= n) return; + for (int i = 0; i < n; i++) { + positions[index] = i; + if (isMatch(positions, index)) { + if (index == n - 1) { + resultCount++; + } else { + dfs(positions, index + 1, n); + } + } + } + } + + /** + * 是否满足N皇后的规则,横、竖、斜边不能放 + * + * @param positions + * @param index + * @return + */ + private boolean isMatch(int[] positions, int index) { + for (int i = 0; i < index; i++) { + //判断横向和斜向是否在一条线上即可,因为竖向用一位数组存储就避免了 + if (positions[i] == positions[index] || Math.abs(positions[i] - positions[index]) == index - i) { + return false; + } + } + return true; + } + +} From ebaf0a9be365079efa24e9ffd552f2c2a785bf10 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Fri, 31 May 2019 10:53:54 +0800 Subject: [PATCH 068/308] docs: add _52_totalNQueens --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 62b574c..e45c155 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成164道 +- leetcode练习,坚持每天一道,目前已完成165道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -21,7 +21,7 @@ - [x] [47. 全排列 II - Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_47_permuteUnique.java) -- [ ] [52. N皇后 II - Hard](https://leetcode-cn.com/problems/n-queens-ii/) +- [x] [52. N皇后 II - Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_52_totalNQueens.java) - [ ] [77. 组合 - Medium](https://leetcode-cn.com/problems/combinations/) @@ -58,7 +58,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成164) +### 题目列表(更新中--已完成165) [Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java) @@ -112,6 +112,7 @@ | #47 | [全排列 II](https://leetcode-cn.com/problems/permutations-ii/) | [PermuteUnique](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_47_permuteUnique.java) | [回溯算法]() | Medium | | | #49 | [字母异位词分组](https://leetcode-cn.com/problems/group-anagrams/) | [GroupAnagrams](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_49_groupAnagrams.java) | [哈希表]()、[字符串]() | Medium | | | #51 | [N皇后](https://leetcode-cn.com/problems/n-queens/) | [SolveNQueens](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_51_solveNQueens_2.java) | [回溯算法]() | Hard | [自己原始解法](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_51_solveNQueens.java) | +| #52 | [N皇后 II](https://leetcode-cn.com/problems/n-queens-ii/) | [TotalNQueens](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_52_totalNQueens.java) | [回溯算法]() | Hard | | | #53 | [最大子序和](https://leetcode-cn.com/problems/maximum-subarray/) | [MaxSubArray.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_53_maxSubArray.java) | [数组]()、[分治算法]()、[动态规划]() | Easy | | | #55 | [跳跃游戏](https://leetcode-cn.com/problems/jump-game/) | [CanJump](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_55_canJump.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Medium | | | #56 | [合并区间](https://leetcode-cn.com/problems/merge-intervals/) | [Merge](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_56_merge.java) | [排序](https://leetcode-cn.com/tag/sort/)、[数组]() | Medium | | From 0b14d5b8b110110e9c9c4b027c938f9b9f4cd0e3 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Sat, 1 Jun 2019 10:29:42 +0800 Subject: [PATCH 069/308] feat(MEDIUM): add _77_combine --- src/pp/arithmetic/leetcode/_77_combine.java | 83 +++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_77_combine.java diff --git a/src/pp/arithmetic/leetcode/_77_combine.java b/src/pp/arithmetic/leetcode/_77_combine.java new file mode 100644 index 0000000..61a5976 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_77_combine.java @@ -0,0 +1,83 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * Created by wangpeng on 2019-06-01. + * 77. 组合 + *

+ * 给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。 + *

+ * 示例: + *

+ * 输入: n = 4, k = 2 + * 输出: + * [ + * [2,4], + * [3,4], + * [2,3], + * [1,2], + * [1,3], + * [1,4], + * ] + * + * @see combinations + */ +public class _77_combine { + public static void main(String[] args) { + _77_combine combine = new _77_combine(); + List> lists = combine.combine(4, 2); + for (int i = 0; i < lists.size(); i++) { + Util.printList(lists.get(i)); + } + } + + /** + * 解题思路(回溯算法): + * 1.从list中开始取,一直取到k位 + * 2.取的数放在一个list中,方便增减 + * 3.取到k位后,回退到上一位,取没有取到的数字,直到全部取完 + *

+ * 注意不能重复[2,3]和[3,2]是一个组合,排序重复的办法:后面取的数必须比之前的大 + * 优化点:可以去除一些不必要的循环,如循环的终止条件不是<=n,而是<=n-k+index + * + * @param n + * @param k + * @return + */ + public List> combine(int n, int k) { + List> retList = new ArrayList<>(); + dfs(retList, new LinkedList<>(), 0, 1, n, k); + return retList; + } + + /** + * DFS遍历 + * @param retList 返回结果 + * @param itemList 取数集合 + * @param preNum 之前取的数 + * @param index 当前第几位 + * @param n n个数 + * @param k 取k位 + */ + private void dfs(List> retList, + List itemList, + int preNum, + int index, + int n, + int k) { + if (itemList.size() == k) { + retList.add(new LinkedList<>(itemList)); + return; + } + for (int i = preNum + 1; i <= n - k + index; i++) { + itemList.add(i); + dfs(retList, itemList, i, index + 1, n, k); + itemList.remove(itemList.size() - 1); + } + } +} From 22e18b099656f5187710f238705d6265a07a26bf Mon Sep 17 00:00:00 2001 From: wangpeng Date: Sat, 1 Jun 2019 10:38:44 +0800 Subject: [PATCH 070/308] docs: add _77_combine --- README.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index e45c155..d250b8a 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成165道 +- leetcode练习,坚持每天一道,目前已完成166道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -16,14 +16,12 @@ 回溯算法 - [x] [39. 组合总和 - Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_39_combinationSum.java) +- [x] [46. 全排列 - Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_46_permute.java) +- [x] [47. 全排列 II - Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_47_permuteUnique.java) +- [x] [52. N皇后 II - Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_52_totalNQueens.java) +- [x] [77. 组合 - Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_77_combine.java) -- [x] [46. 全排列 - Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_46_permute.java) - -- [x] [47. 全排列 II - Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_47_permuteUnique.java) - -- [x] [52. N皇后 II - Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_52_totalNQueens.java) - -- [ ] [77. 组合 - Medium](https://leetcode-cn.com/problems/combinations/) +后面开始扫题,从LeetCode后面题目开始 ## 已解题目 @@ -58,7 +56,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成165) +### 题目列表(更新中--已完成166) [Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java) @@ -126,6 +124,7 @@ | #71 | [简化路径](https://leetcode-cn.com/problems/simplify-path/) | [SimplifyPath](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_71_simplifyPath.java) | [栈](https://leetcode-cn.com/tag/stack/)、[字符串]() | Medium | | | #72 | [编辑距离](https://leetcode-cn.com/problems/edit-distance/) | [MinDistance](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_72_minDistance.java) | [字符串]()、[动态规划]() | Hard | | | #76 | [最小覆盖子串](https://leetcode-cn.com/problems/minimum-window-substring/) | [MinWindow](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_76_minWindow.java) | [哈希表]()、[双指针]()、[字符串]()、[sliding window]() | Hard | | +| #77 | [组合](https://leetcode-cn.com/problems/combinations/) | [Combine](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_77_combine.java) | [回溯算法]() | Medium | | | #78 | [子集](https://leetcode-cn.com/problems/subsets/) | [Subsets](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_78_subsets.java) | [位运算](https://leetcode-cn.com/tag/bit-manipulation/)、[数组]()、[回溯算法]() | Medium | | | #80 | [删除排序数组中的重复项 II](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array-ii/) | [RemoveDuplicates](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_80_removeDuplicates.java) | [数组]()、[双指针]() | Medium | | | #86 | [分隔链表](https://leetcode-cn.com/problems/partition-list/) | [Partition](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_86_Partition.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Medium | | From c8c3d41ad0d2190cdef17865ae6fcd92cc949fb0 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 3 Jun 2019 10:01:46 +0800 Subject: [PATCH 071/308] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E9=A2=98?= =?UTF-8?q?=E7=9B=AE=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d250b8a..0ead83f 100644 --- a/README.md +++ b/README.md @@ -13,15 +13,17 @@ - 网址:https://leetcode-cn.com/ ## 本周待解题目列表 -回溯算法 +开始扫题,从LeetCode后面题目开始 -- [x] [39. 组合总和 - Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_39_combinationSum.java) -- [x] [46. 全排列 - Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_46_permute.java) -- [x] [47. 全排列 II - Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_47_permuteUnique.java) -- [x] [52. N皇后 II - Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_52_totalNQueens.java) -- [x] [77. 组合 - Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_77_combine.java) +- [ ] [1049. 最后一块石头的重量 II -Medium](https://leetcode-cn.com/problems/last-stone-weight-ii/) -后面开始扫题,从LeetCode后面题目开始 +- [ ] [1051. 高度检查器 -Easy](https://leetcode-cn.com/problems/height-checker/) + +- [ ] [1052. 爱生气的书店老板 -Medium](https://leetcode-cn.com/problems/grumpy-bookstore-owner/) + +- [ ] [1053. 交换一次的先前排列 -Medium](https://leetcode-cn.com/problems/previous-permutation-with-one-swap/) + +- [ ] [1054. 距离相等的条形码 -Medium](https://leetcode-cn.com/problems/distant-barcodes/) ## 已解题目 From 7c32bfb255ef6230a9e9557143e351aff51c8c7d Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 3 Jun 2019 22:07:33 +0800 Subject: [PATCH 072/308] feat(MEDIUM): add _1049_lastStoneWeightII --- .../leetcode/_1049_lastStoneWeightII.java | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_1049_lastStoneWeightII.java diff --git a/src/pp/arithmetic/leetcode/_1049_lastStoneWeightII.java b/src/pp/arithmetic/leetcode/_1049_lastStoneWeightII.java new file mode 100644 index 0000000..b71bd21 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_1049_lastStoneWeightII.java @@ -0,0 +1,72 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-06-03. + * 1049. 最后一块石头的重量 II + *

+ * 有一堆石头,每块石头的重量都是正整数。 + *

+ * 每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下: + *

+ * 如果 x == y,那么两块石头都会被完全粉碎; + * 如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。 + * 最后,最多只会剩下一块石头。返回此石头最小的可能重量。如果没有石头剩下,就返回 0。 + *

+ *

+ *

+ * 示例: + *

+ * 输入:[2,7,4,1,8,1] + * 输出:1 + * 解释: + * 组合 2 和 4,得到 2,所以数组转化为 [2,7,1,8,1], + * 组合 7 和 8,得到 1,所以数组转化为 [2,1,1,1], + * 组合 2 和 1,得到 1,所以数组转化为 [1,1,1], + * 组合 1 和 1,得到 0,所以数组转化为 [1],这就是最优值。 + *

+ *

+ * 提示: + *

+ * 1 <= stones.length <= 30 + * 1 <= stones[i] <= 1000 + * + * @see last-stone-weight-ii + */ +public class _1049_lastStoneWeightII { + public static void main(String[] args) { + _1049_lastStoneWeightII lastStoneWeightII = new _1049_lastStoneWeightII(); +// System.out.println(lastStoneWeightII.lastStoneWeightII(new int[]{2, 7, 4, 8, 1, 1})); +// System.out.println(lastStoneWeightII.lastStoneWeightII(new int[]{6, 2, 2, 6, 5, 7, 7})); + System.out.println(lastStoneWeightII.lastStoneWeightII(new int[]{31, 26, 33, 21, 40})); + } + + /** + * 解题思路: + * 1.因为需要数组相减得到最少值,所以可以分成两个一样大小的数组 + * 2.往数组中尽可能装满,转换为背包问题 + * + * @param stones + * @return + */ + public int lastStoneWeightII(int[] stones) { + /* 由于石头拿走还能放回去,因此可以简单地把所有石头看作两堆 + * 假设总重量为 sum, 则问题转化为背包问题:如何使两堆石头总重量接近 sum / 2 + */ + int len = stones.length; + /* 获取石头总重量 */ + int sum = 0; + for (int i : stones) { + sum += i; + } + /* 定义 dp[i] 重量上限为 i 时背包所能装载的最大石头重量 */ + int maxCapacity = sum / 2; + int[] dp = new int[maxCapacity + 1]; + for (int i = 0; i < len; i++) { + int curStone = stones[i]; + for (int j = maxCapacity; j >= curStone; j--) { + dp[j] = Math.max(dp[j], dp[j - curStone] + curStone); + } + } + return sum - 2 * dp[maxCapacity]; + } +} From b6b5f5269c2c4acf25b350e6abd59f7c1c098bbe Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 3 Jun 2019 22:09:35 +0800 Subject: [PATCH 073/308] docs: add _1049_lastStoneWeightII --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0ead83f..31ba52e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成166道 +- leetcode练习,坚持每天一道,目前已完成167道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -15,7 +15,7 @@ 开始扫题,从LeetCode后面题目开始 -- [ ] [1049. 最后一块石头的重量 II -Medium](https://leetcode-cn.com/problems/last-stone-weight-ii/) +- [x] [1049. 最后一块石头的重量 II -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1049_lastStoneWeightII.java) - [ ] [1051. 高度检查器 -Easy](https://leetcode-cn.com/problems/height-checker/) @@ -58,7 +58,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成166) +### 题目列表(更新中--已完成167) [Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java) @@ -225,6 +225,7 @@ | #978 | [最长湍流子数组](https://leetcode-cn.com/problems/longest-turbulent-subarray/) | [MaxTurbulenceSize](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_978_maxTurbulenceSize.java) | [数组]()、[动态规划]()、[sliding window]() | Medium | | | #1004 | [最大连续1的个数 III](https://leetcode-cn.com/problems/max-consecutive-ones-iii/) | [LongestOnes](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1004_longestOnes.java) | [双指针]()、[sliding window]() | Medium | | | #1025 | [除数博弈](https://leetcode-cn.com/problems/divisor-game/) | [DivisorGame](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1025_divisorGame.java) | [数学]()、[动态规划]() | Easy | | +| #1049 | [最后一块石头的重量 II](https://leetcode-cn.com/problems/last-stone-weight-ii/) | [LastStoneWeightII]([Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1049_lastStoneWeightII.java)) | [动态规划]() | Medium | | From 52c0cac44554eb72133fb76d6137a14113ed4a7c Mon Sep 17 00:00:00 2001 From: wangpeng Date: Tue, 4 Jun 2019 11:06:32 +0800 Subject: [PATCH 074/308] feat(EASY): add _1046_lastStoneWeight --- .../leetcode/_1046_lastStoneWeight.java | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_1046_lastStoneWeight.java diff --git a/src/pp/arithmetic/leetcode/_1046_lastStoneWeight.java b/src/pp/arithmetic/leetcode/_1046_lastStoneWeight.java new file mode 100644 index 0000000..e4f4948 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_1046_lastStoneWeight.java @@ -0,0 +1,102 @@ +package pp.arithmetic.leetcode; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +/** + * Created by wangpeng on 2019-06-04. + * 1046. 最后一块石头的重量 + *

+ * 有一堆石头,每块石头的重量都是正整数。 + *

+ * 每一回合,从中选出两块最重的石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下: + *

+ * 如果 x == y,那么两块石头都会被完全粉碎; + * 如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。 + * 最后,最多只会剩下一块石头。返回此石头的重量。如果没有石头剩下,就返回 0。 + *

+ *

+ *

+ * 提示: + *

+ * 1 <= stones.length <= 30 + * 1 <= stones[i] <= 1000 + * + * @see last-stone-weight + */ +public class _1046_lastStoneWeight { + + public static void main(String[] args) { + _1046_lastStoneWeight lastStoneWeight = new _1046_lastStoneWeight(); + System.out.println(lastStoneWeight.lastStoneWeight(new int[]{4, 3, 4, 3, 2})); + System.out.println(lastStoneWeight.lastStoneWeight(new int[]{2, 7, 4, 1, 8, 1})); + System.out.println(lastStoneWeight.lastStoneWeight(new int[]{3, 7, 2})); + System.out.println(lastStoneWeight.lastStoneWeight(new int[]{3, 7, 8})); + } + + /** + * 解题思路: + * 1.先将数组转换成有序list + * 2.从list中取2个最大的数进行粉碎,得到结果>0则插入list,使其还有序 + * 3.重复步骤2直到剩余数<=1 + *

+ * 难点:如何构建有序数并对其进行插入排序 + * 1.先快排(O(nlogn)),顺序遍历插入(O(n)) ==>执行用时 : 5 ms, 在Last Stone Weight的Java提交中击败了43.43% 的用户 + * 2.先快排(O(nlogn)),二分插入排序(O(logn))==>执行用时 : 5 ms, 在Last Stone Weight的Java提交中击败了43.43% 的用户 + * 测试用例数据量并不是很大,两种解题耗时相差不大 + * + * @param stones + * @return + */ + public int lastStoneWeight(int[] stones) { + List stoneList = sort(stones); + while (stoneList.size() > 1) { + Integer s1 = stoneList.remove(stoneList.size() - 1); + Integer s2 = stoneList.remove(stoneList.size() - 1); + int ds = s1 - s2; + if (ds > 0) { + insert(stoneList, ds); + } + } + return stoneList.size() > 0 ? stoneList.get(0) : 0; + } + + private void insertBinary(List stoneList, int insert) { + int si = 0, ei = stoneList.size() - 1, mi = 0; + while (si <= ei) { + mi = (si + ei) / 2; + Integer mNum = stoneList.get(mi); + if (mNum == insert) { + stoneList.add(mi, insert); + return; + } else if (mNum < insert) { + si = mi + 1; + } else { + ei = mi - 1; + } + } + stoneList.add(si, insert); + } + + private void insert(List stoneList, int insert) { + int insertIndex = 0; + for (int i = 0; i < stoneList.size(); i++) { + if (stoneList.get(i) < insert) { + insertIndex = i + 1; + } else { + break; + } + } + stoneList.add(insertIndex, insert); + } + + private List sort(int[] stones) { + List retList = new LinkedList<>(); + Arrays.sort(stones); + for (int i = 0; i < stones.length; i++) { + retList.add(stones[i]); + } + return retList; + } +} From 1ded0b9af71dabd8b92b09ab3af024ec9081a390 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Tue, 4 Jun 2019 11:11:27 +0800 Subject: [PATCH 075/308] docs: add _1046_lastStoneWeight --- README.md | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 31ba52e..18de1e3 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成167道 +- leetcode练习,坚持每天一道,目前已完成168道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -15,14 +15,11 @@ 开始扫题,从LeetCode后面题目开始 -- [x] [1049. 最后一块石头的重量 II -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1049_lastStoneWeightII.java) - -- [ ] [1051. 高度检查器 -Easy](https://leetcode-cn.com/problems/height-checker/) - -- [ ] [1052. 爱生气的书店老板 -Medium](https://leetcode-cn.com/problems/grumpy-bookstore-owner/) - -- [ ] [1053. 交换一次的先前排列 -Medium](https://leetcode-cn.com/problems/previous-permutation-with-one-swap/) - +- [x] [1046. 最后一块石头的重量](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1046_lastStoneWeight.java) +- [x] [1049. 最后一块石头的重量 II -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1049_lastStoneWeightII.java) +- [ ] [1051. 高度检查器 -Easy](https://leetcode-cn.com/problems/height-checker/) +- [ ] [1052. 爱生气的书店老板 -Medium](https://leetcode-cn.com/problems/grumpy-bookstore-owner/) +- [ ] [1053. 交换一次的先前排列 -Medium](https://leetcode-cn.com/problems/previous-permutation-with-one-swap/) - [ ] [1054. 距离相等的条形码 -Medium](https://leetcode-cn.com/problems/distant-barcodes/) ## 已解题目 @@ -58,9 +55,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成167) +### 题目列表(更新中--已完成168) -[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java) +[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -225,6 +222,7 @@ | #978 | [最长湍流子数组](https://leetcode-cn.com/problems/longest-turbulent-subarray/) | [MaxTurbulenceSize](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_978_maxTurbulenceSize.java) | [数组]()、[动态规划]()、[sliding window]() | Medium | | | #1004 | [最大连续1的个数 III](https://leetcode-cn.com/problems/max-consecutive-ones-iii/) | [LongestOnes](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1004_longestOnes.java) | [双指针]()、[sliding window]() | Medium | | | #1025 | [除数博弈](https://leetcode-cn.com/problems/divisor-game/) | [DivisorGame](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1025_divisorGame.java) | [数学]()、[动态规划]() | Easy | | +| #1046 | [最后一块石头的重量](https://leetcode-cn.com/problems/last-stone-weight/) | [LastStoneWeight](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1046_lastStoneWeight.java) | [堆](https://leetcode-cn.com/tag/heap/)、[贪心算法](https://leetcode-cn.com/tag/greedy/) | Easy | | | #1049 | [最后一块石头的重量 II](https://leetcode-cn.com/problems/last-stone-weight-ii/) | [LastStoneWeightII]([Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1049_lastStoneWeightII.java)) | [动态规划]() | Medium | | From 71ebb728e618694052dcc13bf18a72f3aa04f653 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Wed, 5 Jun 2019 21:01:47 +0800 Subject: [PATCH 076/308] feat(EASY): add _1051_heightChecker --- .../leetcode/_1051_heightChecker.java | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_1051_heightChecker.java diff --git a/src/pp/arithmetic/leetcode/_1051_heightChecker.java b/src/pp/arithmetic/leetcode/_1051_heightChecker.java new file mode 100644 index 0000000..0e6a790 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_1051_heightChecker.java @@ -0,0 +1,53 @@ +package pp.arithmetic.leetcode; + +import java.util.Arrays; + +/** + * Created by wangpeng on 2019-06-05. + * 1051. 高度检查器 + *

+ * 学校在拍年度纪念照时,一般要求学生按照 非递减 的高度顺序排列。 + *

+ * 请你返回至少有多少个学生没有站在正确位置数量。该人数指的是:能让所有学生以 非递减 高度排列的必要移动人数。 + *

+ * 示例: + * 输入:[1,1,4,2,1,3] + * 输出:3 + * 解释: + * 高度为 4、3 和最后一个 1 的学生,没有站在正确的位置。 + *

+ * 1 <= heights.length <= 100 + * 1 <= heights[i] <= 100 + * + * @see height-checker + */ +public class _1051_heightChecker { + public static void main(String[] args) { + _1051_heightChecker heightChecker = new _1051_heightChecker(); + System.out.println(heightChecker.heightChecker(new int[]{1, 1, 4, 2, 1, 3})); + } + + /** + * 解题思路: + * 1.对数组进行排序 + * 2.循环遍历原始数组和排序数组,找到差异 + *

+ * 解题时间复杂度(O(nLogn+n)),不知道是否能提交通过,easy的题看来不能考虑太多 + * + * @param heights + * @return + */ + public int heightChecker(int[] heights) { + int[] sortHeights = new int[heights.length]; + System.arraycopy(heights, 0, sortHeights, 0, heights.length); + Arrays.sort(sortHeights); + int diffCount = 0; + for (int i = 0; i < heights.length; i++) { + if (heights[i] != sortHeights[i]) { + diffCount++; + } + } + + return diffCount; + } +} From d0f3e03e6b59366c37251d76bd84c8abd72a6945 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Wed, 5 Jun 2019 21:05:00 +0800 Subject: [PATCH 077/308] docs: add _1051_heightChecker --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 18de1e3..d9d075e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成168道 +- leetcode练习,坚持每天一道,目前已完成169道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -17,7 +17,7 @@ - [x] [1046. 最后一块石头的重量](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1046_lastStoneWeight.java) - [x] [1049. 最后一块石头的重量 II -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1049_lastStoneWeightII.java) -- [ ] [1051. 高度检查器 -Easy](https://leetcode-cn.com/problems/height-checker/) +- [x] [1051. 高度检查器 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1051_heightChecker.java) - [ ] [1052. 爱生气的书店老板 -Medium](https://leetcode-cn.com/problems/grumpy-bookstore-owner/) - [ ] [1053. 交换一次的先前排列 -Medium](https://leetcode-cn.com/problems/previous-permutation-with-one-swap/) - [ ] [1054. 距离相等的条形码 -Medium](https://leetcode-cn.com/problems/distant-barcodes/) @@ -55,7 +55,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成168) +### 题目列表(更新中--已完成169) [Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/) @@ -224,6 +224,7 @@ | #1025 | [除数博弈](https://leetcode-cn.com/problems/divisor-game/) | [DivisorGame](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1025_divisorGame.java) | [数学]()、[动态规划]() | Easy | | | #1046 | [最后一块石头的重量](https://leetcode-cn.com/problems/last-stone-weight/) | [LastStoneWeight](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1046_lastStoneWeight.java) | [堆](https://leetcode-cn.com/tag/heap/)、[贪心算法](https://leetcode-cn.com/tag/greedy/) | Easy | | | #1049 | [最后一块石头的重量 II](https://leetcode-cn.com/problems/last-stone-weight-ii/) | [LastStoneWeightII]([Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1049_lastStoneWeightII.java)) | [动态规划]() | Medium | | +| #1051 | [高度检查器](https://leetcode-cn.com/problems/height-checker/) | [HeightChecker](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1051_heightChecker.java) | [数组]() | Easy | | From aca08d8407fef4468f1e44a10c6091b48d76e20e Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 6 Jun 2019 19:36:12 +0800 Subject: [PATCH 078/308] feat(MEDIUM): add _1052_maxSatisfied --- .../leetcode/_1052_maxSatisfied.java | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_1052_maxSatisfied.java diff --git a/src/pp/arithmetic/leetcode/_1052_maxSatisfied.java b/src/pp/arithmetic/leetcode/_1052_maxSatisfied.java new file mode 100644 index 0000000..99c44c4 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_1052_maxSatisfied.java @@ -0,0 +1,76 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-06-06. + * 1052. 爱生气的书店老板 + *

+ * 今天,书店老板有一家店打算试营业 customers.length 分钟。每分钟都有一些顾客(customers[i])会进入书店,所有这些顾客都会在那一分钟结束后离开。 + *

+ * 在某些时候,书店老板会生气。 如果书店老板在第 i 分钟生气,那么 grumpy[i] = 1,否则 grumpy[i] = 0。 当书店老板生气时,那一分钟的顾客就会不满意,不生气则他们是满意的。 + *

+ * 书店老板知道一个秘密技巧,能抑制自己的情绪,可以让自己连续 X 分钟不生气,但却只能使用一次。 + *

+ * 请你返回这一天营业下来,最多有多少客户能够感到满意的数量。 + *

+ *

+ * 示例: + *

+ * 输入:customers = [1,0,1,2,1,1,7,5], grumpy = [0,1,0,1,0,1,0,1], X = 3 + * 输出:16 + * 解释: + * 书店老板在最后 3 分钟保持冷静。 + * 感到满意的最大客户数量 = 1 + 1 + 1 + 1 + 7 + 5 = 16. + *

+ *

+ * 提示: + *

+ * 1 <= X <= customers.length == grumpy.length <= 20000 + * 0 <= customers[i] <= 1000 + * 0 <= grumpy[i] <= 1 + * + * @see grumpy-bookstore-owner + */ +public class _1052_maxSatisfied { + public static void main(String[] args) { + _1052_maxSatisfied maxSatisfied = new _1052_maxSatisfied(); + System.out.println(maxSatisfied.maxSatisfied(new int[]{1, 0, 1, 2, 1, 1, 7, 5}, new int[]{0, 1, 0, 1, 0, 1, 0, 1}, 3)); + System.out.println(maxSatisfied.maxSatisfied(new int[]{1}, new int[]{0}, 1)); + System.out.println(maxSatisfied.maxSatisfied(new int[]{4, 10, 10}, new int[]{1, 1, 0}, 2)); + } + + /** + * 解题思路(动态规划+窗口): + * 1.定义两个数组dp和zoreDp + * 2.dp保存窗口长度为X的满意度,防止重复计算 + * 3.zoreDp保存不生气时候的满意总和数 + * 4.第I位的最大值为窗口值+窗口前后的zoreDp之和 + * + * @param customers + * @param grumpy + * @param X + * @return + */ + public int maxSatisfied(int[] customers, int[] grumpy, int X) { + //存储第I位维持X位的满意数,防止重复计算 + int[] dp = new int[customers.length + 1]; + //存储不生气的满意总和数 + int[] zoreDp = new int[customers.length + 1]; + //初始化 + int max = X > customers.length ? customers.length : X; + int sum = 0; + for (int i = 0; i < customers.length; i++) { + if (i < X) { + dp[i + 1] = sum += customers[i]; + } + zoreDp[i + 1] = (grumpy[i] == 0) ? customers[i] + zoreDp[i] : zoreDp[i]; + } + int retMax = dp[max] + zoreDp[customers.length] - zoreDp[max]; + for (int i = X; i < customers.length; i++) { + dp[i + 1] = dp[i] - customers[i - X] + customers[i]; + int otherZore = zoreDp[customers.length] - zoreDp[i + 1] + zoreDp[i - X + 1]; + retMax = Math.max(retMax, dp[i + 1] + otherZore); + } + + return retMax; + } +} From 7b2a99c9598dcecf1142705b371c3f81523f0bd3 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 6 Jun 2019 19:50:20 +0800 Subject: [PATCH 079/308] docs: add _1052_maxSatisfied --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d9d075e..f0a43f6 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成169道 +- leetcode练习,坚持每天一道,目前已完成170道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -18,7 +18,7 @@ - [x] [1046. 最后一块石头的重量](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1046_lastStoneWeight.java) - [x] [1049. 最后一块石头的重量 II -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1049_lastStoneWeightII.java) - [x] [1051. 高度检查器 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1051_heightChecker.java) -- [ ] [1052. 爱生气的书店老板 -Medium](https://leetcode-cn.com/problems/grumpy-bookstore-owner/) +- [x] [1052. 爱生气的书店老板 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1052_maxSatisfied.java) - [ ] [1053. 交换一次的先前排列 -Medium](https://leetcode-cn.com/problems/previous-permutation-with-one-swap/) - [ ] [1054. 距离相等的条形码 -Medium](https://leetcode-cn.com/problems/distant-barcodes/) @@ -55,7 +55,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成169) +### 题目列表(更新中--已完成170) [Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/) @@ -225,6 +225,7 @@ | #1046 | [最后一块石头的重量](https://leetcode-cn.com/problems/last-stone-weight/) | [LastStoneWeight](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1046_lastStoneWeight.java) | [堆](https://leetcode-cn.com/tag/heap/)、[贪心算法](https://leetcode-cn.com/tag/greedy/) | Easy | | | #1049 | [最后一块石头的重量 II](https://leetcode-cn.com/problems/last-stone-weight-ii/) | [LastStoneWeightII]([Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1049_lastStoneWeightII.java)) | [动态规划]() | Medium | | | #1051 | [高度检查器](https://leetcode-cn.com/problems/height-checker/) | [HeightChecker](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1051_heightChecker.java) | [数组]() | Easy | | +| #1052 | [爱生气的书店老板](https://leetcode-cn.com/problems/grumpy-bookstore-owner/) | [MaxSatisfied](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1052_maxSatisfied.java) | [数组]()、[sliding window]() | Medium | | From 4b5cc2c6748a8ccb0f127fec6e849aae9165041b Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 10 Jun 2019 10:21:44 +0800 Subject: [PATCH 080/308] feat(MEDIUM): add _1053_prevPermOpt1 --- .../leetcode/_1053_prevPermOpt1.java | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_1053_prevPermOpt1.java diff --git a/src/pp/arithmetic/leetcode/_1053_prevPermOpt1.java b/src/pp/arithmetic/leetcode/_1053_prevPermOpt1.java new file mode 100644 index 0000000..c2e6fb1 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_1053_prevPermOpt1.java @@ -0,0 +1,100 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +/** + * Created by wangpeng on 2019-06-06. + * 1053. 交换一次的先前排列 + *

+ * 给你一个正整数的数组 A(其中的元素不一定完全不同),请你返回可在 一次交换(交换两数字 A[i] 和 A[j] 的位置)后得到的、按字典序排列小于 A 的最大可能排列。 + *

+ * 如果无法这么操作,就请返回原数组。 + *

+ *

+ * 示例 1: + *

+ * 输入:[3,2,1] + * 输出:[3,1,2] + * 解释: + * 交换 2 和 1 + *

+ *

+ * 示例 2: + *

+ * 输入:[1,1,5] + * 输出:[1,1,5] + * 解释: + * 这已经是最小排列 + *

+ *

+ * 示例 3: + *

+ * 输入:[1,9,4,6,7] + * 输出:[1,7,4,6,9] + * 解释: + * 交换 9 和 7 + *

+ *

+ * 示例 4: + *

+ * 输入:[3,1,1,3] + * 输出:[1,3,1,3] + * 解释: + * 交换 1 和 3 + *

+ *

+ * 提示: + *

+ * 1 <= A.length <= 10000 + * 1 <= A[i] <= 10000 + * + * @see previous-permutation-with-one-swap + */ +public class _1053_prevPermOpt1 { + + public static void main(String[] args) { + _1053_prevPermOpt1 prevPermOpt1 = new _1053_prevPermOpt1(); + Util.printArray(prevPermOpt1.prevPermOpt1(new int[]{1, 9, 4, 6, 7})); + } + + /** + * 解题思路: + * 这道题目的关键是 按字典序排列小于 A 的最大可能排列, 那么有 + * + * 1.对当前序列进行逆序查找,找到第一个降序的位置i,使得A[i]>A[i+1]A[i]>A[i+1] + * 1.1>由于A[i]>A[i+1]A[i]>A[i+1],必能构造比当前字典序小的序列 + * 1.2>由于逆序查找,交换A[i]为最优解 + * 2.寻找在 A[i] 最左边且小于 A[i] 的最大的数字 A[j] + * 2.1>由于 A[j] < A[]i]A[j]由于 A[j] 是满足关系的最大的最左的,因此一定是满足小于关系的交换后字典序最大的 + * + * @param A + * @return + */ + public int[] prevPermOpt1(int[] A) { + int len = A.length; + int curMax = -1; + int index = -1; + boolean hasResult = false; + for (int i = len - 2; i >= 0; i--) { + if (A[i + 1] < A[i]) { // 此处逆序,需要移动A[i] + for (int j = i + 1; j < len; j++) { // 寻找与 A[i] 交换的位置 + if (A[i] > A[j]) { // 必须满足 A[i] > A[j],否则不能满足交换后的字典序小于原始字典序 + hasResult = true; + if (A[j] > curMax) { + curMax = A[j]; + index = j; + } + } + } + if (hasResult) { + int tmp = A[i]; + A[i] = A[index]; + A[index] = tmp; + return A; + } + } + } + return A; + } +} From a630e1f57fc658d48a8c89a8b9deb588f03b8e2b Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 10 Jun 2019 10:24:39 +0800 Subject: [PATCH 081/308] docs: add _1053_prevPermOpt1 --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f0a43f6..57d65ab 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成170道 +- leetcode练习,坚持每天一道,目前已完成171道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -19,7 +19,7 @@ - [x] [1049. 最后一块石头的重量 II -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1049_lastStoneWeightII.java) - [x] [1051. 高度检查器 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1051_heightChecker.java) - [x] [1052. 爱生气的书店老板 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1052_maxSatisfied.java) -- [ ] [1053. 交换一次的先前排列 -Medium](https://leetcode-cn.com/problems/previous-permutation-with-one-swap/) +- [x] [1053. 交换一次的先前排列 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1053_prevPermOpt1.java) - [ ] [1054. 距离相等的条形码 -Medium](https://leetcode-cn.com/problems/distant-barcodes/) ## 已解题目 @@ -55,7 +55,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成170) +### 题目列表(更新中--已完成171) [Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/) @@ -226,6 +226,7 @@ | #1049 | [最后一块石头的重量 II](https://leetcode-cn.com/problems/last-stone-weight-ii/) | [LastStoneWeightII]([Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1049_lastStoneWeightII.java)) | [动态规划]() | Medium | | | #1051 | [高度检查器](https://leetcode-cn.com/problems/height-checker/) | [HeightChecker](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1051_heightChecker.java) | [数组]() | Easy | | | #1052 | [爱生气的书店老板](https://leetcode-cn.com/problems/grumpy-bookstore-owner/) | [MaxSatisfied](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1052_maxSatisfied.java) | [数组]()、[sliding window]() | Medium | | +| #1053 | [交换一次的先前排列](https://leetcode-cn.com/problems/previous-permutation-with-one-swap/) | [PrevPermOpt1](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1053_prevPermOpt1.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Medium | | From 920003cdea91ca55708d2dcaea1e0e4142002a35 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Tue, 18 Jun 2019 11:40:03 +0800 Subject: [PATCH 082/308] feat(MEDIUM): add _1054_rearrangeBarcodes --- .../leetcode/_1054_rearrangeBarcodes.java | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_1054_rearrangeBarcodes.java diff --git a/src/pp/arithmetic/leetcode/_1054_rearrangeBarcodes.java b/src/pp/arithmetic/leetcode/_1054_rearrangeBarcodes.java new file mode 100644 index 0000000..4bf714a --- /dev/null +++ b/src/pp/arithmetic/leetcode/_1054_rearrangeBarcodes.java @@ -0,0 +1,112 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +/** + * Created by wangpeng on 2019-06-10. + * 1054. 距离相等的条形码 + *

+ * 在一个仓库里,有一排条形码,其中第 i 个条形码为 barcodes[i]。 + *

+ * 请你重新排列这些条形码,使其中两个相邻的条形码 不能 相等。 你可以返回任何满足该要求的答案,此题保证存在答案。 + *

+ *   + *

+ * 示例 1: + *

+ * 输入:[1,1,1,2,2,2] + * 输出:[2,1,2,1,2,1] + * 示例 2: + *

+ * 输入:[1,1,1,1,2,2,3,3] + * 输出:[1,3,1,3,2,1,2,1] + *   + *

+ * 提示: + *

+ * 1 <= barcodes.length <= 10000 + * 1 <= barcodes[i] <= 10000 + *

+ * + * @see distant-barcodes + */ +public class _1054_rearrangeBarcodes { + public static void main(String[] args) { + _1054_rearrangeBarcodes rearrangeBarcodes = new _1054_rearrangeBarcodes(); + Util.printArray(rearrangeBarcodes.rearrangeBarcodes(new int[]{1, 1, 1, 1, 2, 2, 3, 3})); + } + + /** + * 解题思路: + * 为了保证可以实现相邻一定不相等,可以依次交错排列同一个数字。 + *

+ * 首先统计每个数字的出现次数 + * 最特殊的情况为,数组的长度为奇数,某一个数字出现 (length+1)/2(length+1)/2 次, + * 如 [2, 1, 2, 1, 2],此时必须先从奇数位开始放置2,之后才能防止别的数组。 + *

+ * 首先从奇数位开始放置出现次数最多的数字。 + * 将其余数字放置在奇数位。 + * 将剩余数字依次放置在偶数位。 + * + * @param barcodes + * @return + */ + public int[] rearrangeBarcodes(int[] barcodes) { + /* 存在特殊情况结果类似 2, 1, 2, 1, 2 + * 因此优先使用出现次数最多的元素填充奇数位 + */ + /* 统计每个数据的出现次数 */ + int len = barcodes.length; + int[] count = new int[10001]; + for (int i = 0; i < len; i++) { + count[barcodes[i]]++; + } + /* 得到出现次数最多的数字 */ + int maxCnt = 0; + int maxNum = 0; + for (int i = 1; i < 10001; i++) { + if (count[i] > maxCnt) { + maxCnt = count[i]; + maxNum = i; + } + } + /* 先填充奇数位 */ + int[] result = new int[len]; + int pos = 0; // result 填充位置 + int idx = 0; // count 使用位置 + /* 先使用出现次数最多的数字填充奇数位, 最多恰好填满 */ + while (pos < len) { + if (count[maxNum] <= 0) { + break; // 填充完毕 + } else { + count[maxNum]--; + result[pos] = maxNum; + pos += 2; + } + } + /* 尝试继续填充奇数位 */ + while (pos < len) { + if (count[idx] <= 0) { + idx++; + continue; + } else { + count[idx]--; + result[pos] = idx; + pos += 2; + } + } + /* 继续填充偶数位 */ + pos = 1; + while (pos < len) { + if (count[idx] <= 0) { + idx++; + continue; + } else { + count[idx]--; + result[pos] = idx; + pos += 2; + } + } + return result; + } +} From 45c45d14454df745859175fb1750c3f3984a0aef Mon Sep 17 00:00:00 2001 From: wangpeng Date: Tue, 18 Jun 2019 11:46:54 +0800 Subject: [PATCH 083/308] docs: add _1054_rearrangeBarcodes --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 57d65ab..2cdb488 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成171道 +- leetcode练习,坚持每天一道,目前已完成172道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -20,7 +20,7 @@ - [x] [1051. 高度检查器 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1051_heightChecker.java) - [x] [1052. 爱生气的书店老板 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1052_maxSatisfied.java) - [x] [1053. 交换一次的先前排列 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1053_prevPermOpt1.java) -- [ ] [1054. 距离相等的条形码 -Medium](https://leetcode-cn.com/problems/distant-barcodes/) +- [x] [1054. 距离相等的条形码 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1054_rearrangeBarcodes.java) ## 已解题目 @@ -55,7 +55,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成171) +### 题目列表(更新中--已完成172) [Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/) @@ -226,7 +226,8 @@ | #1049 | [最后一块石头的重量 II](https://leetcode-cn.com/problems/last-stone-weight-ii/) | [LastStoneWeightII]([Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1049_lastStoneWeightII.java)) | [动态规划]() | Medium | | | #1051 | [高度检查器](https://leetcode-cn.com/problems/height-checker/) | [HeightChecker](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1051_heightChecker.java) | [数组]() | Easy | | | #1052 | [爱生气的书店老板](https://leetcode-cn.com/problems/grumpy-bookstore-owner/) | [MaxSatisfied](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1052_maxSatisfied.java) | [数组]()、[sliding window]() | Medium | | -| #1053 | [交换一次的先前排列](https://leetcode-cn.com/problems/previous-permutation-with-one-swap/) | [PrevPermOpt1](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1053_prevPermOpt1.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Medium | | +| #1053 | [交换一次的先前排列](https://leetcode-cn.com/problems/previous-permutation-with-one-swap/) | [PrevPermOpt](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1053_prevPermOpt1.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Medium | | +| #1054 | [距离相等的条形码](https://leetcode-cn.com/problems/distant-barcodes/) | [RearrangeBarcodes](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1054_rearrangeBarcodes.java) | [堆](https://leetcode-cn.com/tag/heap/)、[排序](https://leetcode-cn.com/tag/sort/) | Medium | | From 534a22d29c2ac57cb2347ba54bf453a7ec4c75da Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 20 Jun 2019 15:44:25 +0800 Subject: [PATCH 084/308] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E9=A2=98?= =?UTF-8?q?=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 2cdb488..cb60179 100644 --- a/README.md +++ b/README.md @@ -13,14 +13,21 @@ - 网址:https://leetcode-cn.com/ ## 本周待解题目列表 -开始扫题,从LeetCode后面题目开始 - -- [x] [1046. 最后一块石头的重量](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1046_lastStoneWeight.java) -- [x] [1049. 最后一块石头的重量 II -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1049_lastStoneWeightII.java) -- [x] [1051. 高度检查器 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1051_heightChecker.java) -- [x] [1052. 爱生气的书店老板 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1052_maxSatisfied.java) -- [x] [1053. 交换一次的先前排列 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1053_prevPermOpt1.java) -- [x] [1054. 距离相等的条形码 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1054_rearrangeBarcodes.java) +开始扫题 + +- [ ] [41. 缺失的第一个正数 -Hard](https://leetcode-cn.com/problems/first-missing-positive/) + +- [ ] [48. 旋转图像 -Medium](https://leetcode-cn.com/problems/rotate-image/) + +- [ ] [50. Pow(x, n) -Medium](https://leetcode-cn.com/problems/powx-n/) + +- [ ] [54. 螺旋矩阵 -Medium](https://leetcode-cn.com/problems/spiral-matrix/) + +- [ ] [57. 插入区间 -Hard](https://leetcode-cn.com/problems/insert-interval/) + +- [ ] [58. 最后一个单词的长度 -Easy](https://leetcode-cn.com/problems/length-of-last-word/) + +- [ ] [59. 螺旋矩阵 II -Medium](https://leetcode-cn.com/problems/spiral-matrix-ii/) ## 已解题目 From bf4ca44f065157ce31ef168745813731fb47b546 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 20 Jun 2019 20:08:28 +0800 Subject: [PATCH 085/308] feat(MEDIUM): add _41_firstMissingPositive --- .../leetcode/_41_firstMissingPositive.java | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_41_firstMissingPositive.java diff --git a/src/pp/arithmetic/leetcode/_41_firstMissingPositive.java b/src/pp/arithmetic/leetcode/_41_firstMissingPositive.java new file mode 100644 index 0000000..a93c782 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_41_firstMissingPositive.java @@ -0,0 +1,107 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-06-20. + * 41. 缺失的第一个正数 + *

+ * 给定一个未排序的整数数组,找出其中没有出现的最小的正整数。 + *

+ * 示例 1: + *

+ * 输入: [1,2,0] + * 输出: 3 + * 示例 2: + *

+ * 输入: [3,4,-1,1] + * 输出: 2 + * 示例 3: + *

+ * 输入: [7,8,9,11,12] + * 输出: 1 + * 说明: + *

+ * 你的算法的时间复杂度应为O(n),并且只能使用常数级别的空间。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/first-missing-positive + */ +public class _41_firstMissingPositive { + public static void main(String[] args) { + _41_firstMissingPositive firstMissingPositive = new _41_firstMissingPositive(); + System.out.println(firstMissingPositive.firstMissingPositive(new int[]{3, 4, -1, 1})); + } + + /** + * 解题思路: + * 题目要求算法时间复杂度在O(n),也就是说不能排序(排序最好的平均复杂度也在O(nLogn)) + * O(n)的复杂度只允许一次循环或者常数级的循环,并且只能使用常数级别的空间==>题目的难点 + *

+ * 官方的解法: + * 1、检查 1 是否存在于数组中。如果没有,则已经完成,1 即为答案。 + * 2、如果 nums = [1],答案即为 2 。 + * 3、将负数,零,和大于 n 的数替换为 1 。 + * 4、遍历数组。当读到数字 a 时,替换第 a 个元素的符号。 注意重复元素:只能改变一次符号。由于没有下标 n ,使用下标 0 的元素保存是否存在数字 n。 + * 5、再次遍历数组。返回第一个正数元素的下标。 + * 6、如果 nums[0] > 0,则返回 n 。 + * 7、如果之前的步骤中没有发现 nums 中有正数元素,则返回n + 1。 + * 详细说明:https://leetcode-cn.com/problems/first-missing-positive/solution/que-shi-de-di-yi-ge-zheng-shu-by-leetcode/ + *

+ * 时间复杂度: O(N) 由于所有的操作一共只会遍历长度为 N 的数组 4 次。 + * 空间复杂度: O(1) 由于只使用了常数的空间,原地遍历 + * + * @param nums + * @return + */ + public int firstMissingPositive(int[] nums) { + int n = nums.length; + + // 基本情况 + int contains = 0; + for (int i = 0; i < n; i++) + if (nums[i] == 1) { + contains++; + break; + } + + //不存在1,则最小正整数就是1 + if (contains == 0) + return 1; + + // nums = [1] + if (n == 1) + return 2; + + // 用 1 替换负数,0, + // 和大于 n 的数 + // 在转换以后,nums 只会包含 + // 正数 + for (int i = 0; i < n; i++) + if ((nums[i] <= 0) || (nums[i] > n)) + nums[i] = 1; + + // 使用索引和数字符号作为检查器 + // 例如,如果 nums[1] 是负数表示在数组中出现了数字 `1` + // 如果 nums[2] 是正数 表示数字 2 没有出现 + for (int i = 0; i < n; i++) { + int a = Math.abs(nums[i]); + // 如果发现了一个数字 a - 改变第 a 个元素的符号 + // 注意重复元素只需操作一次 + if (a == n) + nums[0] = -Math.abs(nums[0]); + else + nums[a] = -Math.abs(nums[a]); + } + + // 现在第一个正数的下标 + // 就是第一个缺失的数 + for (int i = 1; i < n; i++) { + if (nums[i] > 0) + return i; + } + + if (nums[0] > 0) + return n; + + return n + 1; + } +} From 9e9a5c1302962fe5aefdb553ff65ba8a92edd2bb Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 20 Jun 2019 20:10:44 +0800 Subject: [PATCH 086/308] docs: add _41_firstMissingPositive --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cb60179..c3e3255 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成172道 +- leetcode练习,坚持每天一道,目前已完成173道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -15,7 +15,7 @@ 开始扫题 -- [ ] [41. 缺失的第一个正数 -Hard](https://leetcode-cn.com/problems/first-missing-positive/) +- [x] [41. 缺失的第一个正数 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_41_firstMissingPositive.java) - [ ] [48. 旋转图像 -Medium](https://leetcode-cn.com/problems/rotate-image/) @@ -62,7 +62,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成172) +### 题目列表(更新中--已完成173) [Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/) @@ -108,6 +108,7 @@ | #38 | [报数](https://leetcode-cn.com/problems/count-and-say/) | [CountAndSay](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_38_countAndSay.java) | [字符串]() | Easy | | | #39 | [组合总和](https://leetcode-cn.com/problems/combination-sum/) | [CombinationSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_39_combinationSum.java) | [数组]()、[回溯算法]() | Medium | | | #40 | [组合总和 II](https://leetcode-cn.com/problems/combination-sum-ii/) | [CombinationSum2](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_40_combinationSum2.java) | [数组]()、[回溯算法]() | Medium | | +| #41 | [缺失的第一个正数](https://leetcode-cn.com/problems/first-missing-positive/) | [FirstMissingPositive](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_41_firstMissingPositive.java) | [数组]() | Medium | | | #42 | [接雨水](https://leetcode-cn.com/problems/trapping-rain-water/) | [Trap](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_42_trap.java) | [栈](https://leetcode-cn.com/tag/stack/)、[数组]()、[双指针]() | Hard | | | #43 | [字符串相乘](https://leetcode-cn.com/problems/multiply-strings/) | [Multiply](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_43_multiply.java) | [数学]()、[字符串]() | Medium | | | #44 | [通配符匹配](https://leetcode-cn.com/problems/wildcard-matching/) | [IsMatch](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_44_isMatch.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[字符串]()、[动态规划]()、[回溯算法]() | Hard | | From 9e8eab9224b96127b28110018555cd895d2de476 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Fri, 21 Jun 2019 13:12:00 +0800 Subject: [PATCH 087/308] feat(MEDIUM): add _48_rotate --- src/pp/arithmetic/leetcode/_48_rotate.java | 113 +++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_48_rotate.java diff --git a/src/pp/arithmetic/leetcode/_48_rotate.java b/src/pp/arithmetic/leetcode/_48_rotate.java new file mode 100644 index 0000000..8edccad --- /dev/null +++ b/src/pp/arithmetic/leetcode/_48_rotate.java @@ -0,0 +1,113 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +/** + * Created by wangpeng on 2019-06-21. + * 48. 旋转图像 + *

+ * 给定一个 n × n 的二维矩阵表示一个图像。 + *

+ * 将图像顺时针旋转 90 度。 + *

+ * 说明: + *

+ * 你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。 + *

+ * 示例 1: + *

+ * 给定 matrix = + * [ + * [1,2,3], + * [4,5,6], + * [7,8,9] + * ], + *

+ * 原地旋转输入矩阵,使其变为: + * [ + * [7,4,1], + * [8,5,2], + * [9,6,3] + * ] + * 示例 2: + *

+ * 给定 matrix = + * [ + * [ 5, 1, 9,11], + * [ 2, 4, 8,10], + * [13, 3, 6, 7], + * [15,14,12,16] + * ], + *

+ * 原地旋转输入矩阵,使其变为: + * [ + * [15,13, 2, 5], + * [14, 3, 4, 1], + * [12, 6, 8, 9], + * [16, 7,10,11] + * ] + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/rotate-image + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _48_rotate { + + public static void main(String[] args) { + _48_rotate rotate = new _48_rotate(); + int[][] arrs = { + {5, 1, 9, 11}, + {2, 4, 8, 10}, + {13, 3, 6, 7}, + {15, 14, 12, 16} + }; + rotate.rotate(arrs); + for (int i = 0; i < arrs.length; i++) { + Util.printArray(arrs[i]); + } + } + + /** + * 解题思路: + * 因为需要原地旋转(不借助另一个矩阵),可以考虑借助一个临时的存储位,接受被旋转位的数据 + * 考虑:如何找到旋转规律?==>纸上比划比划 + * 发现旋转规律:下一位的行等于上一位的列,下一位的列=n-上一位的行-1(-1是从0开始) + * 代码实现:先从外部循环,结束后再逐步向内走,直到循环结束 + *

+ * 需要注意:循环结束条件 + * + * @param matrix + */ + public void rotate(int[][] matrix) { + int n = matrix.length; + if (n == 1) return; + int hn = n % 2 == 0 ? n / 2 : (n / 2 + 1);//一半取偶数的一半,奇数一半+1 + int rowI = 0, colI = 0; + int nrowI, ncolI, tempI;//循环的下标 + int temp, preTemp; + while (colI < n - 1 && rowI < n - 1) { + nrowI = rowI; + ncolI = colI; + preTemp = matrix[nrowI][ncolI]; + //旋转遍历四次 + for (int i = 0; i < 4; i++) { + //取旋转的位置 + tempI = nrowI; + nrowI = ncolI; + ncolI = n - 1 - tempI; + temp = matrix[nrowI][ncolI]; + matrix[nrowI][ncolI] = preTemp; + preTemp = temp; + } + //取下一位循环位置 + colI++; + if (colI - rowI > n - rowI * 2 - 2) { //每次向内缩一圈,少两位 + rowI++; + colI = rowI; + if (rowI >= hn) { + break; + } + } + } + } +} From 2f4303d71f60e51c59329aa894dc6bddf3f7b56c Mon Sep 17 00:00:00 2001 From: wangpeng Date: Fri, 21 Jun 2019 13:17:46 +0800 Subject: [PATCH 088/308] docs: add _48_rotate --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c3e3255..42d4dcc 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成173道 +- leetcode练习,坚持每天一道,目前已完成174道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -17,7 +17,7 @@ - [x] [41. 缺失的第一个正数 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_41_firstMissingPositive.java) -- [ ] [48. 旋转图像 -Medium](https://leetcode-cn.com/problems/rotate-image/) +- [x] [48. 旋转图像 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_48_rotate.java) - [ ] [50. Pow(x, n) -Medium](https://leetcode-cn.com/problems/powx-n/) @@ -62,7 +62,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成173) +### 题目列表(更新中--已完成174) [Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/) @@ -115,6 +115,7 @@ | #45 | [跳跃游戏 II](https://leetcode-cn.com/problems/jump-game-ii/) | [Jump](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_45_jump.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Hard | | | #46 | [全排列](https://leetcode-cn.com/problems/permutations/) | [Permute](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_46_permute.java) | [回溯算法]() | Medium | | | #47 | [全排列 II](https://leetcode-cn.com/problems/permutations-ii/) | [PermuteUnique](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_47_permuteUnique.java) | [回溯算法]() | Medium | | +| #48 | [旋转图像](https://leetcode-cn.com/problems/rotate-image/) | [Rotate](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_48_rotate.java) | [数组]() | Medium | | | #49 | [字母异位词分组](https://leetcode-cn.com/problems/group-anagrams/) | [GroupAnagrams](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_49_groupAnagrams.java) | [哈希表]()、[字符串]() | Medium | | | #51 | [N皇后](https://leetcode-cn.com/problems/n-queens/) | [SolveNQueens](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_51_solveNQueens_2.java) | [回溯算法]() | Hard | [自己原始解法](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_51_solveNQueens.java) | | #52 | [N皇后 II](https://leetcode-cn.com/problems/n-queens-ii/) | [TotalNQueens](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_52_totalNQueens.java) | [回溯算法]() | Hard | | From 6691ac009a0b97f740e0ca61bcaea498f06dc818 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Sat, 22 Jun 2019 11:09:06 +0800 Subject: [PATCH 089/308] feat(MEDIUM): add _50_myPow --- src/pp/arithmetic/leetcode/_50_myPow.java | 76 +++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_50_myPow.java diff --git a/src/pp/arithmetic/leetcode/_50_myPow.java b/src/pp/arithmetic/leetcode/_50_myPow.java new file mode 100644 index 0000000..c180cbf --- /dev/null +++ b/src/pp/arithmetic/leetcode/_50_myPow.java @@ -0,0 +1,76 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-06-22. + * 50. Pow(x, n) + *

+ * 实现 pow(x, n) ,即计算 x 的 n 次幂函数。 + *

+ * 示例 1: + *

+ * 输入: 2.00000, 10 + * 输出: 1024.00000 + * 示例 2: + *

+ * 输入: 2.10000, 3 + * 输出: 9.26100 + * 示例 3: + *

+ * 输入: 2.00000, -2 + * 输出: 0.25000 + * 解释: 2-2 = 1/22 = 1/4 = 0.25 + * 说明: + *

+ * -100.0 < x < 100.0 + * n 是 32 位有符号整数,其数值范围是 [−2^31, 2^31 − 1] 。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/powx-n + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _50_myPow { + + public static void main(String[] args) { + _50_myPow pow = new _50_myPow(); + System.out.println(pow.myPow(2.1, 3)); + System.out.println(pow.myPow(2, -2)); + System.out.println(pow.myPow(0.3, -2)); + System.out.println(pow.myPow(0.3, 1)); + System.out.println(pow.myPow(0.4127, 0)); + System.out.println(pow.myPow(0.00001, 2147483647)); + } + + /** + * 解析思路: + * 平方不就是n个数相乘么,n为负数的时候,先将x求倒数,再n次相乘(此方法会提交超时O(n)) + *

+ * 优化: + * 将上述循环相乘的方法根据分治思想,一分为二(只需要求一半即可,另一半是相同的,奇数再*x),不断拆分至两个数相乘,时间复杂度优化到O(LogN) + * 这个方法称为"快速幂等法" + * + * @param x + * @param n + * @return + */ + public double myPow(double x, int n) { + if (n < 0) { + x = 1f / x; + } + n = Math.abs(n); + //分治求解 + return fastPow(x, n); + } + + double fastPow(double x, long n) { + if (n == 0) { + return 1.0; + } + double half = fastPow(x, n / 2); + if (n % 2 == 0) { + return half * half; + } else { + return half * half * x; + } + } + +} From 23f43a45f260d7ef854f9b07cd63dd6ad293991d Mon Sep 17 00:00:00 2001 From: wangpeng Date: Sat, 22 Jun 2019 11:12:37 +0800 Subject: [PATCH 090/308] docs: add _50_myPow --- README.md | 9 +++++---- src/pp/arithmetic/leetcode/_50_myPow.java | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 42d4dcc..eb1ac9f 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成174道 +- leetcode练习,坚持每天一道,目前已完成175道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -19,7 +19,7 @@ - [x] [48. 旋转图像 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_48_rotate.java) -- [ ] [50. Pow(x, n) -Medium](https://leetcode-cn.com/problems/powx-n/) +- [x] [50. Pow(x, n) -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_50_myPow.java) - [ ] [54. 螺旋矩阵 -Medium](https://leetcode-cn.com/problems/spiral-matrix/) @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成174) +### 题目列表(更新中--已完成175) -[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/) +​ | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -117,6 +117,7 @@ | #47 | [全排列 II](https://leetcode-cn.com/problems/permutations-ii/) | [PermuteUnique](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_47_permuteUnique.java) | [回溯算法]() | Medium | | | #48 | [旋转图像](https://leetcode-cn.com/problems/rotate-image/) | [Rotate](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_48_rotate.java) | [数组]() | Medium | | | #49 | [字母异位词分组](https://leetcode-cn.com/problems/group-anagrams/) | [GroupAnagrams](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_49_groupAnagrams.java) | [哈希表]()、[字符串]() | Medium | | +| #50 | | [MyPow](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_50_myPow.java) | | | | | #51 | [N皇后](https://leetcode-cn.com/problems/n-queens/) | [SolveNQueens](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_51_solveNQueens_2.java) | [回溯算法]() | Hard | [自己原始解法](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_51_solveNQueens.java) | | #52 | [N皇后 II](https://leetcode-cn.com/problems/n-queens-ii/) | [TotalNQueens](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_52_totalNQueens.java) | [回溯算法]() | Hard | | | #53 | [最大子序和](https://leetcode-cn.com/problems/maximum-subarray/) | [MaxSubArray.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_53_maxSubArray.java) | [数组]()、[分治算法]()、[动态规划]() | Easy | | diff --git a/src/pp/arithmetic/leetcode/_50_myPow.java b/src/pp/arithmetic/leetcode/_50_myPow.java index c180cbf..9e3e0b5 100644 --- a/src/pp/arithmetic/leetcode/_50_myPow.java +++ b/src/pp/arithmetic/leetcode/_50_myPow.java @@ -46,7 +46,7 @@ public static void main(String[] args) { *

* 优化: * 将上述循环相乘的方法根据分治思想,一分为二(只需要求一半即可,另一半是相同的,奇数再*x),不断拆分至两个数相乘,时间复杂度优化到O(LogN) - * 这个方法称为"快速幂等法" + * 这个方法称为"快速幂乘法" * * @param x * @param n From 35178dc48473095ec7fa561e6997c5d650528d0d Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 24 Jun 2019 13:16:27 +0800 Subject: [PATCH 091/308] feat(MEDIUM): add _54_spiralOrder --- .../arithmetic/leetcode/_54_spiralOrder.java | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_54_spiralOrder.java diff --git a/src/pp/arithmetic/leetcode/_54_spiralOrder.java b/src/pp/arithmetic/leetcode/_54_spiralOrder.java new file mode 100644 index 0000000..996d73a --- /dev/null +++ b/src/pp/arithmetic/leetcode/_54_spiralOrder.java @@ -0,0 +1,88 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Created by wangpeng on 2019-06-24. + * 54. 螺旋矩阵 + *

+ * 给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。 + *

+ * 示例 1: + *

+ * 输入: + * [ + * [ 1, 2, 3 ], + * [ 4, 5, 6 ], + * [ 7, 8, 9 ] + * ] + * 输出: [1,2,3,6,9,8,7,4,5] + * 示例 2: + *

+ * 输入: + * [ + * [1, 2, 3, 4], + * [5, 6, 7, 8], + * [9,10,11,12] + * ] + * 输出: [1,2,3,4,8,12,11,10,9,5,6,7] + *

+ *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/spiral-matrix + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _54_spiralOrder { + + public static void main(String[] args) { + _54_spiralOrder spiralOrder = new _54_spiralOrder(); + Util.printList(spiralOrder.spiralOrder(new int[][]{ + {1, 2, 3, 4}, + {5, 6, 7, 8}, + {9, 10, 11, 12}, + {13, 14, 15, 16}, + {17, 18, 19, 20}, + })); + Util.printList(spiralOrder.spiralOrder(new int[][]{ + {1, 2, 3}, + {4, 5, 6}, + {7, 8, 9} + })); + Util.printList(spiralOrder.spiralOrder(new int[][]{ + {1, 2, 3} + })); + } + + /** + * 一眼看过去,遍历很简单,如何转换成代码上的遍历逻辑,最好就是遍历一遍就把结果得到 + * 解题思路: + * 通过四层循环按条件遍历结果 + * + * @param matrix + * @return + */ + public List spiralOrder(int[][] matrix) { + List ans = new ArrayList(); + if (matrix.length == 0) + return ans; + int r1 = 0, r2 = matrix.length - 1; + int c1 = 0, c2 = matrix[0].length - 1; + while (r1 <= r2 && c1 <= c2) { + for (int c = c1; c <= c2; c++) ans.add(matrix[r1][c]); + for (int r = r1 + 1; r <= r2; r++) ans.add(matrix[r][c2]); + if (r1 < r2 && c1 < c2) { + for (int c = c2 - 1; c > c1; c--) ans.add(matrix[r2][c]); + for (int r = r2; r > r1; r--) ans.add(matrix[r][c1]); + } + r1++; + r2--; + c1++; + c2--; + } + return ans; + } +} From 7ac8d6d1194a407d0c21753d58138cb6a94f59a2 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Mon, 24 Jun 2019 13:19:40 +0800 Subject: [PATCH 092/308] docs: add _54_spiralOrder --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index eb1ac9f..0e2b877 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成175道 +- leetcode练习,坚持每天一道,目前已完成176道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -21,7 +21,7 @@ - [x] [50. Pow(x, n) -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_50_myPow.java) -- [ ] [54. 螺旋矩阵 -Medium](https://leetcode-cn.com/problems/spiral-matrix/) +- [x] [54. 螺旋矩阵 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_54_spiralOrder.java) - [ ] [57. 插入区间 -Hard](https://leetcode-cn.com/problems/insert-interval/) @@ -64,7 +64,7 @@ ### 题目列表(更新中--已完成175) -​ +​ [数组]() Medium | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -121,6 +121,7 @@ | #51 | [N皇后](https://leetcode-cn.com/problems/n-queens/) | [SolveNQueens](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_51_solveNQueens_2.java) | [回溯算法]() | Hard | [自己原始解法](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_51_solveNQueens.java) | | #52 | [N皇后 II](https://leetcode-cn.com/problems/n-queens-ii/) | [TotalNQueens](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_52_totalNQueens.java) | [回溯算法]() | Hard | | | #53 | [最大子序和](https://leetcode-cn.com/problems/maximum-subarray/) | [MaxSubArray.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_53_maxSubArray.java) | [数组]()、[分治算法]()、[动态规划]() | Easy | | +| #54 | [螺旋矩阵](https://leetcode-cn.com/problems/spiral-matrix/) | [SpiralOrder](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_54_spiralOrder.java) | [数组]() | Medium | | | #55 | [跳跃游戏](https://leetcode-cn.com/problems/jump-game/) | [CanJump](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_55_canJump.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Medium | | | #56 | [合并区间](https://leetcode-cn.com/problems/merge-intervals/) | [Merge](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_56_merge.java) | [排序](https://leetcode-cn.com/tag/sort/)、[数组]() | Medium | | | #60 | [第k个排列](https://leetcode-cn.com/problems/permutation-sequence/) | [GetPermutation](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_60_getPermutation_m.java) | [数学]()、[回溯算法]() | Medium | | From 6fc82d4dc4d26878862d263388b60e34ea494280 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Sat, 29 Jun 2019 17:45:31 +0800 Subject: [PATCH 093/308] feat(HARD): add _57_insert --- src/pp/arithmetic/leetcode/_57_insert.java | 163 +++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_57_insert.java diff --git a/src/pp/arithmetic/leetcode/_57_insert.java b/src/pp/arithmetic/leetcode/_57_insert.java new file mode 100644 index 0000000..ccccb4c --- /dev/null +++ b/src/pp/arithmetic/leetcode/_57_insert.java @@ -0,0 +1,163 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +import java.util.Arrays; + +/** + * Created by wangpeng on 2019-06-25. + * 57. 插入区间 + *

+ * 给出一个无重叠的 ,按照区间起始端点排序的区间列表。 + *

+ * 在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。 + *

+ * 示例 1: + *

+ * 输入: intervals = [[1,3],[6,9]], newInterval = [2,5] + * 输出: [[1,5],[6,9]] + * 示例 2: + *

+ * 输入: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8] + * 输出: [[1,2],[3,10],[12,16]] + * 解释: 这是因为新的区间 [4,8] 与 [3,5],[6,7],[8,10] 重叠。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/insert-interval + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _57_insert { + public static void main(String[] args) { + + _57_insert insert = new _57_insert(); + int[][] insert1 = insert.insert(new int[][]{ + {1, 2}, {3, 5}, {6, 7}, {8, 10}, {12, 16} + }, new int[]{4, 8}); + for (int i = 0; i < insert1.length; i++) { + Util.printArray(insert1[i]); + } + + } + + /** + * 前提: + * 对于数字和一个区间的关系只有三种,在区间内,区间前,区间后 + *

+ * 解题思路: + * 1.遍历intervals,拿到item后先判断,确定newInterval的起始和终止位置和区间的关系si,sFind,ei,eFind + * 2.si,ei代表和目前区间的位置关系,-1代表不在区间范围内(比最后一个区间都大) + * 3.sFind,eFind代表是否在区间内,true表示区间内,false表示区间前(区间后可以转换为下一个区间的区间前) + * 4.根据si,sFind,ei,eFind去拼装结果 + * 5.if:si == -1 && ei == -1 ==> 最后加入 + * 6.else if:si == ei ==> 中间插入或者更新某个区间 + * 7.else ==> 合并区间 + * + * @param intervals + * @param newInterval + * @return + */ + public int[][] insert(int[][] intervals, int[] newInterval) { + int[][] retArr; + + int newStart = newInterval[0]; + int newEnd = newInterval[1]; + int si = -1, ei = -1; + boolean sFind = false, eFind = false; + for (int i = 0; i < intervals.length; i++) { + int[] item = intervals[i]; + int itemStart = item[0]; + int itemEnd = item[1]; + if (si == -1) { + if (newStart <= itemEnd) { + si = i; + if (newStart >= itemStart) { + sFind = true; + } + } + } + if (ei == -1) { + if (newEnd <= itemEnd) { + ei = i; + if (newEnd >= itemStart) { + eFind = true; + } + } + } + if (si != -1 && ei != -1) { + break; + } + } + //插入or合并区间 + if (si == -1 && ei == -1) { + //插入最后 + retArr = Arrays.copyOf(intervals, intervals.length + 1); + retArr[intervals.length] = new int[]{newStart, newEnd}; + } else if (si == ei) { + int[] temp = new int[2]; + if (!sFind) { + temp[0] = newStart; + } else { + temp[0] = intervals[si][0]; + } + if (!eFind) { + temp[1] = newEnd; + } else { + temp[1] = intervals[ei][1]; + } + if (!sFind && !eFind) { + //新插入一个 + retArr = new int[intervals.length + 1][]; + int insetI = 0; + for (int i = 0; i < intervals.length; i++) { + if (i == si) { + retArr[insetI] = temp; + insetI++; + } + retArr[insetI] = intervals[i]; + insetI++; + } + } else { + intervals[si] = temp; + retArr = Arrays.copyOf(intervals, intervals.length); + } + } else { + //合并区间 + int skipStartI, skipEndI; + int[] temp = new int[2]; + if (sFind) { + temp[0] = intervals[si][0]; + skipStartI = si; + } else { + temp[0] = newStart; + skipStartI = si; + } + if (eFind) { + temp[1] = intervals[ei][1]; + skipEndI = ei; + } else { + temp[1] = newEnd; + if (ei == -1) { + skipEndI = intervals.length - 1; + } else { + skipEndI = ei - 1; + } + } + int skip = skipEndI - skipStartI; + retArr = new int[intervals.length - skip][]; + for (int i = 0; i < intervals.length; i++) { + if (i < skipStartI) { + retArr[i] = intervals[i]; + } else if (i >= skipStartI && i <= skipEndI) { + if (i == skipStartI) { + retArr[skipStartI] = temp; + } + } else { + retArr[i - skip] = intervals[i]; + } + } + } + + + return retArr; + } +} From 57b58078a9645c977b87968ab28f659f874f1f3a Mon Sep 17 00:00:00 2001 From: wangpeng Date: Sat, 29 Jun 2019 18:23:57 +0800 Subject: [PATCH 094/308] docs: add _57_insert --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0e2b877..c794e75 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成176道 +- leetcode练习,坚持每天一道,目前已完成177道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -23,7 +23,7 @@ - [x] [54. 螺旋矩阵 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_54_spiralOrder.java) -- [ ] [57. 插入区间 -Hard](https://leetcode-cn.com/problems/insert-interval/) +- [x] [57. 插入区间 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_57_insert.java) - [ ] [58. 最后一个单词的长度 -Easy](https://leetcode-cn.com/problems/length-of-last-word/) @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成175) +### 题目列表(更新中--已完成177) -​ [数组]() Medium +​ [Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_57_insert.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -124,6 +124,7 @@ | #54 | [螺旋矩阵](https://leetcode-cn.com/problems/spiral-matrix/) | [SpiralOrder](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_54_spiralOrder.java) | [数组]() | Medium | | | #55 | [跳跃游戏](https://leetcode-cn.com/problems/jump-game/) | [CanJump](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_55_canJump.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Medium | | | #56 | [合并区间](https://leetcode-cn.com/problems/merge-intervals/) | [Merge](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_56_merge.java) | [排序](https://leetcode-cn.com/tag/sort/)、[数组]() | Medium | | +| #57 | [插入区间](https://leetcode-cn.com/problems/insert-interval/) | [Insert.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_57_insert.java) | [排序](https://leetcode-cn.com/tag/sort/)、[数组]() | Hard | | | #60 | [第k个排列](https://leetcode-cn.com/problems/permutation-sequence/) | [GetPermutation](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_60_getPermutation_m.java) | [数学]()、[回溯算法]() | Medium | | | #61 | [旋转链表](https://leetcode-cn.com/problems/rotate-list/) | [RotateRight](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_61_RotateRight.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Medium | | | #62 | [不同路径](https://leetcode-cn.com/problems/unique-paths/) | [UniquePaths](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_62_uniquePaths.java) | [数组]()、[动态规划]() | Medium | | From 56ad4f7977b37ca967a16991d32bd1d8174892d2 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Tue, 2 Jul 2019 10:37:31 +0800 Subject: [PATCH 095/308] feat(EASY): add _58_lengthOfLastWord --- .../leetcode/_58_lengthOfLastWord.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_58_lengthOfLastWord.java diff --git a/src/pp/arithmetic/leetcode/_58_lengthOfLastWord.java b/src/pp/arithmetic/leetcode/_58_lengthOfLastWord.java new file mode 100644 index 0000000..75f27ac --- /dev/null +++ b/src/pp/arithmetic/leetcode/_58_lengthOfLastWord.java @@ -0,0 +1,55 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-07-02. + * 58. 最后一个单词的长度 + *

+ * 给定一个仅包含大小写字母和空格 ' ' 的字符串,返回其最后一个单词的长度。 + *

+ * 如果不存在最后一个单词,请返回 0 。 + *

+ * 说明:一个单词是指由字母组成,但不包含任何空格的字符串。 + *

+ * 示例: + *

+ * 输入: "Hello World" + * 输出: 5 + *

+ *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/length-of-last-word + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _58_lengthOfLastWord { + + public static void main(String[] args) { + _58_lengthOfLastWord length = new _58_lengthOfLastWord(); + System.out.println(length.lengthOfLastWord("Hello World")); + System.out.println(length.lengthOfLastWord(" s ")); + System.out.println(length.lengthOfLastWord(" Hell ")); + } + + /** + * 解题思路: + * 从s的最后一个开始遍历,遇到首个非空的字母开始计数到下一个为空的时候停止 + * + * @param s + * @return + */ + public int lengthOfLastWord(String s) { + int startIndex = -1, endIndex = -1; + for (int i = s.length() - 1; i >= 0; i--) { + if (startIndex != -1 && s.charAt(i) == ' ') { + endIndex = i; + break; + } + if (startIndex == -1 && s.charAt(i) != ' ') { + startIndex = i; + } + } + if (startIndex == -1) { + return 0; + } + return startIndex - endIndex; + } +} From 425782b7de3f986dcd9b73adf4b088ca41bc0098 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Tue, 2 Jul 2019 10:44:14 +0800 Subject: [PATCH 096/308] docs: add _58_lengthOfLastWord --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c794e75..ac1f9bd 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成177道 +- leetcode练习,坚持每天一道,目前已完成178道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -25,7 +25,7 @@ - [x] [57. 插入区间 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_57_insert.java) -- [ ] [58. 最后一个单词的长度 -Easy](https://leetcode-cn.com/problems/length-of-last-word/) +- [x] [58. 最后一个单词的长度 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_58_lengthOfLastWord.java) - [ ] [59. 螺旋矩阵 II -Medium](https://leetcode-cn.com/problems/spiral-matrix-ii/) @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成177) +### 题目列表(更新中--已完成178) -​ [Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_57_insert.java) +​ [Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_58_lengthOfLastWord.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -125,6 +125,7 @@ | #55 | [跳跃游戏](https://leetcode-cn.com/problems/jump-game/) | [CanJump](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_55_canJump.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Medium | | | #56 | [合并区间](https://leetcode-cn.com/problems/merge-intervals/) | [Merge](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_56_merge.java) | [排序](https://leetcode-cn.com/tag/sort/)、[数组]() | Medium | | | #57 | [插入区间](https://leetcode-cn.com/problems/insert-interval/) | [Insert.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_57_insert.java) | [排序](https://leetcode-cn.com/tag/sort/)、[数组]() | Hard | | +| #58 | [最后一个单词的长度](https://leetcode-cn.com/problems/length-of-last-word/) | [LengthOfLastWord](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_58_lengthOfLastWord.java) | [字符串]() | Easy | | | #60 | [第k个排列](https://leetcode-cn.com/problems/permutation-sequence/) | [GetPermutation](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_60_getPermutation_m.java) | [数学]()、[回溯算法]() | Medium | | | #61 | [旋转链表](https://leetcode-cn.com/problems/rotate-list/) | [RotateRight](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_61_RotateRight.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Medium | | | #62 | [不同路径](https://leetcode-cn.com/problems/unique-paths/) | [UniquePaths](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_62_uniquePaths.java) | [数组]()、[动态规划]() | Medium | | From 6ab2632265e3c793ca752bb2cfec18601168a7e8 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 4 Jul 2019 14:34:26 +0800 Subject: [PATCH 097/308] feat(MEDIUM): add _59_generateMatrix --- .../leetcode/_59_generateMatrix.java | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_59_generateMatrix.java diff --git a/src/pp/arithmetic/leetcode/_59_generateMatrix.java b/src/pp/arithmetic/leetcode/_59_generateMatrix.java new file mode 100644 index 0000000..8b5dac9 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_59_generateMatrix.java @@ -0,0 +1,60 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +/** + * Created by wangpeng on 2019-07-02. + * 59. 螺旋矩阵 II + *

+ * 给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。 + *

+ * 示例: + *

+ * 输入: 3 + * 输出: + * [ + * [ 1, 2, 3 ], + * [ 8, 9, 4 ], + * [ 7, 6, 5 ] + * ] + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/spiral-matrix-ii + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _59_generateMatrix { + public static void main(String[] args) { + _59_generateMatrix generateMatrix = new _59_generateMatrix(); + int[][] ints = generateMatrix.generateMatrix(3); + for (int i = 0; i < ints.length; i++) { + Util.printArray(ints[i]); + } + } + + /** + * 解题思路: + * 通过四个变量(2个行0~n、2个列0~n),一圈一圈的遍历,每一圈遍历的时候做四个方向的遍历 + * + * @param n + * @return + */ + public int[][] generateMatrix(int n) { + int[][] matrix = new int[n][n]; + int r1 = 0, r2 = matrix.length - 1; + int c1 = 0, c2 = matrix[0].length - 1; + int index = 1; + while (r1 <= r2 && c1 <= c2) { + for (int c = c1; c <= c2; c++) matrix[r1][c] = index++; + for (int r = r1 + 1; r <= r2; r++) matrix[r][c2] = index++; + if (r1 < r2 && c1 < c2) { + for (int c = c2 - 1; c > c1; c--) matrix[r2][c] = index++; + for (int r = r2; r > r1; r--) matrix[r][c1] = index++; + } + r1++; + r2--; + c1++; + c2--; + } + return matrix; + } +} From bba73e6c5c78855b86f42d6628b49cca1e38e9f9 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 4 Jul 2019 14:42:32 +0800 Subject: [PATCH 098/308] docs: add _59_generateMatrix --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ac1f9bd..7bc50a2 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成178道 +- leetcode练习,坚持每天一道,目前已完成179道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -27,7 +27,7 @@ - [x] [58. 最后一个单词的长度 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_58_lengthOfLastWord.java) -- [ ] [59. 螺旋矩阵 II -Medium](https://leetcode-cn.com/problems/spiral-matrix-ii/) +- [x] [59. 螺旋矩阵 II -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_59_generateMatrix.java) ## 已解题目 @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成178) +### 题目列表(更新中--已完成179) -​ [Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_58_lengthOfLastWord.java) +​ [Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_59_generateMatrix.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -126,6 +126,7 @@ | #56 | [合并区间](https://leetcode-cn.com/problems/merge-intervals/) | [Merge](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_56_merge.java) | [排序](https://leetcode-cn.com/tag/sort/)、[数组]() | Medium | | | #57 | [插入区间](https://leetcode-cn.com/problems/insert-interval/) | [Insert.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_57_insert.java) | [排序](https://leetcode-cn.com/tag/sort/)、[数组]() | Hard | | | #58 | [最后一个单词的长度](https://leetcode-cn.com/problems/length-of-last-word/) | [LengthOfLastWord](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_58_lengthOfLastWord.java) | [字符串]() | Easy | | +| #59 | [螺旋矩阵 II](https://leetcode-cn.com/problems/spiral-matrix-ii/) | [GenerateMatrix](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_59_generateMatrix.java) | | | | | #60 | [第k个排列](https://leetcode-cn.com/problems/permutation-sequence/) | [GetPermutation](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_60_getPermutation_m.java) | [数学]()、[回溯算法]() | Medium | | | #61 | [旋转链表](https://leetcode-cn.com/problems/rotate-list/) | [RotateRight](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_61_RotateRight.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Medium | | | #62 | [不同路径](https://leetcode-cn.com/problems/unique-paths/) | [UniquePaths](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_62_uniquePaths.java) | [数组]()、[动态规划]() | Medium | | From f8b8ae9eed6d7b9a0a958f7c7b96193fafdf45d6 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 4 Jul 2019 14:51:29 +0800 Subject: [PATCH 099/308] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E9=A2=98?= =?UTF-8?q?=E7=9B=AE=E5=88=97=E8=A1=A8=EF=BC=88=E7=83=AD=E9=A2=98Hot100?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 7bc50a2..280f283 100644 --- a/README.md +++ b/README.md @@ -11,23 +11,23 @@ - 欢迎star、fork、交流,一起互勉 - 微信号:pp_hdsny(备注leetcode) - 网址:https://leetcode-cn.com/ -## 本周待解题目列表 +## 待解题目列表 -开始扫题 +扫题:热题 Hot 100 -- [x] [41. 缺失的第一个正数 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_41_firstMissingPositive.java) +- [ ] [75. 颜色分类 -Medium](https://leetcode-cn.com/problems/sort-colors/) -- [x] [48. 旋转图像 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_48_rotate.java) +- [ ] [79. 单词搜索 -Medium](https://leetcode-cn.com/problems/word-search/) -- [x] [50. Pow(x, n) -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_50_myPow.java) +- [ ] [84. 柱状图中最大的矩形 -Hard](https://leetcode-cn.com/problems/largest-rectangle-in-histogram/) -- [x] [54. 螺旋矩阵 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_54_spiralOrder.java) +- [ ] [85. 最大矩形 -Hard](https://leetcode-cn.com/problems/maximal-rectangle/) -- [x] [57. 插入区间 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_57_insert.java) +- [ ] [94. 二叉树的中序遍历 -Medium](https://leetcode-cn.com/problems/binary-tree-inorder-traversal/) -- [x] [58. 最后一个单词的长度 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_58_lengthOfLastWord.java) +- [ ] [98. 验证二叉搜索树 -Medium](https://leetcode-cn.com/problems/validate-binary-search-tree/) -- [x] [59. 螺旋矩阵 II -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_59_generateMatrix.java) +- [ ] [101. 对称二叉树 -Easy](https://leetcode-cn.com/problems/symmetric-tree/) ## 已解题目 @@ -126,7 +126,7 @@ | #56 | [合并区间](https://leetcode-cn.com/problems/merge-intervals/) | [Merge](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_56_merge.java) | [排序](https://leetcode-cn.com/tag/sort/)、[数组]() | Medium | | | #57 | [插入区间](https://leetcode-cn.com/problems/insert-interval/) | [Insert.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_57_insert.java) | [排序](https://leetcode-cn.com/tag/sort/)、[数组]() | Hard | | | #58 | [最后一个单词的长度](https://leetcode-cn.com/problems/length-of-last-word/) | [LengthOfLastWord](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_58_lengthOfLastWord.java) | [字符串]() | Easy | | -| #59 | [螺旋矩阵 II](https://leetcode-cn.com/problems/spiral-matrix-ii/) | [GenerateMatrix](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_59_generateMatrix.java) | | | | +| #59 | [螺旋矩阵 II](https://leetcode-cn.com/problems/spiral-matrix-ii/) | [GenerateMatrix](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_59_generateMatrix.java) | [数组]() | Medium | | | #60 | [第k个排列](https://leetcode-cn.com/problems/permutation-sequence/) | [GetPermutation](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_60_getPermutation_m.java) | [数学]()、[回溯算法]() | Medium | | | #61 | [旋转链表](https://leetcode-cn.com/problems/rotate-list/) | [RotateRight](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_61_RotateRight.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Medium | | | #62 | [不同路径](https://leetcode-cn.com/problems/unique-paths/) | [UniquePaths](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_62_uniquePaths.java) | [数组]()、[动态规划]() | Medium | | From defab889e217a86ab05beb2084c231316e9d6a11 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Fri, 5 Jul 2019 13:52:35 +0800 Subject: [PATCH 100/308] feat(MEDIUM): add _75_sortColors --- .../arithmetic/leetcode/_75_sortColors.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_75_sortColors.java diff --git a/src/pp/arithmetic/leetcode/_75_sortColors.java b/src/pp/arithmetic/leetcode/_75_sortColors.java new file mode 100644 index 0000000..2ee6eed --- /dev/null +++ b/src/pp/arithmetic/leetcode/_75_sortColors.java @@ -0,0 +1,75 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +/** + * Created by wangpeng on 2019-07-04. + * 75. 颜色分类 + *

+ * 给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。 + *

+ * 此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。 + *

+ * 注意: + * 不能使用代码库中的排序函数来解决这道题。 + *

+ * 示例: + *

+ * 输入: [2,0,2,1,1,0] + * 输出: [0,0,1,1,2,2] + * 进阶: + *

+ * 一个直观的解决方案是使用计数排序的两趟扫描算法。 + * 首先,迭代计算出0、1 和 2 元素的个数,然后按照0、1、2的排序,重写当前数组。 + * 你能想出一个仅使用常数空间的一趟扫描算法吗? + *

+ *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/sort-colors + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _75_sortColors { + + public static void main(String[] args) { + _75_sortColors sortColors = new _75_sortColors(); + int[] nums = {2, 1, 2}; + sortColors.sortColors(nums); + Util.printArray(nums); + } + + /** + * 解题思路: + * 原地排序==>借助常量级的空间做中转,可以参考快排实现? + * 但是题目所需:你能想出一个仅使用常数空间的一趟扫描算法吗?(也就是说时间复杂度最好是O(n)) + * 我们用三个指针(p0, p2 和curr)来分别追踪0的最右边界,2的最左边界和当前考虑的元素 + * 此问题称为"荷兰国旗问题" + * + * @param nums + */ + public void sortColors(int[] nums) { + // 对于所有 idx < i : nums[idx < i] = 0 + // j是当前考虑元素的下标 + int p0 = 0, curr = 0; + // 对于所有 idx > k : nums[idx > k] = 2 + int p2 = nums.length - 1; + + int tmp; + while (curr <= p2) { + if (nums[curr] == 0) { + // 交换第 p0个和第curr个元素 + // i++,j++ + tmp = nums[p0]; + nums[p0++] = nums[curr]; + nums[curr++] = tmp; + } else if (nums[curr] == 2) { + // 交换第k个和第curr个元素 + // p2-- + tmp = nums[curr]; + nums[curr] = nums[p2]; + nums[p2--] = tmp; + } else { + curr++; + } + } + } +} From 5dc1a0cf670bf89f4c338c4eb869fea8dcd999fd Mon Sep 17 00:00:00 2001 From: wangpeng Date: Fri, 5 Jul 2019 13:56:43 +0800 Subject: [PATCH 101/308] docs: add _75_sortColors --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 280f283..7d7de81 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成179道 +- leetcode练习,坚持每天一道,目前已完成180道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -15,7 +15,7 @@ 扫题:热题 Hot 100 -- [ ] [75. 颜色分类 -Medium](https://leetcode-cn.com/problems/sort-colors/) +- [x] [75. 颜色分类 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_75_sortColors.java) - [ ] [79. 单词搜索 -Medium](https://leetcode-cn.com/problems/word-search/) @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成179) +### 题目列表(更新中--已完成180) -​ [Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_59_generateMatrix.java) +​ [Leetcode-Java(更多题解,持续更新)]https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_75_sortColors.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -136,9 +136,11 @@ | #70 | [爬楼梯](https://leetcode-cn.com/problems/climbing-stairs/) | [ClimbStairs](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_70_climbStairs.java) | [动态规划]() | Easy | 经典题 | | #71 | [简化路径](https://leetcode-cn.com/problems/simplify-path/) | [SimplifyPath](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_71_simplifyPath.java) | [栈](https://leetcode-cn.com/tag/stack/)、[字符串]() | Medium | | | #72 | [编辑距离](https://leetcode-cn.com/problems/edit-distance/) | [MinDistance](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_72_minDistance.java) | [字符串]()、[动态规划]() | Hard | | +| #75 | [颜色分类](https://leetcode-cn.com/problems/sort-colors/) | [SortColors](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_75_sortColors.java) | [排序](https://leetcode-cn.com/tag/sort/)、[数组]()、[双指针]() | Medium | | | #76 | [最小覆盖子串](https://leetcode-cn.com/problems/minimum-window-substring/) | [MinWindow](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_76_minWindow.java) | [哈希表]()、[双指针]()、[字符串]()、[sliding window]() | Hard | | | #77 | [组合](https://leetcode-cn.com/problems/combinations/) | [Combine](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_77_combine.java) | [回溯算法]() | Medium | | | #78 | [子集](https://leetcode-cn.com/problems/subsets/) | [Subsets](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_78_subsets.java) | [位运算](https://leetcode-cn.com/tag/bit-manipulation/)、[数组]()、[回溯算法]() | Medium | | +| | | | | | | | #80 | [删除排序数组中的重复项 II](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array-ii/) | [RemoveDuplicates](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_80_removeDuplicates.java) | [数组]()、[双指针]() | Medium | | | #86 | [分隔链表](https://leetcode-cn.com/problems/partition-list/) | [Partition](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_86_Partition.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Medium | | | #90 | [子集 II](https://leetcode-cn.com/problems/subsets-ii/) | [SubsetsWithDup](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_90_subsetsWithDup.java) | [数组]()、[回溯算法]() | Medium | | From 0116954b4cb351d95004f1275c0d6e14fc8a2223 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Wed, 17 Jul 2019 10:27:55 +0800 Subject: [PATCH 102/308] feat(MEDIUM): add _79_exist --- src/pp/arithmetic/leetcode/_79_exist.java | 109 ++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_79_exist.java diff --git a/src/pp/arithmetic/leetcode/_79_exist.java b/src/pp/arithmetic/leetcode/_79_exist.java new file mode 100644 index 0000000..27d1a92 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_79_exist.java @@ -0,0 +1,109 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-07-05. + * 79. 单词搜索 + *

+ * 给定一个二维网格和一个单词,找出该单词是否存在于网格中。 + *

+ * 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。 + *

+ * 示例: + *

+ * board = + * [ + * ['A','B','C','E'], + * ['S','F','C','S'], + * ['A','D','E','E'] + * ] + *

+ * 给定 word = "ABCCED", 返回 true. + * 给定 word = "SEE", 返回 true. + * 给定 word = "ABCB", 返回 false. + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/word-search + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _79_exist { + + public static void main(String[] args) { + _79_exist exist = new _79_exist(); + char[][] board = { + {'A', 'B', 'C', 'E'}, + {'S', 'F', 'C', 'S'}, + {'A', 'D', 'E', 'E'} + }; + System.out.println(exist.exist(board, "ABCCED")); + System.out.println(exist.exist(board, "SEE")); + System.out.println(exist.exist(board, "ABCB")); + } + + /** + * 解题思路: + * 初步构思,类似图的BFS + * 执行用时 :20 ms, 在所有 Java 提交中击败了21.03%的用户 + * 内存消耗 :45 MB, 在所有 Java 提交中击败了75.00%的用户 + * + * @param board + * @param word + * @return + */ + public boolean exist(char[][] board, String word) { + if (board.length == 0) return false; + boolean[][] find = new boolean[board.length][board[0].length]; + int wordIndex = 0; + boolean isExist; + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[i].length; j++) { + if (board[i][j] == word.charAt(wordIndex)) { + isExist = bfs(board, find, i, j, 0, word); + if (isExist) { + return true; + } + } + } + } + return false; + } + + int[][] rec = new int[][]{{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; + + private boolean bfs(char[][] board, boolean[][] find, int rowI, int colI, int wordI, String word) { + if (wordI >= word.length()) { + return false; + } + if (rowI >= board.length) { + return false; + } + boolean isExist = false; + if (board[rowI][colI] == word.charAt(wordI)) { + //保存已遍历的结果,防止重复死循环找 + find[rowI][colI] = true; + if (wordI == word.length() - 1) return true; + //向四个方向开始遍历 + for (int i = 0; i < rec.length; i++) { + int nextRowI = rowI + rec[i][0]; + int nextColI = colI + rec[i][1]; + if (nextRowI < 0 || nextRowI >= board.length || nextColI < 0 || nextColI >= board[rowI].length) { + //位置越界 + continue; + } + if (find[nextRowI][nextColI]) { + //已遍历过 + continue; + } + //找到下一个单词,开始到下一个位置进行寻找 + if (board[nextRowI][nextColI] == word.charAt(wordI + 1)) { + isExist = bfs(board, find, nextRowI, nextColI, wordI + 1, word); + } + if (isExist) { + break; + } + } + find[rowI][colI] = false; + } + return isExist; + } + +} From 48653f67f8b4b2553769b12a75552ed0e79a75f2 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Wed, 17 Jul 2019 10:30:48 +0800 Subject: [PATCH 103/308] docs: add _79_exist --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 7d7de81..643a6ae 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成180道 +- leetcode练习,坚持每天一道,目前已完成181道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -17,7 +17,7 @@ - [x] [75. 颜色分类 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_75_sortColors.java) -- [ ] [79. 单词搜索 -Medium](https://leetcode-cn.com/problems/word-search/) +- [x] [79. 单词搜索 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_79_exist.java) - [ ] [84. 柱状图中最大的矩形 -Hard](https://leetcode-cn.com/problems/largest-rectangle-in-histogram/) @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成180) +### 题目列表(更新中--已完成181) -​ [Leetcode-Java(更多题解,持续更新)]https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_75_sortColors.java) +​ [Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_79_exist.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -140,7 +140,7 @@ | #76 | [最小覆盖子串](https://leetcode-cn.com/problems/minimum-window-substring/) | [MinWindow](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_76_minWindow.java) | [哈希表]()、[双指针]()、[字符串]()、[sliding window]() | Hard | | | #77 | [组合](https://leetcode-cn.com/problems/combinations/) | [Combine](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_77_combine.java) | [回溯算法]() | Medium | | | #78 | [子集](https://leetcode-cn.com/problems/subsets/) | [Subsets](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_78_subsets.java) | [位运算](https://leetcode-cn.com/tag/bit-manipulation/)、[数组]()、[回溯算法]() | Medium | | -| | | | | | | +| #79 | [单词搜索](https://leetcode-cn.com/problems/word-search/) | [Exist](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_79_exist.java) | [数组]()、[回溯算法]() | Medium | | | #80 | [删除排序数组中的重复项 II](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array-ii/) | [RemoveDuplicates](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_80_removeDuplicates.java) | [数组]()、[双指针]() | Medium | | | #86 | [分隔链表](https://leetcode-cn.com/problems/partition-list/) | [Partition](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_86_Partition.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Medium | | | #90 | [子集 II](https://leetcode-cn.com/problems/subsets-ii/) | [SubsetsWithDup](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_90_subsetsWithDup.java) | [数组]()、[回溯算法]() | Medium | | From b526d5361019e1a748789afcbb8732e69353c4da Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 18 Jul 2019 19:55:25 +0800 Subject: [PATCH 104/308] feat(HARD): add _84_largestRectangleArea --- .../leetcode/_84_largestRectangleArea.java | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_84_largestRectangleArea.java diff --git a/src/pp/arithmetic/leetcode/_84_largestRectangleArea.java b/src/pp/arithmetic/leetcode/_84_largestRectangleArea.java new file mode 100644 index 0000000..8ff5f1a --- /dev/null +++ b/src/pp/arithmetic/leetcode/_84_largestRectangleArea.java @@ -0,0 +1,109 @@ +package pp.arithmetic.leetcode; + +import java.util.Stack; + +/** + * Created by wangpeng on 2019-07-18. + *

+ * 84. 柱状图中最大的矩形 + *

+ * 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 + *

+ * 求在该柱状图中,能够勾勒出来的矩形的最大面积。 + *

+ *  https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/10/12/histogram.png + *

+ * 以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]。 + *

+ * https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/10/12/histogram_area.png + *

+ * 图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。 + *

+ *   + *

+ * 示例: + *

+ * 输入: [2,1,5,6,2,3] + * 输出: 10 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/largest-rectangle-in-histogram + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _84_largestRectangleArea { + + public static void main(String[] args) { + _84_largestRectangleArea largestRectangleArea = new _84_largestRectangleArea(); + System.out.println(largestRectangleArea.largestRectangleArea(new int[]{2, 1, 5, 6, 2, 3})); + System.out.println(largestRectangleArea.largestRectangleArea(new int[]{1})); + System.out.println(largestRectangleArea.largestRectangleArea(new int[]{4, 2})); + } + + /** + * 解题思路: + * 能画出的矩形面积受两部分影响,一是宽,一是高,但是具体如何才能使勾勒出的矩形最大?==>尽可能使宽*高最大化 + * 难点:如何保存遍历过程中的中间结果,可能中间结果在不断遍历的过程中会变成最大的面积 + *

+ * 分治求解 + * 1、先找到矩形中最小的一个,求出面积 + * 2、再求最小左边的矩形面积(循环1,2,3) + * 3、再求最小右边的矩形面积(循环1,2,3) + * 4、从其中找出最大的面积 + *

+ * 执行用时 :591 ms, 在所有 Java 提交中击败了20.50%的用户 ==>时间复杂度O(nLogn) + * 内存消耗 :43.3 MB, 在所有 Java 提交中击败了31.60%的用户 + *

+ * 更优解法(栈):{@link _84_largestRectangleArea#largestRectangleArea2(int[])} ==>时间复杂度O(n) + * + * @param heights + * @return + */ + public int largestRectangleArea(int[] heights) { + return calculate(heights, 0, heights.length - 1); + } + + /** + * 分治求解 + * + * @param heights + * @param start + * @param end + * @return + */ + private int calculate(int[] heights, int start, int end) { + if (start > end) { + return 0; + } + + int min = start; + for (int i = start; i <= end; i++) { + if (heights[i] < heights[min]) { + min = i; + } + } + int mid = heights[min] * (end - start + 1); + int left = calculate(heights, start, min - 1); + int right = calculate(heights, min + 1, end); + return Math.max(mid, Math.max(left, right)); + } + + + /** + * 栈 + * @param heights + * @return + */ + public int largestRectangleArea2(int[] heights) { + Stack stack = new Stack<>(); + stack.push(-1); + int maxarea = 0; + for (int i = 0; i < heights.length; ++i) { + while (stack.peek() != -1 && heights[stack.peek()] >= heights[i]) + maxarea = Math.max(maxarea, heights[stack.pop()] * (i - stack.peek() - 1)); + stack.push(i); + } + while (stack.peek() != -1) + maxarea = Math.max(maxarea, heights[stack.pop()] * (heights.length - stack.peek() - 1)); + return maxarea; + } +} From 730ea2cb73a1ff0e41731ff4258e251cd7d4e4c8 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Thu, 18 Jul 2019 19:58:50 +0800 Subject: [PATCH 105/308] docs: add _84_largestRectangleArea --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 643a6ae..4da9d3f 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成181道 +- leetcode练习,坚持每天一道,目前已完成182道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -19,7 +19,7 @@ - [x] [79. 单词搜索 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_79_exist.java) -- [ ] [84. 柱状图中最大的矩形 -Hard](https://leetcode-cn.com/problems/largest-rectangle-in-histogram/) +- [x] [84. 柱状图中最大的矩形 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_84_largestRectangleArea.java) - [ ] [85. 最大矩形 -Hard](https://leetcode-cn.com/problems/maximal-rectangle/) @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成181) +### 题目列表(更新中--已完成182) -​ [Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_79_exist.java) +​ [Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_84_largestRectangleArea.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -140,8 +140,9 @@ | #76 | [最小覆盖子串](https://leetcode-cn.com/problems/minimum-window-substring/) | [MinWindow](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_76_minWindow.java) | [哈希表]()、[双指针]()、[字符串]()、[sliding window]() | Hard | | | #77 | [组合](https://leetcode-cn.com/problems/combinations/) | [Combine](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_77_combine.java) | [回溯算法]() | Medium | | | #78 | [子集](https://leetcode-cn.com/problems/subsets/) | [Subsets](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_78_subsets.java) | [位运算](https://leetcode-cn.com/tag/bit-manipulation/)、[数组]()、[回溯算法]() | Medium | | -| #79 | [单词搜索](https://leetcode-cn.com/problems/word-search/) | [Exist](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_79_exist.java) | [数组]()、[回溯算法]() | Medium | | +| #79 | [单词搜索](https://leetcode-cn.com/problems/word-search/) | [Exist](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_79_exist.java) | [数组]()、[回溯算法]() | Medium | 回溯-经典题 | | #80 | [删除排序数组中的重复项 II](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array-ii/) | [RemoveDuplicates](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_80_removeDuplicates.java) | [数组]()、[双指针]() | Medium | | +| #84 | [柱状图中最大的矩形](https://leetcode-cn.com/problems/largest-rectangle-in-histogram/) | [LargestRectangleArea](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_84_largestRectangleArea.java) | [栈](https://leetcode-cn.com/tag/stack/)、[数组]() | Hard | 栈、分治-经典题 | | #86 | [分隔链表](https://leetcode-cn.com/problems/partition-list/) | [Partition](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_86_Partition.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Medium | | | #90 | [子集 II](https://leetcode-cn.com/problems/subsets-ii/) | [SubsetsWithDup](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_90_subsetsWithDup.java) | [数组]()、[回溯算法]() | Medium | | | #91 | [解码方法](https://leetcode-cn.com/problems/decode-ways/) | [NumDecodings](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_91_numDecodings.java) | [字符串]()、[动态规划]() | Medium | | From 415b161f13a10a9c001b3dd814f64e8c9c96ca6a Mon Sep 17 00:00:00 2001 From: wangpeng Date: Fri, 19 Jul 2019 11:16:49 +0800 Subject: [PATCH 106/308] feat(HARD): add _85_maximalRectangle --- .../leetcode/_85_maximalRectangle.java | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_85_maximalRectangle.java diff --git a/src/pp/arithmetic/leetcode/_85_maximalRectangle.java b/src/pp/arithmetic/leetcode/_85_maximalRectangle.java new file mode 100644 index 0000000..4fce06c --- /dev/null +++ b/src/pp/arithmetic/leetcode/_85_maximalRectangle.java @@ -0,0 +1,88 @@ +package pp.arithmetic.leetcode; + +import java.util.Arrays; + +/** + * Created by wangpeng on 2019-07-18. + * 85. 最大矩形 + *

+ * 给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。 + *

+ * 示例: + *

+ * 输入: + * [ + * ["1","0","1","0","0"], + * ["1","0","1","1","1"], + * ["1","1","1","1","1"], + * ["1","0","0","1","0"] + * ] + * 输出: 6 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/maximal-rectangle + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _85_maximalRectangle { + + public static void main(String[] args) { + _85_maximalRectangle maximalRectangle = new _85_maximalRectangle(); + int i = maximalRectangle.maximalRectangle(new char[][]{ + {'1', '0', '1', '0', '0'}, + {'1', '0', '1', '1', '1'}, + {'1', '1', '1', '1', '1'}, + {'1', '0', '0', '1', '0'} + }); + System.out.println(i); + } + + + /** + * 官方题解:动态规划 + * + * @param matrix + * @return + */ + public int maximalRectangle(char[][] matrix) { + if (matrix.length == 0) return 0; + int m = matrix.length; + int n = matrix[0].length; + + int[] left = new int[n]; // initialize left as the leftmost boundary possible + int[] right = new int[n]; + int[] height = new int[n]; + + Arrays.fill(right, n); // initialize right as the rightmost boundary possible + + int maxarea = 0; + for (int i = 0; i < m; i++) { + int cur_left = 0, cur_right = n; + // update height + for (int j = 0; j < n; j++) { + if (matrix[i][j] == '1') height[j]++; + else height[j] = 0; + } + // update left + for (int j = 0; j < n; j++) { + if (matrix[i][j] == '1') left[j] = Math.max(left[j], cur_left); + else { + left[j] = 0; + cur_left = j + 1; + } + } + // update right + for (int j = n - 1; j >= 0; j--) { + if (matrix[i][j] == '1') right[j] = Math.min(right[j], cur_right); + else { + right[j] = n; + cur_right = j; + } + } + // update area + for (int j = 0; j < n; j++) { + maxarea = Math.max(maxarea, (right[j] - left[j]) * height[j]); + } + } + return maxarea; + } +} From 56e10ac091f122ed5091e7d7cb9e43732d2eb8d5 Mon Sep 17 00:00:00 2001 From: wangpeng Date: Fri, 19 Jul 2019 11:19:48 +0800 Subject: [PATCH 107/308] docs: add _85_maximalRectangle --- README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 4da9d3f..85ed0e2 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成182道 +- leetcode练习,坚持每天一道,目前已完成183道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -21,7 +21,7 @@ - [x] [84. 柱状图中最大的矩形 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_84_largestRectangleArea.java) -- [ ] [85. 最大矩形 -Hard](https://leetcode-cn.com/problems/maximal-rectangle/) +- [x] [85. 最大矩形 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_85_maximalRectangle.java) - [ ] [94. 二叉树的中序遍历 -Medium](https://leetcode-cn.com/problems/binary-tree-inorder-traversal/) @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成182) +### 题目列表(更新中--已完成183) -​ [Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_84_largestRectangleArea.java) +[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_85_maximalRectangle.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -140,9 +140,10 @@ | #76 | [最小覆盖子串](https://leetcode-cn.com/problems/minimum-window-substring/) | [MinWindow](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_76_minWindow.java) | [哈希表]()、[双指针]()、[字符串]()、[sliding window]() | Hard | | | #77 | [组合](https://leetcode-cn.com/problems/combinations/) | [Combine](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_77_combine.java) | [回溯算法]() | Medium | | | #78 | [子集](https://leetcode-cn.com/problems/subsets/) | [Subsets](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_78_subsets.java) | [位运算](https://leetcode-cn.com/tag/bit-manipulation/)、[数组]()、[回溯算法]() | Medium | | -| #79 | [单词搜索](https://leetcode-cn.com/problems/word-search/) | [Exist](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_79_exist.java) | [数组]()、[回溯算法]() | Medium | 回溯-经典题 | +| #79 | [单词搜索](https://leetcode-cn.com/problems/word-search/) | [Exist](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_79_exist.java) | [数组]()、[回溯算法]() | Medium | 经典题(回溯) | | #80 | [删除排序数组中的重复项 II](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array-ii/) | [RemoveDuplicates](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_80_removeDuplicates.java) | [数组]()、[双指针]() | Medium | | -| #84 | [柱状图中最大的矩形](https://leetcode-cn.com/problems/largest-rectangle-in-histogram/) | [LargestRectangleArea](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_84_largestRectangleArea.java) | [栈](https://leetcode-cn.com/tag/stack/)、[数组]() | Hard | 栈、分治-经典题 | +| #84 | [柱状图中最大的矩形](https://leetcode-cn.com/problems/largest-rectangle-in-histogram/) | [LargestRectangleArea](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_84_largestRectangleArea.java) | [栈](https://leetcode-cn.com/tag/stack/)、[数组]() | Hard | 经典题(栈、分治) | +| #85 | [最大矩形](https://leetcode-cn.com/problems/maximal-rectangle/) | [MaximalRectangle](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_85_maximalRectangle.java) | [栈](https://leetcode-cn.com/tag/stack/)、[数组]() | Hard | | | #86 | [分隔链表](https://leetcode-cn.com/problems/partition-list/) | [Partition](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_86_Partition.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Medium | | | #90 | [子集 II](https://leetcode-cn.com/problems/subsets-ii/) | [SubsetsWithDup](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_90_subsetsWithDup.java) | [数组]()、[回溯算法]() | Medium | | | #91 | [解码方法](https://leetcode-cn.com/problems/decode-ways/) | [NumDecodings](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_91_numDecodings.java) | [字符串]()、[动态规划]() | Medium | | From 99435b9df59a438b29b1663158f8e0fcbffdcfa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 24 Jul 2019 20:47:18 +0800 Subject: [PATCH 108/308] feat(MEDIUM): add _94_inorderTraversal --- .../leetcode/_94_inorderTraversal.java | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_94_inorderTraversal.java diff --git a/src/pp/arithmetic/leetcode/_94_inorderTraversal.java b/src/pp/arithmetic/leetcode/_94_inorderTraversal.java new file mode 100644 index 0000000..152c197 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_94_inorderTraversal.java @@ -0,0 +1,95 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; +import pp.arithmetic.model.TreeNode; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +/** + * Created by wangpeng on 2019-07-24. + * 94. 二叉树的中序遍历 + *

+ * 给定一个二叉树,返回它的中序 遍历。 + *

+ * 示例: + *

+ * 输入: [1,null,2,3] + * 1 + * \ + * 2 + * / + * 3 + *

+ * 输出: [1,3,2] + * 进阶: 递归算法很简单,你可以通过迭代算法完成吗? + *

+ *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _94_inorderTraversal { + + public static void main(String[] args) { + TreeNode treeNode = Util.generateTreeNode(); + Util.printTree(treeNode); + _94_inorderTraversal inorderTraversal = new _94_inorderTraversal(); + //递归算法 + Util.printList(inorderTraversal.inorderTraversal(treeNode)); + Util.printList(inorderTraversal.inorderTraversal2(treeNode)); + + } + + /** + * 解题思路: + * 按题目所说,递归算法{@link _94_inorderTraversal#inorderTraversal2(TreeNode)}很简单,我们试着迭代算法完成 + * 模拟递归,用一个栈保存遍历结果 + * + * @param root + * @return + */ + public List inorderTraversal(TreeNode root) { + List result = new ArrayList<>(); + Stack stack = new Stack<>(); + TreeNode curr = root; + while (curr != null || !stack.isEmpty()) { + //左 + while (curr != null) { + stack.push(curr); + curr = curr.left; + } + curr = stack.pop(); + //中 + result.add(curr.val); + //右 + curr = curr.right; + } + return result; + } + + /** + * 递归算法 + * + * @param root + * @return + */ + public List inorderTraversal2(TreeNode root) { + List result = new ArrayList<>(); + recursion(root, result); + return result; + } + + private void recursion(TreeNode root, List result) { + if (root == null) { + return; + } + //左 + recursion(root.left, result); + //中 + result.add(root.val); + //右 + recursion(root.right, result); + } +} From b2920e6f98805c5d27f75de70dc92f4336ede511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 24 Jul 2019 20:50:09 +0800 Subject: [PATCH 109/308] docs: add _94_inorderTraversal --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 85ed0e2..082eb4b 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成183道 +- leetcode练习,坚持每天一道,目前已完成184道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -23,7 +23,7 @@ - [x] [85. 最大矩形 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_85_maximalRectangle.java) -- [ ] [94. 二叉树的中序遍历 -Medium](https://leetcode-cn.com/problems/binary-tree-inorder-traversal/) +- [x] [94. 二叉树的中序遍历 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_94_inorderTraversal.java) - [ ] [98. 验证二叉搜索树 -Medium](https://leetcode-cn.com/problems/validate-binary-search-tree/) @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成183) +### 题目列表(更新中--已完成184) -[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_85_maximalRectangle.java) +[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_94_inorderTraversal.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -149,6 +149,7 @@ | #91 | [解码方法](https://leetcode-cn.com/problems/decode-ways/) | [NumDecodings](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_91_numDecodings.java) | [字符串]()、[动态规划]() | Medium | | | #92 | [反转链表 II](https://leetcode-cn.com/problems/reverse-linked-list-ii/) | [ReverseBetween](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_92_ReverseBetween.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | | #93 | [复原IP地址](https://leetcode-cn.com/problems/restore-ip-addresses/) | [RestoreIpAddresses](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_93_restoreIpAddresses.java) | [字符串]()、[回溯算法]() | Medium | | +| #94 | [二叉树的中序遍历](https://leetcode-cn.com/problems/binary-tree-inorder-traversal/) | [InorderTraversal](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_94_inorderTraversal.java) | [栈](https://leetcode-cn.com/tag/stack/)、[树](https://leetcode-cn.com/tag/tree/)、[哈希表]() | Medium | | | #95 | [不同的二叉搜索树 II](https://leetcode-cn.com/problems/unique-binary-search-trees-ii/) | [GenerateTrees](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_95_generateTrees.java) | [树](https://leetcode-cn.com/tag/tree/)、[动态规划]() | Medium | DP实现未想到 | | #103 | [二叉树的锯齿形层次遍历](https://leetcode-cn.com/problems/binary-tree-zigzag-level-order-traversal/) | [ZigzagLevelOrder](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_103_zigzagLevelOrder.java) | [栈](https://leetcode-cn.com/tag/stack/)、[树](https://leetcode-cn.com/tag/tree/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Medium | | | #104 | [二叉树的最大深度](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/) | [MaxDepth](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_104_maxDepth.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | From 92a7abb71c9a5a281700fefd2c0b21c9d9636c06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 25 Jul 2019 14:06:49 +0800 Subject: [PATCH 110/308] feat(MEDIUM): add _98_isValidBST --- .../arithmetic/leetcode/_98_isValidBST.java | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_98_isValidBST.java diff --git a/src/pp/arithmetic/leetcode/_98_isValidBST.java b/src/pp/arithmetic/leetcode/_98_isValidBST.java new file mode 100644 index 0000000..e975f4e --- /dev/null +++ b/src/pp/arithmetic/leetcode/_98_isValidBST.java @@ -0,0 +1,83 @@ +package pp.arithmetic.leetcode; + +import javafx.util.Pair; +import pp.arithmetic.model.TreeNode; + +/** + * Created by wangpeng on 2019-07-24. + * 98. 验证二叉搜索树 + *

+ * 给定一个二叉树,判断其是否是一个有效的二叉搜索树。 + *

+ * 假设一个二叉搜索树具有如下特征: + *

+ * 节点的左子树只包含小于当前节点的数。 + * 节点的右子树只包含大于当前节点的数。 + * 所有左子树和右子树自身必须也是二叉搜索树。 + * 示例 1: + *

+ * 输入: + * 2 + * / \ + * 1 3 + * 输出: true + * 示例 2: + *

+ * 输入: + * 5 + * / \ + * 1 4 + *   / \ + *   3 6 + * 输出: false + * 解释: 输入为: [5,1,4,null,null,3,6]。 + *   根节点的值为 5 ,但是其右子节点值为 4 。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/validate-binary-search-tree + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _98_isValidBST { + + public static void main(String[] args) { + TreeNode treeNode = new TreeNode(2); + treeNode.left = new TreeNode(1); + treeNode.right = new TreeNode(3); + _98_isValidBST isValidBST = new _98_isValidBST(); + System.out.println(isValidBST.isValidBST(treeNode)); + TreeNode treeNode1 = new TreeNode(5); + treeNode1.left = new TreeNode(1); + treeNode1.right = new TreeNode(4); + treeNode1.right.left = new TreeNode(3); + treeNode1.right.right = new TreeNode(6); + System.out.println(isValidBST.isValidBST(treeNode1)); + //[10,5,15,null,null,6,20] + TreeNode treeNode2 = new TreeNode(10); + treeNode2.left = new TreeNode(5); + treeNode2.left.right = new TreeNode(15); +// treeNode2.left.right = new TreeNode(6); +// treeNode2.right = new TreeNode(20); + System.out.println(isValidBST.isValidBST(treeNode2)); + } + + /** + * 解题思路: + * 树的解题思路:递归 + * 1.左子树满足条件 + * 2.右子树满足条件 + * 3.自己满足条件(大于左子树max,跟小于又子树min) + * + * @param root + * @return + */ + public boolean isValidBST(TreeNode root) { + return valid(root, Integer.MIN_VALUE, Integer.MAX_VALUE); + } + + private boolean valid(TreeNode root, int min, int max) { + if (root == null) return true; + if (root.val <= min || root.val >= max) return false; + return valid(root.left, min, root.val) && valid(root.right, root.val, max); + } + +} From 760d7d36d6a094d1d3ef7507e7f2c64fb63224b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 25 Jul 2019 14:11:08 +0800 Subject: [PATCH 111/308] docs: add _98_isValidBST --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 082eb4b..c75994e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成184道 +- leetcode练习,坚持每天一道,目前已完成185道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -25,7 +25,7 @@ - [x] [94. 二叉树的中序遍历 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_94_inorderTraversal.java) -- [ ] [98. 验证二叉搜索树 -Medium](https://leetcode-cn.com/problems/validate-binary-search-tree/) +- [x] [98. 验证二叉搜索树 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_98_isValidBST.java) - [ ] [101. 对称二叉树 -Easy](https://leetcode-cn.com/problems/symmetric-tree/) @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成184) +### 题目列表(更新中--已完成185) -[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_94_inorderTraversal.java) +[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_98_isValidBST.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -151,6 +151,7 @@ | #93 | [复原IP地址](https://leetcode-cn.com/problems/restore-ip-addresses/) | [RestoreIpAddresses](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_93_restoreIpAddresses.java) | [字符串]()、[回溯算法]() | Medium | | | #94 | [二叉树的中序遍历](https://leetcode-cn.com/problems/binary-tree-inorder-traversal/) | [InorderTraversal](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_94_inorderTraversal.java) | [栈](https://leetcode-cn.com/tag/stack/)、[树](https://leetcode-cn.com/tag/tree/)、[哈希表]() | Medium | | | #95 | [不同的二叉搜索树 II](https://leetcode-cn.com/problems/unique-binary-search-trees-ii/) | [GenerateTrees](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_95_generateTrees.java) | [树](https://leetcode-cn.com/tag/tree/)、[动态规划]() | Medium | DP实现未想到 | +| #98 | [验证二叉搜索树](https://leetcode-cn.com/problems/validate-binary-search-tree/) | [IsValidBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_98_isValidBST.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #103 | [二叉树的锯齿形层次遍历](https://leetcode-cn.com/problems/binary-tree-zigzag-level-order-traversal/) | [ZigzagLevelOrder](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_103_zigzagLevelOrder.java) | [栈](https://leetcode-cn.com/tag/stack/)、[树](https://leetcode-cn.com/tag/tree/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Medium | | | #104 | [二叉树的最大深度](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/) | [MaxDepth](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_104_maxDepth.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | | #108 | [将有序数组转换为二叉搜索树](https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/) | [SortedArrayToBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_108_sortedArrayToBST.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | From 718afbb6cba42deea2173e4812da63d66d2a5b45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 26 Jul 2019 10:57:40 +0800 Subject: [PATCH 112/308] feat(EASY): add _101_isSymmetric --- .../arithmetic/leetcode/_101_isSymmetric.java | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_101_isSymmetric.java diff --git a/src/pp/arithmetic/leetcode/_101_isSymmetric.java b/src/pp/arithmetic/leetcode/_101_isSymmetric.java new file mode 100644 index 0000000..5e92734 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_101_isSymmetric.java @@ -0,0 +1,133 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.model.TreeNode; + +import java.util.Stack; + +/** + * Created by wangpeng on 2019-07-26. + * 101. 对称二叉树 + *

+ * 给定一个二叉树,检查它是否是镜像对称的。 + *

+ * 例如,二叉树 [1,2,2,3,4,4,3] 是对称的。 + *

+ * 1 + * / \ + * 2 2 + * / \ / \ + * 3 4 4 3 + * 但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的: + *

+ * 1 + * / \ + * 2 2 + * \ \ + * 3 3 + * 说明: + *

+ * 如果你可以运用递归和迭代两种方法解决这个问题,会很加分。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/symmetric-tree + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _101_isSymmetric { + + public static void main(String[] args) { + _101_isSymmetric isSymmetric = new _101_isSymmetric(); + //UT1 + TreeNode treeNode = new TreeNode(1); + treeNode.left = new TreeNode(2); + treeNode.right = new TreeNode(2); + treeNode.left.left = new TreeNode(3); + treeNode.left.right = new TreeNode(4); + treeNode.right.left = new TreeNode(4); + treeNode.right.right = new TreeNode(3); + System.out.println(isSymmetric.isSymmetric(treeNode)); + System.out.println(isSymmetric.isSymmetric2(treeNode)); + //UT2 + TreeNode treeNode1 = new TreeNode(1); + treeNode1.left = new TreeNode(2); + treeNode1.right = new TreeNode(2); + treeNode1.left.right = new TreeNode(3); + treeNode1.right.right = new TreeNode(3); + System.out.println(isSymmetric.isSymmetric(treeNode1)); + System.out.println(isSymmetric.isSymmetric2(treeNode1)); + } + + /** + * 解题思路: + * 树的两种方法:递归和迭代 + *

+ * 递归: + * 1.左子树是镜像对称 + * 2.右子树是镜像对称 + * 3.自己是镜像对称 + * 选择递归入参:左子树,右子树,条件:左子树value==右子树value, + * 需要注意因为是镜像,所以递归的时候左右子树取相对的left和right + *

+ * 迭代解法:{@link _101_isSymmetric#isSymmetric2(TreeNode)} + * + * @param root + * @return + */ + public boolean isSymmetric(TreeNode root) { + if (root == null) return true; + return isEqual(root.left, root.right); + } + + private boolean isEqual(TreeNode left, TreeNode right) { + if (left == null && right == null) return true; + if (left == null || right == null) return false; + //左 + boolean leftEqual = isEqual(left.left, right.right); + //右 + boolean rightEqual = isEqual(left.right, right.left); + //自己 + boolean selfEqual = left.val == right.val; + return leftEqual && rightEqual && selfEqual; + } + + /** + * 迭代: + * 通过栈保存遍历结果 + * + * @param root + * @return + */ + public boolean isSymmetric2(TreeNode root) { + if (root == null) return true; + Stack leftStack = new Stack<>(); + Stack rightStack = new Stack<>(); + TreeNode left = root.left; + TreeNode right = root.right; + + while (true) { + //左 + while (left != null && right != null) { + leftStack.add(left); + rightStack.add(right); + left = left.left; + right = right.right; + } + if (left != null || right != null) { + return false; + } + if (leftStack.isEmpty() && rightStack.isEmpty()) { + break; + } + //自己 + TreeNode leftPop = leftStack.pop(); + TreeNode rightPop = rightStack.pop(); + if (leftPop.val != rightPop.val) { + return false; + } + //右 + left = leftPop.right; + right = rightPop.left; + } + + return true; + } +} From 8dd4670938c8a8b3911c5f67da84031f7e9b89de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 26 Jul 2019 11:00:00 +0800 Subject: [PATCH 113/308] docs: add _101_isSymmetric --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c75994e..582c61a 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成185道 +- leetcode练习,坚持每天一道,目前已完成186道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -27,7 +27,7 @@ - [x] [98. 验证二叉搜索树 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_98_isValidBST.java) -- [ ] [101. 对称二叉树 -Easy](https://leetcode-cn.com/problems/symmetric-tree/) +- [x] [101. 对称二叉树 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_101_isSymmetric.java) ## 已解题目 @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成185) +### 题目列表(更新中--已完成186) -[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_98_isValidBST.java) +[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_101_isSymmetric.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -152,6 +152,7 @@ | #94 | [二叉树的中序遍历](https://leetcode-cn.com/problems/binary-tree-inorder-traversal/) | [InorderTraversal](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_94_inorderTraversal.java) | [栈](https://leetcode-cn.com/tag/stack/)、[树](https://leetcode-cn.com/tag/tree/)、[哈希表]() | Medium | | | #95 | [不同的二叉搜索树 II](https://leetcode-cn.com/problems/unique-binary-search-trees-ii/) | [GenerateTrees](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_95_generateTrees.java) | [树](https://leetcode-cn.com/tag/tree/)、[动态规划]() | Medium | DP实现未想到 | | #98 | [验证二叉搜索树](https://leetcode-cn.com/problems/validate-binary-search-tree/) | [IsValidBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_98_isValidBST.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | +| #101 | [对称二叉树](https://leetcode-cn.com/problems/symmetric-tree/) | [IsSymmetric](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_101_isSymmetric.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Easy | | | #103 | [二叉树的锯齿形层次遍历](https://leetcode-cn.com/problems/binary-tree-zigzag-level-order-traversal/) | [ZigzagLevelOrder](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_103_zigzagLevelOrder.java) | [栈](https://leetcode-cn.com/tag/stack/)、[树](https://leetcode-cn.com/tag/tree/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Medium | | | #104 | [二叉树的最大深度](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/) | [MaxDepth](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_104_maxDepth.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | | #108 | [将有序数组转换为二叉搜索树](https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/) | [SortedArrayToBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_108_sortedArrayToBST.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | From c8b40436181d065dcbce9bf5f2b80674bf145106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 26 Jul 2019 11:07:01 +0800 Subject: [PATCH 114/308] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E9=A2=98?= =?UTF-8?q?=E7=9B=AE=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 582c61a..72691f5 100644 --- a/README.md +++ b/README.md @@ -15,19 +15,19 @@ 扫题:热题 Hot 100 -- [x] [75. 颜色分类 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_75_sortColors.java) +- [ ] [102. 二叉树的层次遍历](https://leetcode-cn.com/problems/binary-tree-level-order-traversal/) -- [x] [79. 单词搜索 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_79_exist.java) +- [ ] [105. 从前序与中序遍历序列构造二叉树](https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) -- [x] [84. 柱状图中最大的矩形 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_84_largestRectangleArea.java) +- [ ] [124. 二叉树中的最大路径和](https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/) -- [x] [85. 最大矩形 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_85_maximalRectangle.java) +- [ ] [136. 只出现一次的数字](https://leetcode-cn.com/problems/single-number/) -- [x] [94. 二叉树的中序遍历 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_94_inorderTraversal.java) +- [ ] [169. 求众数](https://leetcode-cn.com/problems/majority-element/) -- [x] [98. 验证二叉搜索树 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_98_isValidBST.java) +- [ ] [226. 翻转二叉树](https://leetcode-cn.com/problems/invert-binary-tree/) -- [x] [101. 对称二叉树 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_101_isSymmetric.java) +- [ ] [238. 除自身以外数组的乘积](https://leetcode-cn.com/problems/product-of-array-except-self/) ## 已解题目 From 0676903d8ee0a501a92956d409b58e8ce08b917c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Sat, 27 Jul 2019 10:57:21 +0800 Subject: [PATCH 115/308] feat(MEDIUM): add _102_levelOrder --- .../arithmetic/leetcode/_102_levelOrder.java | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_102_levelOrder.java diff --git a/src/pp/arithmetic/leetcode/_102_levelOrder.java b/src/pp/arithmetic/leetcode/_102_levelOrder.java new file mode 100644 index 0000000..13f0972 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_102_levelOrder.java @@ -0,0 +1,85 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; +import pp.arithmetic.model.TreeNode; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; + +/** + * Created by wangpeng on 2019-07-27. + * 102. 二叉树的层次遍历 + *

+ * 给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。 + *

+ * 例如: + * 给定二叉树: [3,9,20,null,null,15,7], + *

+ * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * 返回其层次遍历结果: + *

+ * [ + * [3], + * [9,20], + * [15,7] + * ] + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _102_levelOrder { + + public static void main(String[] args) { + _102_levelOrder levelOrder = new _102_levelOrder(); + List> lists = levelOrder.levelOrder(Util.generateTreeNode()); + for (int i = 0; i < lists.size(); i++) { + Util.printList(lists.get(i)); + } + } + + /** + * 解题思路: + * 按层次遍历,类似于BFS,用一个队列保存遍历结果 + * 1.将(根)节点存入队列 + * 2.将队列中数据取空 + * 3.将取出的treeNode的左右子树存入队列并将结果存入结果集 + * 4.重复1-3直到队列无数据 + * + * @param root + * @return + */ + public List> levelOrder(TreeNode root) { + List> result = new ArrayList<>(); + if (root == null) return result; + Queue queue = new ArrayDeque<>(); + //1 + queue.add(root); + //4 + while (!queue.isEmpty()) { + List list = new ArrayList<>(); + //2 + while (!queue.isEmpty()) { + list.add(queue.poll()); + } + //3 + if (list.size() > 0) { + List addList = new ArrayList<>(); + for (int i = 0; i < list.size(); i++) { + TreeNode treeNode = list.get(i); + addList.add(treeNode.val); + if (treeNode.left != null) queue.add(treeNode.left); + if (treeNode.right != null) queue.add(treeNode.right); + } + result.add(addList); + } + } + return result; + } +} From d8248182228cfd93ea8e0deb0b16ec4793b8d77b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Sat, 27 Jul 2019 10:59:19 +0800 Subject: [PATCH 116/308] docs: add _102_levelOrder --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 72691f5..d11bdd4 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成186道 +- leetcode练习,坚持每天一道,目前已完成187道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -15,7 +15,7 @@ 扫题:热题 Hot 100 -- [ ] [102. 二叉树的层次遍历](https://leetcode-cn.com/problems/binary-tree-level-order-traversal/) +- [x] [102. 二叉树的层次遍历](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_102_levelOrder.java) - [ ] [105. 从前序与中序遍历序列构造二叉树](https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成186) +### 题目列表(更新中--已完成187) -[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_101_isSymmetric.java) +[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_102_levelOrder.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -153,6 +153,7 @@ | #95 | [不同的二叉搜索树 II](https://leetcode-cn.com/problems/unique-binary-search-trees-ii/) | [GenerateTrees](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_95_generateTrees.java) | [树](https://leetcode-cn.com/tag/tree/)、[动态规划]() | Medium | DP实现未想到 | | #98 | [验证二叉搜索树](https://leetcode-cn.com/problems/validate-binary-search-tree/) | [IsValidBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_98_isValidBST.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #101 | [对称二叉树](https://leetcode-cn.com/problems/symmetric-tree/) | [IsSymmetric](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_101_isSymmetric.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Easy | | +| #102 | [二叉树的层次遍历](https://leetcode-cn.com/problems/binary-tree-level-order-traversal/) | [LevelOrder](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_102_levelOrder.java) | [树](https://leetcode-cn.com/tag/tree/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Medium | | | #103 | [二叉树的锯齿形层次遍历](https://leetcode-cn.com/problems/binary-tree-zigzag-level-order-traversal/) | [ZigzagLevelOrder](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_103_zigzagLevelOrder.java) | [栈](https://leetcode-cn.com/tag/stack/)、[树](https://leetcode-cn.com/tag/tree/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Medium | | | #104 | [二叉树的最大深度](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/) | [MaxDepth](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_104_maxDepth.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | | #108 | [将有序数组转换为二叉搜索树](https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/) | [SortedArrayToBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_108_sortedArrayToBST.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | From 0e7b990290d702294e01628d91e36b20d461b0c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Sat, 27 Jul 2019 11:08:48 +0800 Subject: [PATCH 117/308] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=5F102=5Fleve?= =?UTF-8?q?lOrder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../arithmetic/leetcode/_102_levelOrder.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/pp/arithmetic/leetcode/_102_levelOrder.java b/src/pp/arithmetic/leetcode/_102_levelOrder.java index 13f0972..db889e1 100644 --- a/src/pp/arithmetic/leetcode/_102_levelOrder.java +++ b/src/pp/arithmetic/leetcode/_102_levelOrder.java @@ -42,6 +42,10 @@ public static void main(String[] args) { for (int i = 0; i < lists.size(); i++) { Util.printList(lists.get(i)); } + List> lists2 = levelOrder.levelOrder2(Util.generateTreeNode()); + for (int i = 0; i < lists2.size(); i++) { + Util.printList(lists2.get(i)); + } } /** @@ -52,6 +56,9 @@ public static void main(String[] args) { * 3.将取出的treeNode的左右子树存入队列并将结果存入结果集 * 4.重复1-3直到队列无数据 * + * 优化:可以把2-3合并成一步,你会咋弄? + * 优化方案{@link _102_levelOrder#levelOrder2(TreeNode)} + * * @param root * @return */ @@ -82,4 +89,32 @@ public List> levelOrder(TreeNode root) { } return result; } + + /** + * 优化:将2-3合并 + * + * @param root + * @return + */ + public List> levelOrder2(TreeNode root) { + List> result = new ArrayList<>(); + if (root == null) return result; + Queue queue = new ArrayDeque<>(); + //1 + queue.add(root); + //4 + while (!queue.isEmpty()) { + List addList = new ArrayList<>(); + //2-3 + int depth = queue.size(); + for (int i = 0; i < depth; i++) { + TreeNode treeNode = queue.poll(); + addList.add(treeNode.val); + if (treeNode.left != null) queue.add(treeNode.left); + if (treeNode.right != null) queue.add(treeNode.right); + } + if (addList.size() > 0) result.add(addList); + } + return result; + } } From 594fcc15124b80dd5274312844ef7fbcc888115f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 29 Jul 2019 11:45:33 +0800 Subject: [PATCH 118/308] feat(MEDIUM): add _105_buildTree --- .../arithmetic/leetcode/_105_buildTree.java | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_105_buildTree.java diff --git a/src/pp/arithmetic/leetcode/_105_buildTree.java b/src/pp/arithmetic/leetcode/_105_buildTree.java new file mode 100644 index 0000000..79c7bc1 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_105_buildTree.java @@ -0,0 +1,126 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; +import pp.arithmetic.model.TreeNode; + +import java.util.Arrays; + +/** + * Created by wangpeng on 2019-07-27. + * 105. 从前序与中序遍历序列构造二叉树 + *

+ * 根据一棵树的前序遍历与中序遍历构造二叉树。 + *

+ * 注意: + * 你可以假设树中没有重复的元素。 + *

+ * 例如,给出 + *

+ * 前序遍历 preorder = [3,9,20,15,7] + * 中序遍历 inorder = [9,3,15,20,7] + * 返回如下的二叉树: + *

+ * 3 + * / \ + * 9 20 + * / \ + * 15 7 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _105_buildTree { + + public static void main(String[] args) { + _105_buildTree buildTree = new _105_buildTree(); + Util.printTree(buildTree.buildTree1(new int[]{3, 9, 20, 15, 7}, new int[]{9, 3, 15, 20, 7})); + //优化方案 + Util.printTree(buildTree.buildTree(new int[]{1, 2, 3}, new int[]{3, 2, 1})); + Util.printTree(buildTree.buildTree(new int[]{3, 9, 20, 15, 7}, new int[]{9, 3, 15, 20, 7})); + } + + /** + * 解题思路: + * 1.确定根节点,前序的首位就是根节点 + * 2.确定根节点的左子树和右子树,找到中序根节点之前的就是左子树,之后的就是右子树 + * 3.将左子树和右子树的前序和中序传递到buildTree中,递归1-2步骤 + *

+ * 执行耗时 + * 执行用时 :48 ms, 在所有 Java 提交中击败了9.05%的用户 + * 内存消耗 :77.6 MB, 在所有 Java 提交中击败了5.07%的用户 + *

+ * 优化:提交时间耗时有点长,感觉问题出在数组拷贝下,将数组拷贝改为传递下标试试 + * {@link _105_buildTree#buildTree(int[], int[])} + * + * @param preorder + * @param inorder + * @return + */ + public TreeNode buildTree1(int[] preorder, int[] inorder) { + if (preorder.length == 0) return null; + //1 + TreeNode root = new TreeNode(preorder[0]); + if (preorder.length == 1) return root; + //2 + int leftIndex; + for (leftIndex = 0; leftIndex < inorder.length; leftIndex++) { + if (inorder[leftIndex] == preorder[0]) { + break; + } + } + //3 + TreeNode leftNode = buildTree1(Arrays.copyOfRange(preorder, 1, leftIndex + 1), Arrays.copyOfRange(inorder, 0, leftIndex)); + TreeNode rightNode = buildTree1(Arrays.copyOfRange(preorder, leftIndex + 1, preorder.length), Arrays.copyOfRange(inorder, leftIndex + 1, inorder.length)); + root.left = leftNode; + root.right = rightNode; + return root; + } + + /** + * 优化方案:避免数组的拷贝 + * + * 执行用时 :3 ms, 在所有 Java 提交中击败了99.12%的用户 + * 内存消耗 :37.5 MB, 在所有 Java 提交中击败了70.21%的用户 + * + * @param preorder + * @param inorder + * @return + */ + public TreeNode buildTree(int[] preorder, int[] inorder) { + return buildTree(preorder.length, preorder, 0, inorder, 0); + } + + // 从前序和中序构造二叉树,前序和中序是大数组中的一段[start, start + count) + private TreeNode buildTree(int count, int[] preOrder, int preStart, int[] inOrder, int inStart) { + if (count <= 0) return null; + + int rootValue = preOrder[preStart]; + TreeNode root = new TreeNode(rootValue); + + // 从inorder中找到root值,(inorder)左边就是左子树,(inorder)右边就是右子树 + // 然后在preorder中,数出与inorder中相同的个数即可 + int pos = inStart + count - 1; + for (; pos >= inStart; --pos) { + if (inOrder[pos] == rootValue) { + break; + } + } + int leftCount = pos - inStart; + int rightCount = inStart + count - pos - 1; + + if (leftCount > 0) { + int leftInStart = inStart; + int leftPreStart = preStart + 1; + root.left = buildTree(leftCount, preOrder, leftPreStart, inOrder, leftInStart); + } + + if (rightCount > 0) { + int rightInStart = pos + 1; + int rightPreStart = preStart + 1 + leftCount; + root.right = buildTree(rightCount, preOrder, rightPreStart, inOrder, rightInStart); + } + + return root; + } +} From 55ed1a1d8b8b2a2ba26191fcac9587f172ae8469 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 29 Jul 2019 11:50:47 +0800 Subject: [PATCH 119/308] docs: add _105_buildTree --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d11bdd4..98c4fa5 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成187道 +- leetcode练习,坚持每天一道,目前已完成188道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -17,7 +17,7 @@ - [x] [102. 二叉树的层次遍历](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_102_levelOrder.java) -- [ ] [105. 从前序与中序遍历序列构造二叉树](https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) +- [x] [105. 从前序与中序遍历序列构造二叉树](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_105_buildTree.java) - [ ] [124. 二叉树中的最大路径和](https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/) @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成187) +### 题目列表(更新中--已完成188) -[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_102_levelOrder.java) +[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_105_buildTree.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -156,6 +156,7 @@ | #102 | [二叉树的层次遍历](https://leetcode-cn.com/problems/binary-tree-level-order-traversal/) | [LevelOrder](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_102_levelOrder.java) | [树](https://leetcode-cn.com/tag/tree/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Medium | | | #103 | [二叉树的锯齿形层次遍历](https://leetcode-cn.com/problems/binary-tree-zigzag-level-order-traversal/) | [ZigzagLevelOrder](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_103_zigzagLevelOrder.java) | [栈](https://leetcode-cn.com/tag/stack/)、[树](https://leetcode-cn.com/tag/tree/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Medium | | | #104 | [二叉树的最大深度](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/) | [MaxDepth](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_104_maxDepth.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | +| #105 | [从前序与中序遍历序列构造二叉树](https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) | [BuildTree](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_105_buildTree.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/)、[数组]() | Medium | | | #108 | [将有序数组转换为二叉搜索树](https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/) | [SortedArrayToBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_108_sortedArrayToBST.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | | #113 | [路径总和 II](https://leetcode-cn.com/problems/path-sum-ii/) | [PathSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_113_pathSum.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #114 | [二叉树展开为链表](https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/) | [Flatten](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_114_flatten.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | From 946f17d810dd71d3331c54e48f52e1ec9f848100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 30 Jul 2019 17:33:50 +0800 Subject: [PATCH 120/308] feat(HARD): add _124_maxPathSum --- .../arithmetic/leetcode/_124_maxPathSum.java | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_124_maxPathSum.java diff --git a/src/pp/arithmetic/leetcode/_124_maxPathSum.java b/src/pp/arithmetic/leetcode/_124_maxPathSum.java new file mode 100644 index 0000000..db4f098 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_124_maxPathSum.java @@ -0,0 +1,99 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; +import pp.arithmetic.model.TreeNode; + +/** + * Created by wangpeng on 2019-07-30. + * 124. 二叉树中的最大路径和 + *

+ * 给定一个非空二叉树,返回其最大路径和。 + *

+ * 本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。 + *

+ * 示例 1: + *

+ * 输入: [1,2,3] + *

+ * 1 + * / \ + * 2 3 + *

+ * 输出: 6 + * 示例 2: + *

+ *

+ * 输入: [-10,9,20,null,null,15,7] + *

+ *   -10 + *    / \ + *   9  20 + *     /  \ + *    15   7 + *

+ * 输出: 42 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/binary-tree-maximum-path-sum + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _124_maxPathSum { + + public static void main(String[] args) { + _124_maxPathSum maxPathSum = new _124_maxPathSum(); + TreeNode root = new TreeNode(2); + root.left = new TreeNode(1); + root.right = new TreeNode(3); + System.out.println(maxPathSum.maxPathSum(root)); + TreeNode root1 = new TreeNode(-10); + root1.left = new TreeNode(9); + root1.right = new TreeNode(20); + root1.right.left = new TreeNode(15); + root1.right.right = new TreeNode(7); + System.out.println(maxPathSum.maxPathSum(root1)); + System.out.println(maxPathSum.maxPathSum(new TreeNode(-3))); + System.out.println(maxPathSum.maxPathSum(Util.generateTreeNode())); + //[2,-1] + TreeNode root2 = new TreeNode(2); + root2.left = new TreeNode(-1); + System.out.println(maxPathSum.maxPathSum(root2)); + } + + private int maxPath = Integer.MIN_VALUE; + + /** + * 解题思路: + * 树的解题离不开递归遍历 + * 1.寻找左子树的最大路径和(负数抛弃) + * 2.寻找右子树的最大路径和(负数抛弃) + * 3.如根节点是整数(含0),合并左右子树中的正数(负数不要),比较已存在得最大值 + * 4.返回结果是根节点、根节点+左子树、根节点+右子树的最大值 + *

+ * 注意: + * 1.因为求的是连续路径,如果子树的最大值中根节点未参数计算,不应该加入子树父节点的计算 + * 2.可能存在左、右子树都是可以用的,但是路径不能走回头路,只能返回左右子树和根节点的最大值 + * + * @param root + * @return + */ + public int maxPathSum(TreeNode root) { + maxPath = Integer.MIN_VALUE; + dfs(root); + return maxPath; + } + + private int dfs(TreeNode root) { + if (root == null) return 0; + //1 + int leftMax = dfs(root.left); + //2 + int rightMax = dfs(root.right); + //3 + int max = root.val; + if (leftMax > 0) max += leftMax; + if (rightMax > 0) max += rightMax; + maxPath = Math.max(maxPath, max); + //4 + return Math.max(root.val, Math.max(root.val + leftMax, root.val + rightMax)); + } +} From 9aea0d2d28d50fde2fb7fa6d0dbab3a92c78db89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 30 Jul 2019 17:37:50 +0800 Subject: [PATCH 121/308] docs: add _124_maxPathSum --- README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 98c4fa5..0682586 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成188道 +- leetcode练习,坚持每天一道,目前已完成189道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -15,11 +15,11 @@ 扫题:热题 Hot 100 -- [x] [102. 二叉树的层次遍历](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_102_levelOrder.java) +- [x] [102. 二叉树的层次遍历 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_102_levelOrder.java) -- [x] [105. 从前序与中序遍历序列构造二叉树](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_105_buildTree.java) +- [x] [105. 从前序与中序遍历序列构造二叉树 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_105_buildTree.java) -- [ ] [124. 二叉树中的最大路径和](https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/) +- [x] [124. 二叉树中的最大路径和 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_124_maxPathSum.java) - [ ] [136. 只出现一次的数字](https://leetcode-cn.com/problems/single-number/) @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成188) +### 题目列表(更新中--已完成189) -[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_105_buildTree.java) +[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_124_maxPathSum.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -164,6 +164,7 @@ | #121 | [买卖股票的最佳时机](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/) | [MaxProfit](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_121_maxProfit.java) | [数组]()、[动态规划]() | Easy | | | #122 | [买卖股票的最佳时机 II](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/) | [MaxProfit](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_122_maxProfit.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Easy | | | #123 | [买卖股票的最佳时机 III](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/) | [MaxProfit](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_123_maxProfit.java) | [数组]()、[动态规划]() | Hard | | +| #124 | [二叉树中的最大路径和](https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/) | [MaxPathSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_124_maxPathSum.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Hard | | | #125 | [验证回文串](https://leetcode-cn.com/problems/valid-palindrome/) | //待提交 | [双指针]()、[字符串]() | Easy | | | #126 | [单词接龙 II](https://leetcode-cn.com/problems/word-ladder-ii/) | [FindLadders](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_126_findLadders.java) | [BFS](https://leetcode-cn.com/tag/breadth-first-search/)、[数组]()、[字符串]()、[回溯算法]() | Hard | | | #127 | [单词接龙](https://leetcode-cn.com/problems/word-ladder/) | [LadderLength](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_127_ladderLength_2.java) | [BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Medium | [自己原始解法](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_127_ladderLength.java) | From 9ab81badff9624e1dc71c189703f41f8e5cceca4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 31 Jul 2019 10:29:30 +0800 Subject: [PATCH 122/308] feat(EASY): add _136_singleNumber --- .../leetcode/_136_singleNumber.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_136_singleNumber.java diff --git a/src/pp/arithmetic/leetcode/_136_singleNumber.java b/src/pp/arithmetic/leetcode/_136_singleNumber.java new file mode 100644 index 0000000..70150f0 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_136_singleNumber.java @@ -0,0 +1,57 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-07-30. + * 136. 只出现一次的数字 + * + * 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。 + * + * 说明: + * + * 你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗? + * + * 示例 1: + * + * 输入: [2,2,1] + * 输出: 1 + * 示例 2: + * + * 输入: [4,1,2,1,2] + * 输出: 4 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/single-number + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _136_singleNumber { + public static void main(String[] args) { + _136_singleNumber singleNumber = new _136_singleNumber(); + System.out.println(singleNumber.singleNumber(new int[]{2, 2, 1})); + System.out.println(singleNumber.singleNumber(new int[]{4, 1, 2, 1, 2})); + } + + /** + * 思考: + * 线性的时间复杂度就是O(n),不适用额外空间也就是最好常量级空间也不要有 + * O(n)的复杂度只允许遍历数组一次,一次遍历如何标识数字出现的次数?不能用额外空间就只能用数组本身进行存储 + * 是不是可以建立数字在数组中位置的映射关系? + * + * 解题思路: + * 映射关系最常见的就是哈希表,比如数字对数组长度取模,但是可能会发生冲突(两个数组取模结果一致),需解决,处理复杂==>放弃 + * 看了提示说位运算,思考了下的确可以,判断只出现一次,其他都出现两次,正好可以使用异或运算,两次结果复原,出现一次的数据停留在bit上 + * 1.取bit=0 + * 2.循环遍历数组,与bit做异或操作 + * 3.将最终的bit返回 + * + * + * @param nums + * @return + */ + public int singleNumber(int[] nums) { + int bit = 0; + for (int i = 0; i < nums.length; i++) { + bit = bit ^ nums[i]; + } + return bit; + } +} From 42205fc0c113c6b421299cb6b0bd7e7025715234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 31 Jul 2019 10:34:39 +0800 Subject: [PATCH 123/308] docs: add _136_singleNumber --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0682586..885138b 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成189道 +- leetcode练习,坚持每天一道,目前已完成190道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -21,7 +21,7 @@ - [x] [124. 二叉树中的最大路径和 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_124_maxPathSum.java) -- [ ] [136. 只出现一次的数字](https://leetcode-cn.com/problems/single-number/) +- [x] [136. 只出现一次的数字](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_136_singleNumber.java) - [ ] [169. 求众数](https://leetcode-cn.com/problems/majority-element/) @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成189) +### 题目列表(更新中--已完成190) -[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_124_maxPathSum.java) +[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_136_singleNumber.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -169,6 +169,7 @@ | #126 | [单词接龙 II](https://leetcode-cn.com/problems/word-ladder-ii/) | [FindLadders](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_126_findLadders.java) | [BFS](https://leetcode-cn.com/tag/breadth-first-search/)、[数组]()、[字符串]()、[回溯算法]() | Hard | | | #127 | [单词接龙](https://leetcode-cn.com/problems/word-ladder/) | [LadderLength](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_127_ladderLength_2.java) | [BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Medium | [自己原始解法](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_127_ladderLength.java) | | #128 | [最长连续序列](https://leetcode-cn.com/problems/longest-consecutive-sequence/) | [LongestConsecutive](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_128_longestConsecutive.java) | [并查集](https://leetcode-cn.com/tag/union-find/)、[数组]() | Hard | | +| #136 | [只出现一次的数字](https://leetcode-cn.com/problems/single-number/) | [SingleNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_136_singleNumber.java) | [哈希表]()、[位运算](https://leetcode-cn.com/tag/bit-manipulation/) | Easy | 位运算了解下 | | #138 | [复制带随机指针的链表](https://leetcode-cn.com/problems/copy-list-with-random-pointer/) | [CopyRandomList](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_138_CopyRandomList.java) | [哈希表]()、[链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | | #139 | [单词拆分](https://leetcode-cn.com/problems/word-break/) | [WordBreak](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_139_wordBreak.java) | [动态规划]() | Medium | 回溯实现耗时 | | #141 | [环形链表](https://leetcode-cn.com/problems/linked-list-cycle/) | [HasCycle](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_141_HasCycle.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Easy | | From c47dbc07d6e1032e15fffa155b0ec72cfb81da1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 1 Aug 2019 13:54:25 +0800 Subject: [PATCH 124/308] feat(EASY): add _169_majorityElement --- .../leetcode/_169_majorityElement.java | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_169_majorityElement.java diff --git a/src/pp/arithmetic/leetcode/_169_majorityElement.java b/src/pp/arithmetic/leetcode/_169_majorityElement.java new file mode 100644 index 0000000..a916b50 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_169_majorityElement.java @@ -0,0 +1,87 @@ +package pp.arithmetic.leetcode; + +import java.util.HashMap; + +/** + * Created by wangpeng on 2019-08-01. + * 169. 求众数 + *

+ * 给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。 + *

+ * 你可以假设数组是非空的,并且给定的数组总是存在众数。 + *

+ * 示例 1: + *

+ * 输入: [3,2,3] + * 输出: 3 + * 示例 2: + *

+ * 输入: [2,2,1,1,1,2,2] + * 输出: 2 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/majority-element + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _169_majorityElement { + public static void main(String[] args) { + _169_majorityElement majorityElement = new _169_majorityElement(); + System.out.println(majorityElement.majorityElement(new int[]{3, 2, 3})); + System.out.println(majorityElement.majorityElement(new int[]{2, 2, 1, 1, 1, 2, 2})); + } + + /** + * 解题思路: + * 如题所示,总是存在众数,所以是不是找出出现次数最大的数即可 + * 利用一个HashMap存储遍历的结果树,最终找到最大值 + *

+ * 提交结果: + * 执行用时 :33 ms, 在所有 Java 提交中击败了25.67%的用户 + * 内存消耗 :50 MB, 在所有 Java 提交中击败了29.52%的用户 + *

+ * 时间复杂度O(n),hashmap的扩容需要时间,有性能消耗 + * 优化方案 + * + * @param nums + * @return + */ + public int majorityElement(int[] nums) { + HashMap map = new HashMap<>(); + int maxCount = Integer.MIN_VALUE; + int maxValue = 0; + for (int i = 0; i < nums.length; i++) { + int item = nums[i]; + Integer count = map.getOrDefault(item, 0); + map.put(item, ++count); + if (count > maxCount) { + maxCount = count; + maxValue = item; + } + } + return maxValue; + } + + /** + * 优化方案:减少HashMap的扩容消耗 + * 官方说明:投票法Boyer-Moore + * + * @param nums + * @return + */ + public int majorityElement2(int[] nums) { + int result = nums[0]; + int count = 1; + for (int i = 1; i < nums.length; i++) { + if (count == 0) { + //因为众数个数>n/2,所以最后的result一定是众数 + result = nums[i]; + count++; + } else if (result == nums[i]) { + count++; + } else { + count--; + } + } + return result; + } +} From b26a5591c8bf82484df5f1520f57d294e0c00781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 1 Aug 2019 13:57:57 +0800 Subject: [PATCH 125/308] docs: add _169_majorityElement --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 885138b..18df724 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成190道 +- leetcode练习,坚持每天一道,目前已完成191道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -21,9 +21,9 @@ - [x] [124. 二叉树中的最大路径和 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_124_maxPathSum.java) -- [x] [136. 只出现一次的数字](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_136_singleNumber.java) +- [x] [136. 只出现一次的数字 -EASY](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_136_singleNumber.java) -- [ ] [169. 求众数](https://leetcode-cn.com/problems/majority-element/) +- [x] [169. 求众数 -EASY](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_169_majorityElement.java) - [ ] [226. 翻转二叉树](https://leetcode-cn.com/problems/invert-binary-tree/) @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成190) +### 题目列表(更新中--已完成191) -[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_136_singleNumber.java) +[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_169_majorityElement.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -182,6 +182,7 @@ | #155 | [最小栈](https://leetcode-cn.com/problems/min-stack/) | [MinStack](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_155_MinStack.java) | [栈](https://leetcode-cn.com/tag/stack/)、[设计](https://leetcode-cn.com/tag/design/) | Easy | | | #160 | [相交链表](https://leetcode-cn.com/problems/intersection-of-two-linked-lists/) | [GetIntersectionNode](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_160_GetIntersectionNode.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Easy | | | #167 | [两数之和 II - 输入有序数组](https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/) | [TwoSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_167_twoSum.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]()、[二分查找]() | Easy | | +| #169 | [求众数](https://leetcode-cn.com/problems/majority-element/) | [MajorityElement](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_169_majorityElement.java) | [位运算](https://leetcode-cn.com/tag/bit-manipulation/)、[数组]()、[分治算法]() | Easy | | | #174 | [地下城游戏](https://leetcode-cn.com/problems/dungeon-game/) | [CalculateMinimumHP](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_174_calculateMinimumHP.java) | [二分查找]()、[动态规划]() | Hard | | | #187 | [重复的DNA序列](https://leetcode-cn.com/problems/repeated-dna-sequences/) | [FindRepeatedDnaSequences](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_187_findRepeatedDnaSequences.java) | [位运算](https://leetcode-cn.com/tag/bit-manipulation/)、[哈希表]() | Medium | | | #188 | [买卖股票的最佳时机 IV](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv/) | [MaxProfit](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_188_maxProfit.java) | [动态规划]() | Hard | | From 1df0ff04e23e362b85ab19cee262f628264d1f3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 2 Aug 2019 10:06:09 +0800 Subject: [PATCH 126/308] feat(EASY): add _226_invertTree --- .../arithmetic/leetcode/_226_invertTree.java | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_226_invertTree.java diff --git a/src/pp/arithmetic/leetcode/_226_invertTree.java b/src/pp/arithmetic/leetcode/_226_invertTree.java new file mode 100644 index 0000000..78f2071 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_226_invertTree.java @@ -0,0 +1,69 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; +import pp.arithmetic.model.TreeNode; + +/** + * Created by wangpeng on 2019-08-02. + * 226. 翻转二叉树 + * + * 翻转一棵二叉树。 + * + * 示例: + * + * 输入: + * + * 4 + * / \ + * 2 7 + * / \ / \ + * 1 3 6 9 + * 输出: + * + * 4 + * / \ + * 7 2 + * / \ / \ + * 9 6 3 1 + * 备注: + * 这个问题是受到 Max Howell 的 原问题 启发的 : + * + * 谷歌:我们90%的工程师使用您编写的软件(Homebrew),但是您却无法在面试时在白板上写出翻转二叉树这道题,这太糟糕了。 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/invert-binary-tree + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _226_invertTree { + + public static void main(String[] args) { + _226_invertTree invertTree = new _226_invertTree(); + TreeNode treeNode = Util.generateTreeNode(); + Util.printTree(treeNode); + TreeNode treeNode1 = invertTree.invertTree(treeNode); + Util.printTree(treeNode1); + } + + /** + * 解题思路: + * 树的经典解题:左、右、自己,递归遍历,拿到翻转后的左右子树,将root的左右子树坐下替换 + * 1.翻转左子树 + * 2.翻转右子树 + * 3.替换root的左右子树(翻转后) + * + * + * @param root + * @return + */ + public TreeNode invertTree(TreeNode root) { + if (root ==null) return null; + //1 + TreeNode left = invertTree(root.left); + //2 + TreeNode right = invertTree(root.right); + //3 + root.left = right; + root.right = left; + return root; + } +} From 704e6183c64be131342a421c1a8044ee5fbca04f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 2 Aug 2019 10:09:49 +0800 Subject: [PATCH 127/308] docs: add _226_invertTree --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 18df724..b6c7dcb 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成191道 +- leetcode练习,坚持每天一道,目前已完成192道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -25,7 +25,7 @@ - [x] [169. 求众数 -EASY](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_169_majorityElement.java) -- [ ] [226. 翻转二叉树](https://leetcode-cn.com/problems/invert-binary-tree/) +- [x] [226. 翻转二叉树-EASY](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_226_invertTree.java) - [ ] [238. 除自身以外数组的乘积](https://leetcode-cn.com/problems/product-of-array-except-self/) @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成191) +### 题目列表(更新中--已完成192) -[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_169_majorityElement.java) +[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_226_invertTree.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -200,6 +200,7 @@ | #215 | [数组中的第K个最大元素](https://leetcode-cn.com/problems/kth-largest-element-in-an-array/) | [FindKthLargest](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_215_findKthLargest_2.java) | [堆](https://leetcode-cn.com/tag/heap/)、[分治算法]() | Medium | | | #221 | [最大正方形](https://leetcode-cn.com/problems/maximal-square/) | [MaximalSquare](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_221_maximalSquare.java) | [动态规划]() | Medium | | | #225 | [用队列实现栈](https://leetcode-cn.com/problems/implement-stack-using-queues/) | [MyStack](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_225_MyStack.java) | [栈](https://leetcode-cn.com/tag/stack/)、[设计](https://leetcode-cn.com/tag/design/) | Easy | | +| #226 | [翻转二叉树](https://leetcode-cn.com/problems/invert-binary-tree/) | [InvertTree](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_226_invertTree.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | 经典,要能手写 | | #232 | [用栈实现队列](https://leetcode-cn.com/problems/implement-queue-using-stacks/) | [MyQuene](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_232_MyQuene.java) | 栈](https://leetcode-cn.com/tag/stack/)、[设计](https://leetcode-cn.com/tag/design/) | Easy | | | #234 | [回文链表](https://leetcode-cn.com/problems/palindrome-linked-list/) | [IsPalindrome](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_234_isPalindrome.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Easy | | | #236 | [二叉树的最近公共祖先](https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/) | [LowestCommonAncestor](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_236_lowestCommonAncestor.java) | [树](https://leetcode-cn.com/tag/tree/) | Medium | | From d29b0de1731b727c78f13bfb7a33eb0d8ff2277b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Sat, 3 Aug 2019 11:01:35 +0800 Subject: [PATCH 128/308] feat(MEDIUM): add _238_productExceptSelf --- .../leetcode/_238_productExceptSelf.java | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_238_productExceptSelf.java diff --git a/src/pp/arithmetic/leetcode/_238_productExceptSelf.java b/src/pp/arithmetic/leetcode/_238_productExceptSelf.java new file mode 100644 index 0000000..09dbd24 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_238_productExceptSelf.java @@ -0,0 +1,108 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +/** + * Created by wangpeng on 2019-08-02. + * 238. 除自身以外数组的乘积 + *

+ * 给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。 + *

+ * 示例: + *

+ * 输入: [1,2,3,4] + * 输出: [24,12,8,6] + * 说明: 请不要使用除法,且在 O(n) 时间复杂度内完成此题。 + *

+ * 进阶: + * 你可以在常数空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组不被视为额外空间。) + *

+ *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/product-of-array-except-self + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _238_productExceptSelf { + + public static void main(String[] args) { + _238_productExceptSelf productExceptSelf = new _238_productExceptSelf(); + Util.printArray(productExceptSelf.productExceptSelf(new int[]{0, 0})); + Util.printArray(productExceptSelf.productExceptSelf(new int[]{1, 0})); + Util.printArray(productExceptSelf.productExceptSelf(new int[]{0, 1, 2, 3, 4})); + } + + /** + * 解题思路: + * 1.遍历数组,将所有的数进行乘积,得到最大的乘积 + * 2.再次遍历数组,将最大的乘积除以遍历item,得到除自身以外的乘积 + *

+ * 注意: + * 1.如item为0,要跳过处理,不能乘和除 + * 2.如果数组中有0,则非0的数字结果都是0,如0的个数>1,则所有数字结果都是0 + *

+ * 执行用时 :4 ms, 在所有 Java 提交中击败了30.79%的用户 + * 内存消耗 :51.7 MB, 在所有 Java 提交中击败了22.40%的用户 + *

+ * 解题过程略复杂,他人优秀解法{@link _238_productExceptSelf#productExceptSelf2(int[])} + * + * @param nums + * @return + */ + public int[] productExceptSelf(int[] nums) { + int[] retNums = new int[nums.length]; + int max = 0; + int zoreCount = 0; + //1 + for (int i = 0; i < nums.length; i++) { + int item = nums[i]; + if (item != 0) { + if (max == 0) max = 1; + max *= item; + } else { + zoreCount++; + } + } + //2 + for (int i = 0; i < nums.length; i++) { + int item = nums[i]; + if (item != 0) { + if (zoreCount > 0) { + retNums[i] = 0; + } else { + retNums[i] = max / item; + } + } else { + if (zoreCount > 1) { + retNums[i] = 0; + } else { + retNums[i] = max; + } + } + } + + return retNums; + } + + /** + * 他人解题思路,借鉴下 + * 乘积 = 当前数左边的乘积 * 当前数右边的乘积 + * 有一些分治的思想 + * + * @param nums + * @return + */ + public int[] productExceptSelf2(int[] nums) { + int[] res = new int[nums.length]; + int k = 1; + for (int i = 0; i < res.length; i++) { + res[i] = k; + k = k * nums[i]; // 此时数组存储的是除去当前元素左边的元素乘积 + } + k = 1; + for (int i = res.length - 1; i >= 0; i--) { + res[i] *= k; // k为该数右边的乘积。 + k *= nums[i]; // 此时数组等于左边的 * 该数右边的。 + } + return res; + } +} From 12a8034ad25670382d4b783320b87c483c1e4eb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Sat, 3 Aug 2019 11:07:02 +0800 Subject: [PATCH 129/308] docs: add _238_productExceptSelf --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b6c7dcb..bb01239 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成192道 +- leetcode练习,坚持每天一道,目前已完成193道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -27,7 +27,7 @@ - [x] [226. 翻转二叉树-EASY](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_226_invertTree.java) -- [ ] [238. 除自身以外数组的乘积](https://leetcode-cn.com/problems/product-of-array-except-self/) +- [x] [238. 除自身以外数组的乘积](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_238_productExceptSelf.java) ## 已解题目 @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成192) +### 题目列表(更新中--已完成193) -[Leetcode-Java(更多题解,持续更新)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_226_invertTree.java) +[Leetcode-Java(更多题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_238_productExceptSelf.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -201,10 +201,11 @@ | #221 | [最大正方形](https://leetcode-cn.com/problems/maximal-square/) | [MaximalSquare](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_221_maximalSquare.java) | [动态规划]() | Medium | | | #225 | [用队列实现栈](https://leetcode-cn.com/problems/implement-stack-using-queues/) | [MyStack](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_225_MyStack.java) | [栈](https://leetcode-cn.com/tag/stack/)、[设计](https://leetcode-cn.com/tag/design/) | Easy | | | #226 | [翻转二叉树](https://leetcode-cn.com/problems/invert-binary-tree/) | [InvertTree](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_226_invertTree.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | 经典,要能手写 | -| #232 | [用栈实现队列](https://leetcode-cn.com/problems/implement-queue-using-stacks/) | [MyQuene](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_232_MyQuene.java) | 栈](https://leetcode-cn.com/tag/stack/)、[设计](https://leetcode-cn.com/tag/design/) | Easy | | +| #232 | [用栈实现队列](https://leetcode-cn.com/problems/implement-queue-using-stacks/) | [MyQuene](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_232_MyQuene.java) | [栈](https://leetcode-cn.com/tag/stack/)、[设计](https://leetcode-cn.com/tag/design/) | Easy | | | #234 | [回文链表](https://leetcode-cn.com/problems/palindrome-linked-list/) | [IsPalindrome](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_234_isPalindrome.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Easy | | | #236 | [二叉树的最近公共祖先](https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/) | [LowestCommonAncestor](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_236_lowestCommonAncestor.java) | [树](https://leetcode-cn.com/tag/tree/) | Medium | | | #237 | [删除链表中的节点](https://leetcode-cn.com/problems/delete-node-in-a-linked-list/) | [DeleteNode](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_237_deleteNode.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Easy | | +| #238 | [除自身以外数组的乘积](https://leetcode-cn.com/problems/product-of-array-except-self/) | [ProductExceptSelf](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_238_productExceptSelf.java) | [数组]() | Medium | | | #239 | [滑动窗口最大值](https://leetcode-cn.com/problems/sliding-window-maximum/) | [MaxSlidingWindow](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_239_maxSlidingWindow.java) | [堆](https://leetcode-cn.com/tag/heap/)、[sliding window]() | Hard | | | #264 | [丑数 II](https://leetcode-cn.com/problems/ugly-number-ii/) | [NthUglyNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_264_nthUglyNumber.java) | [堆](https://leetcode-cn.com/tag/heap/)、[数学]()、[动态规划]() | Medium | | | #279 | [完全平方数](https://leetcode-cn.com/problems/perfect-squares/) | [NumSquares](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_279_numSquares.java) | [BFS](https://leetcode-cn.com/tag/breadth-first-search/)、[数学]()、[动态规划]() | Medium | | From bf2fec815380d5bd32958c2a5b4c6144dea2e381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Sat, 3 Aug 2019 11:09:48 +0800 Subject: [PATCH 130/308] docs: update code list --- README.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index bb01239..4642d1a 100644 --- a/README.md +++ b/README.md @@ -15,19 +15,17 @@ 扫题:热题 Hot 100 -- [x] [102. 二叉树的层次遍历 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_102_levelOrder.java) +- [ ] [240. 搜索二维矩阵 II -Medium](https://leetcode-cn.com/problems/search-a-2d-matrix-ii/) -- [x] [105. 从前序与中序遍历序列构造二叉树 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_105_buildTree.java) +- [ ] [283. 移动零 -Easy](https://leetcode-cn.com/problems/move-zeroes/) -- [x] [124. 二叉树中的最大路径和 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_124_maxPathSum.java) +- [ ] [287. 寻找重复数 - Medium](https://leetcode-cn.com/problems/find-the-duplicate-number/) -- [x] [136. 只出现一次的数字 -EASY](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_136_singleNumber.java) +- [ ] [297. 二叉树的序列化与反序列化 -Hard](https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/) -- [x] [169. 求众数 -EASY](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_169_majorityElement.java) +- [ ] [301. 删除无效的括号 -Hard](https://leetcode-cn.com/problems/remove-invalid-parentheses/) -- [x] [226. 翻转二叉树-EASY](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_226_invertTree.java) - -- [x] [238. 除自身以外数组的乘积](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_238_productExceptSelf.java) +- [ ] [312. 戳气球 - Hard](https://leetcode-cn.com/problems/burst-balloons/) ## 已解题目 From 81b87839478e2cf0e8490cc87368355a5bb377ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 5 Aug 2019 12:49:33 +0800 Subject: [PATCH 131/308] feat(MEDIUM): add _240_searchMatrix --- .../leetcode/_240_searchMatrix.java | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_240_searchMatrix.java diff --git a/src/pp/arithmetic/leetcode/_240_searchMatrix.java b/src/pp/arithmetic/leetcode/_240_searchMatrix.java new file mode 100644 index 0000000..83ade15 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_240_searchMatrix.java @@ -0,0 +1,124 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-08-05. + * 240. 搜索二维矩阵 II + *

+ * 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性: + *

+ * 每行的元素从左到右升序排列。 + * 每列的元素从上到下升序排列。 + * 示例: + *

+ * 现有矩阵 matrix 如下: + *

+ * [ + * [1, 4, 7, 11, 15], + * [2, 5, 8, 12, 19], + * [3, 6, 9, 16, 22], + * [10, 13, 14, 17, 24], + * [18, 21, 23, 26, 30] + * ] + * 给定 target = 5,返回 true。 + *

+ * 给定 target = 20,返回 false。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/search-a-2d-matrix-ii + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _240_searchMatrix { + + public static void main(String[] args) { + _240_searchMatrix searchMatrix = new _240_searchMatrix(); + int[][] matrix = new int[][]{ + {1, 4, 7, 11, 15}, + {2, 5, 8, 12, 19}, + {3, 6, 9, 16, 22}, + {10, 13, 14, 17, 24}, + {18, 21, 23, 26, 30} + }; + //初始题解 + System.out.println(searchMatrix.searchMatrix(matrix, 5)); + System.out.println(searchMatrix.searchMatrix(matrix, 20)); + System.out.println(searchMatrix.searchMatrix(matrix, 18)); + System.out.println(searchMatrix.searchMatrix(matrix, 19)); + //更优题解 + System.out.println(searchMatrix.searchMatrix2(matrix, 5)); + } + + /** + * 解题思路: + * 最简单的解法就是全遍历一遍矩阵,时间复杂度O(m*n),肯定不是题目中所说的高效算法 + * 看看能不能减少一些不必要的遍历,观察矩阵是有规则的:从左到右和从上到下都是递增的 + * 1.斜脚线遍历Matrix,如果taget==遍历项,则直接返回 + * 2.如果target>遍历项,则继续遍历下一个斜脚线 + * 3.如果target<遍历项,则结果在其左子矩阵和右上子矩阵中,将子矩阵循环1-3 + *

+ * 执行用时 :19 ms, 在所有 Java 提交中击败了16.82%的用户 + * 内存消耗 :51.2 MB, 在所有 Java 提交中击败了42.79%的用户 + * 耗时思考: + * + * @param matrix + * @param target + * @return + */ + public boolean searchMatrix(int[][] matrix, int target) { + if (matrix.length == 0) return false; + return searchMatrix(matrix, target, 0, matrix.length, 0, matrix[0].length); + } + + private boolean searchMatrix(int[][] matrix, int target, int sx, int ex, int sy, int ey) { + if (sx == ex || sy == ey) return false; + int x = sx, y = sy; + while (x < ex && y < ey) { + if (target == matrix[x][y]) { + return true; + } + if (target > matrix[x][y]) { + x++; + y++; + } else { + return searchMatrix(matrix, target, sx, x, y, ey) || searchMatrix(matrix, target, x, ex, sy, y); + } + } + if (x == ex && y == ey) { + return false; + } + //matrix不一定是对称矩阵,可能会存在遗留项 + if (x < ex) { + return searchMatrix(matrix, target, x, ex, sy, ey); + } + if (y < ey) { + return searchMatrix(matrix, target, sx, ex, y, ey); + } + + return false; + } + + /** + * 时间复杂度O(m+n) + * + * @param matrix + * @param target + * @return + */ + public boolean searchMatrix2(int[][] matrix, int target) { + if (matrix == null || matrix.length == 0 || matrix[0] == null || matrix[0].length == 0) return false; + int row = matrix.length - 1; + int col = 0; + int count = 0; + while (row >= 0 && col < matrix[0].length) { + if (target < matrix[row][col]) row--; + else if (target > matrix[row][col]) col++; + else { + count++; + row--; + col++; + } + } + return count > 0; + + } + +} From 7b88fa9978c7402697cec404eaafbd12d24b3aa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 5 Aug 2019 12:51:43 +0800 Subject: [PATCH 132/308] docs: add _240_searchMatrix --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4642d1a..5c35048 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成193道 +- leetcode练习,坚持每天一道,目前已完成194道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -15,7 +15,7 @@ 扫题:热题 Hot 100 -- [ ] [240. 搜索二维矩阵 II -Medium](https://leetcode-cn.com/problems/search-a-2d-matrix-ii/) +- [x] [240. 搜索二维矩阵 II -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_240_searchMatrix.java) - [ ] [283. 移动零 -Easy](https://leetcode-cn.com/problems/move-zeroes/) @@ -60,9 +60,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成193) +### 题目列表(更新中--已完成194) -[Leetcode-Java(更多题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_238_productExceptSelf.java) +[Leetcode-Java(更多题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_240_searchMatrix.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -205,6 +205,7 @@ | #237 | [删除链表中的节点](https://leetcode-cn.com/problems/delete-node-in-a-linked-list/) | [DeleteNode](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_237_deleteNode.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Easy | | | #238 | [除自身以外数组的乘积](https://leetcode-cn.com/problems/product-of-array-except-self/) | [ProductExceptSelf](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_238_productExceptSelf.java) | [数组]() | Medium | | | #239 | [滑动窗口最大值](https://leetcode-cn.com/problems/sliding-window-maximum/) | [MaxSlidingWindow](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_239_maxSlidingWindow.java) | [堆](https://leetcode-cn.com/tag/heap/)、[sliding window]() | Hard | | +| #240 | [搜索二维矩阵 II](https://leetcode-cn.com/problems/search-a-2d-matrix-ii/) | [SearchMatrix](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_240_searchMatrix.java) | [数组]()、[二分查找]() | Medium | | | #264 | [丑数 II](https://leetcode-cn.com/problems/ugly-number-ii/) | [NthUglyNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_264_nthUglyNumber.java) | [堆](https://leetcode-cn.com/tag/heap/)、[数学]()、[动态规划]() | Medium | | | #279 | [完全平方数](https://leetcode-cn.com/problems/perfect-squares/) | [NumSquares](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_279_numSquares.java) | [BFS](https://leetcode-cn.com/tag/breadth-first-search/)、[数学]()、[动态规划]() | Medium | | | #290 | [单词模式](https://leetcode-cn.com/problems/word-pattern/) | [WordPattern](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_290_wordPattern.java) | [哈希表]() | Easy | | From a49584763b42b6ae4095e4a5be01bd3d889d01fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 7 Aug 2019 10:29:39 +0800 Subject: [PATCH 133/308] feat(EASY): add _283_moveZeroes --- .../arithmetic/leetcode/_283_moveZeroes.java | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_283_moveZeroes.java diff --git a/src/pp/arithmetic/leetcode/_283_moveZeroes.java b/src/pp/arithmetic/leetcode/_283_moveZeroes.java new file mode 100644 index 0000000..28e1016 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_283_moveZeroes.java @@ -0,0 +1,61 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +/** + * Created by wangpeng on 2019-08-07. + * 283. 移动零 + *

+ * 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 + *

+ * 示例: + *

+ * 输入: [0,1,0,3,12] + * 输出: [1,3,12,0,0] + * 说明: + *

+ * 必须在原数组上操作,不能拷贝额外的数组。 + * 尽量减少操作次数。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/move-zeroes + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _283_moveZeroes { + public static void main(String[] args) { + _283_moveZeroes moveZeroes = new _283_moveZeroes(); + int[] nums = {0, 1, 0, 3, 12}; + moveZeroes.moveZeroes(nums); + Util.printArray(nums); + } + + /** + * 解题思路: + * 1.遍历数组,找到第一个0并标记zeroIndex + * 2.找到下一个非0,将其与0交互,zeroIndex++ + * 3.找到下一个0,不做任何处理 + * + * @param nums + */ + public void moveZeroes(int[] nums) { + int zeroIndex = -1; + //1 + for (int i = 0; i < nums.length; i++) { + int num = nums[i]; + if (num == 0) { + //1 + if (zeroIndex == -1) { + zeroIndex = i; + } + //3 + } else { + //2 + if (zeroIndex != -1) { + nums[zeroIndex] = num; + nums[i] = 0; + zeroIndex++; + } + } + } + } +} From d9f077cb67c63a24472d42e3fc0f3d15b01dda84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 7 Aug 2019 10:34:02 +0800 Subject: [PATCH 134/308] docs: add _283_moveZeroes --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5c35048..935ffcb 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成194道 +- leetcode练习,坚持每天一道,目前已完成195道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -17,7 +17,7 @@ - [x] [240. 搜索二维矩阵 II -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_240_searchMatrix.java) -- [ ] [283. 移动零 -Easy](https://leetcode-cn.com/problems/move-zeroes/) +- [x] [283. 移动零 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_283_moveZeroes.java) - [ ] [287. 寻找重复数 - Medium](https://leetcode-cn.com/problems/find-the-duplicate-number/) @@ -60,9 +60,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成194) +### 题目列表(更新中--已完成195) -[Leetcode-Java(更多题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_240_searchMatrix.java) +[Leetcode-Java(更多题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_283_moveZeroes.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -208,6 +208,7 @@ | #240 | [搜索二维矩阵 II](https://leetcode-cn.com/problems/search-a-2d-matrix-ii/) | [SearchMatrix](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_240_searchMatrix.java) | [数组]()、[二分查找]() | Medium | | | #264 | [丑数 II](https://leetcode-cn.com/problems/ugly-number-ii/) | [NthUglyNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_264_nthUglyNumber.java) | [堆](https://leetcode-cn.com/tag/heap/)、[数学]()、[动态规划]() | Medium | | | #279 | [完全平方数](https://leetcode-cn.com/problems/perfect-squares/) | [NumSquares](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_279_numSquares.java) | [BFS](https://leetcode-cn.com/tag/breadth-first-search/)、[数学]()、[动态规划]() | Medium | | +| #283 | [移动零](https://leetcode-cn.com/problems/move-zeroes/) | [MoveZeroes](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_283_moveZeroes.java) | [数组]()、[双指针]() | Easy | | | #290 | [单词模式](https://leetcode-cn.com/problems/word-pattern/) | [WordPattern](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_290_wordPattern.java) | [哈希表]() | Easy | | | #300 | [最长上升子序列](https://leetcode-cn.com/problems/longest-increasing-subsequence/) | [LengthOfLIS](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_300_lengthOfLIS.java) | [二分查找]()、[动态规划]() | Medium | | | #303 | [区域和检索 - 数组不可变](https://leetcode-cn.com/problems/range-sum-query-immutable/) | [NumArray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_303_NumArray.java) | [动态规划]() | Easy | | From a7d5b7070f7888a5ccf106df14619ad4d155a23d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 15 Aug 2019 11:05:38 +0800 Subject: [PATCH 135/308] feat(MEDIUM): add _287_findDuplicate --- .../leetcode/_287_findDuplicate.java | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_287_findDuplicate.java diff --git a/src/pp/arithmetic/leetcode/_287_findDuplicate.java b/src/pp/arithmetic/leetcode/_287_findDuplicate.java new file mode 100644 index 0000000..42a2f87 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_287_findDuplicate.java @@ -0,0 +1,73 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-08-07. + * 287. 寻找重复数 + *

+ * 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。 + *

+ * 示例 1: + *

+ * 输入: [1,3,4,2,2] + * 输出: 2 + * 示例 2: + *

+ * 输入: [3,1,3,4,2] + * 输出: 3 + * 说明: + *

+ * 不能更改原数组(假设数组是只读的)。 + * 只能使用额外的 O(1) 的空间。 + * 时间复杂度小于 O(n^2) 。 + * 数组中只有一个重复的数字,但它可能不止重复出现一次。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/find-the-duplicate-number + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _287_findDuplicate { + + public static void main(String[] args) { + _287_findDuplicate findDuplicate = new _287_findDuplicate(); +// System.out.println(findDuplicate.findDuplicate(new int[]{1, 3, 4, 2, 2})); +// System.out.println(findDuplicate.findDuplicate(new int[]{3, 1, 3, 4, 2})); + System.out.println(findDuplicate.findDuplicate(new int[]{2, 5, 9, 6, 9, 3, 8, 9, 7, 1})); + } + + /** + * 题意解读: + * 1、数组只读==>不能对数组进行重排序==>排序取连续两个相同的 + * 2、O(1)空间==>不能用哈希等进行遍历存储==>哈希取出现次数>1的 + * 3、O(n^2)的时间复杂度==>少于2次循环遍历,可以一次循环或者二分 + * 如果没有上述限制,上面的方法都可行 + *

+ * 解题思路: + * 仔细看题目,发现数组大小n+1,数组数字1-n,一定会存在重复数字 + * 从0开始遍历,最开始一条直线,到后面会形成个环,可参考这张图 https://img-blog.csdn.net/20160101111128525 + * 从图中来看,环和直线相遇的点就是重复数 + * 1.用快慢指针,找到第一次相遇的点 + * 2.将一个指针移至起始点,再次相遇的一定是环和直线相遇的点,也就是重复数 + * + * @param nums + * @return + */ + public int findDuplicate(int[] nums) { + // 1.找到第一次相遇点 + int slow = nums[0]; + int fast = nums[0]; + do { + slow = nums[slow]; + fast = nums[nums[fast]]; + } while (slow != fast); + + // 2.找第二次相遇点 + int ptr1 = nums[0]; + int ptr2 = slow; + while (ptr1 != ptr2) { + ptr1 = nums[ptr1]; + ptr2 = nums[ptr2]; + } + + return ptr1; + } +} From 3620e93178befc68e2c93b33d54600fc41b0ed2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 15 Aug 2019 11:12:43 +0800 Subject: [PATCH 136/308] docs: add _287_findDuplicate --- README.md | 9 +++++---- src/pp/arithmetic/leetcode/_287_findDuplicate.java | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 935ffcb..2cf275c 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成195道 +- leetcode练习,坚持每天一道,目前已完成196道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -19,7 +19,7 @@ - [x] [283. 移动零 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_283_moveZeroes.java) -- [ ] [287. 寻找重复数 - Medium](https://leetcode-cn.com/problems/find-the-duplicate-number/) +- [x] [287. 寻找重复数 - Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_287_findDuplicate.java) - [ ] [297. 二叉树的序列化与反序列化 -Hard](https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/) @@ -60,9 +60,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成195) +### 题目列表(更新中--已完成196) -[Leetcode-Java(更多题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_283_moveZeroes.java) +[Leetcode-Java(更多题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_287_findDuplicate.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -209,6 +209,7 @@ | #264 | [丑数 II](https://leetcode-cn.com/problems/ugly-number-ii/) | [NthUglyNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_264_nthUglyNumber.java) | [堆](https://leetcode-cn.com/tag/heap/)、[数学]()、[动态规划]() | Medium | | | #279 | [完全平方数](https://leetcode-cn.com/problems/perfect-squares/) | [NumSquares](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_279_numSquares.java) | [BFS](https://leetcode-cn.com/tag/breadth-first-search/)、[数学]()、[动态规划]() | Medium | | | #283 | [移动零](https://leetcode-cn.com/problems/move-zeroes/) | [MoveZeroes](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_283_moveZeroes.java) | [数组]()、[双指针]() | Easy | | +| #287 | [寻找重复数](https://leetcode-cn.com/problems/find-the-duplicate-number/) | [FindDuplicate](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_287_findDuplicate.java) | [数组]()、[双指针]()、[二分查找]() | Medium | | | #290 | [单词模式](https://leetcode-cn.com/problems/word-pattern/) | [WordPattern](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_290_wordPattern.java) | [哈希表]() | Easy | | | #300 | [最长上升子序列](https://leetcode-cn.com/problems/longest-increasing-subsequence/) | [LengthOfLIS](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_300_lengthOfLIS.java) | [二分查找]()、[动态规划]() | Medium | | | #303 | [区域和检索 - 数组不可变](https://leetcode-cn.com/problems/range-sum-query-immutable/) | [NumArray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_303_NumArray.java) | [动态规划]() | Easy | | diff --git a/src/pp/arithmetic/leetcode/_287_findDuplicate.java b/src/pp/arithmetic/leetcode/_287_findDuplicate.java index 42a2f87..7be189f 100644 --- a/src/pp/arithmetic/leetcode/_287_findDuplicate.java +++ b/src/pp/arithmetic/leetcode/_287_findDuplicate.java @@ -48,6 +48,8 @@ public static void main(String[] args) { * 1.用快慢指针,找到第一次相遇的点 * 2.将一个指针移至起始点,再次相遇的一定是环和直线相遇的点,也就是重复数 * + * 计算详解:https://leetcode-cn.com/problems/find-the-duplicate-number/solution/287-xun-zhao-zhong-fu-shu-java-kuai-man-zhi-zhen-t/ + * * @param nums * @return */ From eab05b22015d9ef01025a091d9d2b9eeecc55f76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 16 Aug 2019 12:50:07 +0800 Subject: [PATCH 137/308] feat(HARD): add _297_Codec --- src/pp/arithmetic/leetcode/_297_Codec.java | 116 +++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_297_Codec.java diff --git a/src/pp/arithmetic/leetcode/_297_Codec.java b/src/pp/arithmetic/leetcode/_297_Codec.java new file mode 100644 index 0000000..9bfa71c --- /dev/null +++ b/src/pp/arithmetic/leetcode/_297_Codec.java @@ -0,0 +1,116 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; +import pp.arithmetic.model.TreeNode; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Created by wangpeng on 2019-08-16. + * 297. 二叉树的序列化与反序列化 + *

+ * 序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。 + *

+ * 请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。 + *

+ * 示例:  + *

+ * 你可以将以下二叉树: + *

+ * 1 + * / \ + * 2 3 + * / \ + * 4 5 + *

+ * 序列化为 "[1,2,3,null,null,4,5]" + * 提示: 这与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。 + *

+ * 说明: 不要使用类的成员 / 全局 / 静态变量来存储状态,你的序列化和反序列化算法应该是无状态的。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _297_Codec { + + public static void main(String[] args) { + _297_Codec codec = new _297_Codec(); + TreeNode root = new TreeNode(1); + root.left = new TreeNode(2); + root.right = new TreeNode(3); + root.right.left = new TreeNode(4); + root.right.right = new TreeNode(5); + String serialize = codec.serialize(root); + System.out.println(serialize); + TreeNode deserialize = codec.deserialize(serialize); + Util.printTree(deserialize); + } + + // Encodes a tree to a single string. + + /** + * 按层次遍历,序列化格式:1 2 3 null null 4 5 null null null null + * 借助队列实现树的BFS + * @param root + * @return + */ + public String serialize(TreeNode root) { + StringBuilder builder = new StringBuilder(); + Queue queue = new LinkedList<>(); + queue.add(root); + while (!queue.isEmpty()) { + TreeNode pop = queue.poll(); + builder.append(pop != null ? pop.val : null).append(" "); + if (pop != null) { + queue.add(pop.left); + queue.add(pop.right); + } + } + + return builder.toString(); + + } + + // Decodes your encoded data to tree. + + /** + * "1 2 3 null null 4 5 null null null null"遍历数组,使用BFS反序列化生成Tree + * @param data + * @return + */ + public TreeNode deserialize(String data) { + String[] split = data.split(" "); + if (split.length == 0) return null; + String top = split[0]; + if (top.equals("null")) { + return null; + } + TreeNode root = new TreeNode(toInt(top)); + Queue queue = new LinkedList<>(); + queue.add(root); + int index = 1; + while (!queue.isEmpty() && index < split.length) { + TreeNode poll = queue.poll(); + String left = split[index++]; + String right = split[index++]; + if (!left.equals("null")) { + TreeNode leftNode = new TreeNode(toInt(left)); + poll.left = leftNode; + queue.add(leftNode); + } + if (!right.equals("null")) { + TreeNode rightNode = new TreeNode(toInt(right)); + poll.right = rightNode; + queue.add(rightNode); + } + } + + return root; + } + + private int toInt(String str) { + return Integer.parseInt(str); + } +} From 2b8e54bf209d12d628c1048a1ee0b0bd498419ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 16 Aug 2019 12:55:22 +0800 Subject: [PATCH 138/308] docs: add _297_Codec --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2cf275c..36a23a7 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成196道 +- leetcode练习,坚持每天一道,目前已完成197道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -21,7 +21,7 @@ - [x] [287. 寻找重复数 - Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_287_findDuplicate.java) -- [ ] [297. 二叉树的序列化与反序列化 -Hard](https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/) +- [x] [297. 二叉树的序列化与反序列化 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_297_Codec.java) - [ ] [301. 删除无效的括号 -Hard](https://leetcode-cn.com/problems/remove-invalid-parentheses/) @@ -60,9 +60,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成196) +### 题目列表(更新中--已完成197) -[Leetcode-Java(更多题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_287_findDuplicate.java) +[Leetcode-Java(更多题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_297_Codec.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -211,6 +211,7 @@ | #283 | [移动零](https://leetcode-cn.com/problems/move-zeroes/) | [MoveZeroes](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_283_moveZeroes.java) | [数组]()、[双指针]() | Easy | | | #287 | [寻找重复数](https://leetcode-cn.com/problems/find-the-duplicate-number/) | [FindDuplicate](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_287_findDuplicate.java) | [数组]()、[双指针]()、[二分查找]() | Medium | | | #290 | [单词模式](https://leetcode-cn.com/problems/word-pattern/) | [WordPattern](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_290_wordPattern.java) | [哈希表]() | Easy | | +| #297 | [二叉树的序列化与反序列化](https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/) | [Codec](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_297_Codec.java) | [树](https://leetcode-cn.com/tag/tree/)、[设计](https://leetcode-cn.com/tag/design/) | Hard | | | #300 | [最长上升子序列](https://leetcode-cn.com/problems/longest-increasing-subsequence/) | [LengthOfLIS](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_300_lengthOfLIS.java) | [二分查找]()、[动态规划]() | Medium | | | #303 | [区域和检索 - 数组不可变](https://leetcode-cn.com/problems/range-sum-query-immutable/) | [NumArray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_303_NumArray.java) | [动态规划]() | Easy | | | #304 | [二维区域和检索 - 矩阵不可变](https://leetcode-cn.com/problems/range-sum-query-2d-immutable/) | [NumMatrix](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_304_NumMatrix.java) | [动态规划]() | Medium | | From 2c4300831d2db038a998ce6b78425906ab152cf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Sat, 17 Aug 2019 11:08:23 +0800 Subject: [PATCH 139/308] feat(HARD): add _301_removeInvalidParentheses --- .../_301_removeInvalidParentheses.java | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_301_removeInvalidParentheses.java diff --git a/src/pp/arithmetic/leetcode/_301_removeInvalidParentheses.java b/src/pp/arithmetic/leetcode/_301_removeInvalidParentheses.java new file mode 100644 index 0000000..4d26596 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_301_removeInvalidParentheses.java @@ -0,0 +1,124 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +import java.util.*; + +/** + * Created by wangpeng on 2019-08-17. + * 301. 删除无效的括号 + *

+ * 删除最小数量的无效括号,使得输入的字符串有效,返回所有可能的结果。 + *

+ * 说明: 输入可能包含了除 ( 和 ) 以外的字符。 + *

+ * 示例 1: + *

+ * 输入: "()())()" + * 输出: ["()()()", "(())()"] + * 示例 2: + *

+ * 输入: "(a)())()" + * 输出: ["(a)()()", "(a())()"] + * 示例 3: + *

+ * 输入: ")(" + * 输出: [""] + *

+ *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/remove-invalid-parentheses + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _301_removeInvalidParentheses { + + public static void main(String[] args) { + _301_removeInvalidParentheses removeInvalidParentheses = new _301_removeInvalidParentheses(); + List strings = removeInvalidParentheses.removeInvalidParentheses("(a)())()"); + Util.printStringList(strings); + } + + private Set validExpressions = new HashSet(); + + private void recurse( + String s, + int index, + int leftCount, + int rightCount, + int leftRem, + int rightRem, + StringBuilder expression) { + + // If we reached the end of the string, just check if the resulting expression is + // valid or not and also if we have removed the total number of left and right + // parentheses that we should have removed. + if (index == s.length()) { + if (leftRem == 0 && rightRem == 0) { + this.validExpressions.add(expression.toString()); + } + + } else { + char character = s.charAt(index); + int length = expression.length(); + + // The discard case. Note that here we have our pruning condition. + // We don't recurse if the remaining count for that parenthesis is == 0. + if ((character == '(' && leftRem > 0) || (character == ')' && rightRem > 0)) { + this.recurse( + s, + index + 1, + leftCount, + rightCount, + leftRem - (character == '(' ? 1 : 0), + rightRem - (character == ')' ? 1 : 0), + expression); + } + + expression.append(character); + + // Simply recurse one step further if the current character is not a parenthesis. + if (character != '(' && character != ')') { + + this.recurse(s, index + 1, leftCount, rightCount, leftRem, rightRem, expression); + + } else if (character == '(') { + + // Consider an opening bracket. + this.recurse(s, index + 1, leftCount + 1, rightCount, leftRem, rightRem, expression); + + } else if (rightCount < leftCount) { + + // Consider a closing bracket. + this.recurse(s, index + 1, leftCount, rightCount + 1, leftRem, rightRem, expression); + } + + // Delete for backtracking. + expression.deleteCharAt(length); + } + } + + public List removeInvalidParentheses(String s) { + + int left = 0, right = 0; + + // First, we find out the number of misplaced left and right parentheses. + for (int i = 0; i < s.length(); i++) { + + // Simply record the left one. + if (s.charAt(i) == '(') { + left++; + } else if (s.charAt(i) == ')') { + // If we don't have a matching left, then this is a misplaced right, record it. + right = left == 0 ? right + 1 : right; + + // Decrement count of left parentheses because we have found a right + // which CAN be a matching one for a left. + left = left > 0 ? left - 1 : left; + } + } + + this.recurse(s, 0, 0, 0, left, right, new StringBuilder()); + return new ArrayList(this.validExpressions); + } + +} From 1f37602a4ed60fe7ca27444029081e842b205c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Sat, 17 Aug 2019 11:12:43 +0800 Subject: [PATCH 140/308] docs: add _301_removeInvalidParentheses --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 36a23a7..28035ca 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成197道 +- leetcode练习,坚持每天一道,目前已完成198道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -23,7 +23,7 @@ - [x] [297. 二叉树的序列化与反序列化 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_297_Codec.java) -- [ ] [301. 删除无效的括号 -Hard](https://leetcode-cn.com/problems/remove-invalid-parentheses/) +- [x] [301. 删除无效的括号 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_301_removeInvalidParentheses.java) - [ ] [312. 戳气球 - Hard](https://leetcode-cn.com/problems/burst-balloons/) @@ -60,9 +60,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成197) +### 题目列表(更新中--已完成198) -[Leetcode-Java(更多题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_297_Codec.java) +[Leetcode-Java(更多题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_301_removeInvalidParentheses.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -213,6 +213,7 @@ | #290 | [单词模式](https://leetcode-cn.com/problems/word-pattern/) | [WordPattern](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_290_wordPattern.java) | [哈希表]() | Easy | | | #297 | [二叉树的序列化与反序列化](https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/) | [Codec](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_297_Codec.java) | [树](https://leetcode-cn.com/tag/tree/)、[设计](https://leetcode-cn.com/tag/design/) | Hard | | | #300 | [最长上升子序列](https://leetcode-cn.com/problems/longest-increasing-subsequence/) | [LengthOfLIS](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_300_lengthOfLIS.java) | [二分查找]()、[动态规划]() | Medium | | +| #301 | [删除无效的括号](https://leetcode-cn.com/problems/remove-invalid-parentheses/) | [RemoveInvalidParentheses](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_301_removeInvalidParentheses.java) | [BFS](https://leetcode-cn.com/tag/breadth-first-search/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Hard | | | #303 | [区域和检索 - 数组不可变](https://leetcode-cn.com/problems/range-sum-query-immutable/) | [NumArray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_303_NumArray.java) | [动态规划]() | Easy | | | #304 | [二维区域和检索 - 矩阵不可变](https://leetcode-cn.com/problems/range-sum-query-2d-immutable/) | [NumMatrix](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_304_NumMatrix.java) | [动态规划]() | Medium | | | #307 | [区域和检索 - 数组可修改](https://leetcode-cn.com/problems/range-sum-query-mutable/) | [NumArray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_307_NumArray_2.java) | [树状数组](https://leetcode-cn.com/tag/binary-indexed-tree/)、[线段树](https://leetcode-cn.com/tag/segment-tree/) | Medium | | From 723c63bc61d91374196c36c6519b307ba96536e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 20 Aug 2019 17:19:40 +0800 Subject: [PATCH 141/308] feat(HARD): add _312_maxCoins --- src/pp/arithmetic/leetcode/_312_maxCoins.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_312_maxCoins.java diff --git a/src/pp/arithmetic/leetcode/_312_maxCoins.java b/src/pp/arithmetic/leetcode/_312_maxCoins.java new file mode 100644 index 0000000..daa3a18 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_312_maxCoins.java @@ -0,0 +1,67 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-08-17. + * 312. 戳气球 + *

+ * 有 n 个气球,编号为0 到 n-1,每个气球上都标有一个数字,这些数字存在数组 nums 中。 + *

+ * 现在要求你戳破所有的气球。每当你戳破一个气球 i 时,你可以获得 nums[left] * nums[i] * nums[right] 个硬币。 这里的 left 和 right 代表和 i 相邻的两个气球的序号。注意当你戳破了气球 i 后,气球 left 和气球 right 就变成了相邻的气球。 + *

+ * 求所能获得硬币的最大数量。 + *

+ * 说明: + *

+ * 你可以假设 nums[-1] = nums[n] = 1,但注意它们不是真实存在的所以并不能被戳破。 + * 0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100 + * 示例: + *

+ * 输入: [3,1,5,8] + * 输出: 167 + * 解释: nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> [] + *   coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167 + *

+ *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/burst-balloons + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _312_maxCoins { + public static void main(String[] args) { + _312_maxCoins maxCoins = new _312_maxCoins(); + System.out.println(maxCoins.maxCoins(new int[]{3, 1, 5, 8})); + } + + /** + * 解题思路:如何使最终结果最大化?动态规划保存结果 + * 1.将问题拆解成求i->j的最大值,最大的i=0,j=n + * 2.从i->j中找一个k,拆分求解,i->k,k,k->j三个值之和的最大值 + * 3.i->k和k->j代表k的左边和右边全部戳破求解的最大值 + * 4.左右全部戳破后,k的值为num[i]*num[k]*num[j] + * 5.动态转移方程:dp[i][j]=Math.max(dp[i][j],dp[i][k]+dp[k][j]+num[i]*num[k]*num[j]); + * + * @param nums + * @return + */ + public int maxCoins(int[] nums) { + //dp[i][j]代表i->j的最大值 + int[][] dp = new int[nums.length + 2][nums.length + 2]; + //左右+1方便操作。 nums[-1] = nums[n] = 1 + int[] newNums = new int[nums.length + 2]; + for (int i = 1; i < newNums.length - 1; i++) { + newNums[i] = nums[i - 1]; + } + newNums[0] = 1; + newNums[newNums.length - 1] = 1; + //从2开始,保证最少3个 + for (int j = 2; j < newNums.length; j++) { + //遍历所有的可能性,0-2...0-n,1-3...1-n,... + for (int i = 0; i < newNums.length - j; i++) { + for (int k = i + 1; k < i + j; k++) { + dp[i][i + j] = Math.max(dp[i][i + j], dp[i][k] + dp[k][i + j] + newNums[i] * newNums[k] * newNums[i + j]); + } + } + } + return dp[0][newNums.length - 1]; + } +} From d0b67b214aeda5c4722561a0560d27a0945de4de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 20 Aug 2019 17:21:52 +0800 Subject: [PATCH 142/308] docs: add _312_maxCoins --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 28035ca..7aa3444 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成198道 +- leetcode练习,坚持每天一道,目前已完成199道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -25,7 +25,7 @@ - [x] [301. 删除无效的括号 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_301_removeInvalidParentheses.java) -- [ ] [312. 戳气球 - Hard](https://leetcode-cn.com/problems/burst-balloons/) +- [x] [312. 戳气球 - Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_312_maxCoins.java) ## 已解题目 @@ -60,9 +60,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成198) +### 题目列表(更新中--已完成199) -[Leetcode-Java(更多题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_301_removeInvalidParentheses.java) +[Leetcode-Java(更多题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_312_maxCoins.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -218,6 +218,7 @@ | #304 | [二维区域和检索 - 矩阵不可变](https://leetcode-cn.com/problems/range-sum-query-2d-immutable/) | [NumMatrix](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_304_NumMatrix.java) | [动态规划]() | Medium | | | #307 | [区域和检索 - 数组可修改](https://leetcode-cn.com/problems/range-sum-query-mutable/) | [NumArray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_307_NumArray_2.java) | [树状数组](https://leetcode-cn.com/tag/binary-indexed-tree/)、[线段树](https://leetcode-cn.com/tag/segment-tree/) | Medium | | | #309 | [最佳买卖股票时机含冷冻期](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) | [MaxProfit](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_309_maxProfit.java) | [动态规划]() | Medium | | +| #312 | [戳气球](https://leetcode-cn.com/problems/burst-balloons/) | [MaxCoins](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_312_maxCoins.java) | [分治算法]()、[动态规划]() | Hard | | | #315 | [计算右侧小于当前元素的个数](https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self/) | [CountSmaller](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_315_countSmaller_2.java) | [树状数组](https://leetcode-cn.com/tag/binary-indexed-tree/)、[线段树](https://leetcode-cn.com/tag/segment-tree/)、[二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)、[分治算法]() | Hard | | | #322 | [零钱兑换](https://leetcode-cn.com/problems/coin-change/) | [CoinChange](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_322_coinChange.java) | [动态规划]() | Medium | | | #328 | [奇偶链表](https://leetcode-cn.com/problems/odd-even-linked-list/) | [OddEvenList](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_328_OddEvenList.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | From 632b2217cc40cd22200118325900df4c60073a26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 20 Aug 2019 17:28:13 +0800 Subject: [PATCH 143/308] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E9=A2=98?= =?UTF-8?q?=E7=9B=AE=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 7aa3444..d88d3fa 100644 --- a/README.md +++ b/README.md @@ -15,17 +15,17 @@ 扫题:热题 Hot 100 -- [x] [240. 搜索二维矩阵 II -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_240_searchMatrix.java) +- [ ] [337. 打家劫舍 III -Medium](https://leetcode-cn.com/problems/house-robber-iii/) -- [x] [283. 移动零 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_283_moveZeroes.java) +- [ ] [347. 前 K 个高频元素 -Medium](https://leetcode-cn.com/problems/top-k-frequent-elements/) -- [x] [287. 寻找重复数 - Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_287_findDuplicate.java) +- [ ] [394. 字符串解码 -Medium](https://leetcode-cn.com/problems/decode-string/) -- [x] [297. 二叉树的序列化与反序列化 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_297_Codec.java) +- [ ] [399. 除法求值 -Medium](https://leetcode-cn.com/problems/evaluate-division/) -- [x] [301. 删除无效的括号 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_301_removeInvalidParentheses.java) +- [ ] [406. 根据身高重建队列 -Medium](https://leetcode-cn.com/problems/queue-reconstruction-by-height/) -- [x] [312. 戳气球 - Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_312_maxCoins.java) +- [ ] [416. 分割等和子集 -Medium](https://leetcode-cn.com/problems/partition-equal-subset-sum/) ## 已解题目 From 50438249de83acca52c2efa4570c5ecc96c22711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 21 Aug 2019 12:06:35 +0800 Subject: [PATCH 144/308] feat(MEDIUM): add _337_rob --- src/pp/arithmetic/leetcode/_337_rob.java | 94 ++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_337_rob.java diff --git a/src/pp/arithmetic/leetcode/_337_rob.java b/src/pp/arithmetic/leetcode/_337_rob.java new file mode 100644 index 0000000..ad585d2 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_337_rob.java @@ -0,0 +1,94 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.model.TreeNode; + +/** + * Created by wangpeng on 2019-08-21. + * 337. 打家劫舍 III + *

+ * 在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为“根”。 除了“根”之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警。 + * + * 计算在不触动警报的情况下,小偷一晚能够盗取的最高金额。 + * + * 示例 1: + * + * 输入: [3,2,3,null,3,null,1] + * + * 3 + * / \ + * 2 3 + * \ \ + * 3 1 + * + * 输出: 7 + * 解释: 小偷一晚能够盗取的最高金额 = 3 + 3 + 1 = 7. + * 示例 2: + * + * 输入: [3,4,5,1,3,null,1] + * + *   3 + * / \ + * 4 5 + * / \ \ + * 1 3 1 + * + * 输出: 9 + * 解释: 小偷一晚能够盗取的最高金额 = 4 + 5 = 9. + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/house-robber-iii + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _337_rob { + + public static void main(String[] args) { + _337_rob rob = new _337_rob(); + TreeNode treeNode = new TreeNode(3); + treeNode.left = new TreeNode(4); + treeNode.right = new TreeNode(5); + treeNode.left.left = new TreeNode(1); + treeNode.left.right = new TreeNode(3); + treeNode.right.right = new TreeNode(1); + System.out.println(rob.rob(treeNode)); + //[4,1,null,2,null,3] + TreeNode r1 = new TreeNode(4); + r1.left = new TreeNode(1); + r1.left.left = new TreeNode(2); + r1.left.left.left = new TreeNode(3); + System.out.println(rob.rob(r1)); + } + + /** + * 按题意,不能相连=根节点和左右子树选择只能二选一,每个节点都有选和不选,总共组合个数2^n次,全部循环明显不合适 + * 按经验,树的解题思路就是DFS递归 + * 1.求解左右子树的最大金额(左右子树需要求解2遍,选择了根节点和没有选择根节点的) + * 2.选择根节点的最大值max1=max(左)+max(右)+跟,没有选择根节点的最大值max2=max(左)+max(右) + * 3.比较max1和max2,求出最大值 + * + * @param root + * @return + */ + public int rob(TreeNode root) { + int[] max = doRob(root); + return Math.max(max[0], max[1]); + } + + /** + * 0代表不含根节点,1代表含根节点 + * + * @param root + * @return + */ + private int[] doRob(TreeNode root) { + int[] res = new int[2]; + if (root == null) + return res; + int[] left = doRob(root.left); + int[] right = doRob(root.right); + //不包含根节点,最大值为两个子树的最大值之和 + res[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]); + //包含根节点,最大值为两个子树不包含根节点的最大值加上根节点的值 + res[1] = left[0] + right[0] + root.val; + return res; + } +} From d37899c7fa3f7aef2fdd9d4c2f99198e587a9dea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 21 Aug 2019 12:46:21 +0800 Subject: [PATCH 145/308] docs: add _337_rob --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d88d3fa..cd4a1d8 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成199道 +- leetcode练习,坚持每天一道,目前已完成200道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -15,7 +15,7 @@ 扫题:热题 Hot 100 -- [ ] [337. 打家劫舍 III -Medium](https://leetcode-cn.com/problems/house-robber-iii/) +- [x] [337. 打家劫舍 III -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_337_rob.java) - [ ] [347. 前 K 个高频元素 -Medium](https://leetcode-cn.com/problems/top-k-frequent-elements/) @@ -60,9 +60,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中--已完成199) +### 题目列表(更新中—已完成200) -[Leetcode-Java(更多题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_312_maxCoins.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_337_rob.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -223,6 +223,7 @@ | #322 | [零钱兑换](https://leetcode-cn.com/problems/coin-change/) | [CoinChange](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_322_coinChange.java) | [动态规划]() | Medium | | | #328 | [奇偶链表](https://leetcode-cn.com/problems/odd-even-linked-list/) | [OddEvenList](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_328_OddEvenList.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | | #336 | [回文对](https://leetcode-cn.com/problems/palindrome-pairs/) | [PalindromePairs](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_336_palindromePairs_2.java) | [字典树](https://leetcode-cn.com/tag/trie/)、[哈希表]()、[字符串]() | Hard | | +| #337 | [打家劫舍 III](https://leetcode-cn.com/problems/house-robber-iii/) | [Rob](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_337_rob.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #338 | [比特位计数](https://leetcode-cn.com/problems/counting-bits/) | [CountBits](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_338_countBits.java) | [位运算](https://leetcode-cn.com/tag/bit-manipulation/)、[动态规划]() | Medium | | | #343 | [整数拆分](https://leetcode-cn.com/problems/integer-break/) | [IntegerBreak](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_343_integerBreak.java) | [数学]()、[动态规划]() | Medium | | | #354 | [俄罗斯套娃信封问题](https://leetcode-cn.com/problems/russian-doll-envelopes/) | [MaxEnvelopes.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_354_maxEnvelopes_2.java) | [二分查找]()、[动态规划]() | Hard | | From 2cce6f87d4933a4bfdc49cf155bda0cc0ef5b6c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 22 Aug 2019 15:15:25 +0800 Subject: [PATCH 146/308] feat(MEDIUM): add _347_topKFrequent --- .../leetcode/_347_topKFrequent.java | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_347_topKFrequent.java diff --git a/src/pp/arithmetic/leetcode/_347_topKFrequent.java b/src/pp/arithmetic/leetcode/_347_topKFrequent.java new file mode 100644 index 0000000..993b6c5 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_347_topKFrequent.java @@ -0,0 +1,124 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +import java.util.*; + +/** + * Created by wangpeng on 2019-08-22. + * 347. 前 K 个高频元素 + *

+ * 给定一个非空的整数数组,返回其中出现频率前 k 高的元素。 + *

+ * 示例 1: + *

+ * 输入: nums = [1,1,1,2,2,3], k = 2 + * 输出: [1,2] + * 示例 2: + *

+ * 输入: nums = [1], k = 1 + * 输出: [1] + * 说明: + *

+ * 你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。 + * 你的算法的时间复杂度必须优于 O(n log n) , n 是数组的大小。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/top-k-frequent-elements + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _347_topKFrequent { + + public static void main(String[] args) { + _347_topKFrequent topKFrequent = new _347_topKFrequent(); + Util.printList(topKFrequent.topKFrequent(new int[]{1, 2, 1, 2, 1, 4}, 2)); + Util.printList(topKFrequent.topKFrequent(new int[]{4, 1, -1, 2, -1, 2, 3}, 2)); + Util.printList(topKFrequent.topKFrequent1(new int[]{1, 2, 1, 2, 1, 4}, 2)); + Util.printList(topKFrequent.topKFrequent1(new int[]{4, 1, -1, 2, -1, 2, 3}, 2)); + } + + /** + * 解题思路: + * 1.遍历count使用HashMap进行保存 + * 2.从遍历的count中找到最K大的数字,此时使用了PriorityQueue进行保存,队列顶部就是最小的 + * 3.将PriorityQueue结果转换为List返回 + * + * 执行用时 :104 ms, 在所有 Java 提交中击败了16.20%的用户 + * 内存消耗 :45.8 MB, 在所有 Java 提交中击败了57.61%的用户 + * + * 时间复杂度O(NLogN) + * + * 更优解法:{@link _347_topKFrequent#topKFrequent1(int[], int)} + * + * @param nums + * @param k + * @return + */ + public List topKFrequent(int[] nums, int k) { + HashMap map = new HashMap<>(); + for (int n : nums) { + map.put(n, map.getOrDefault(n, 0) + 1); + } + + PriorityQueue heap = new PriorityQueue((n1, n2) -> map.get(n1) - map.get(n2)); + for (int n : map.keySet()) { + heap.add(n); + if (heap.size() > k) + heap.poll(); + } + List retList = new LinkedList(); + while (!heap.isEmpty()) + retList.add(heap.poll()); + Collections.reverse(retList); + return retList; + } + + + /** + * 更优解法,优化了建堆和排序的消耗 + * + * 执行用时 :28 ms, 在所有 Java 提交中击败了89.78%的用户 + * 内存消耗 :46.8 MB, 在所有 Java 提交中击败了41.99%的用户 + * + * 时间复杂度O(N) + * + * @param nums + * @param k + * @return + */ + public List topKFrequent1(int[] nums, int k) { + Map map = new HashMap<>(); + for (int i : nums) { + map.put(i, map.getOrDefault(i, 0) + 1); + } + + List[] count = new ArrayList[nums.length + 1]; + for (int key : map.keySet()) { + int freq = map.get(key); + if (count[freq] == null) { + count[freq] = new ArrayList<>(); + } + count[freq].add(key); + } + + List result = new ArrayList<>(k); + int remain = k; + + for (int i = nums.length; i > 0 && remain > 0; i--) { + if (count[i] != null) { + if (remain > count[i].size()) { + result.addAll(count[i]); + remain -= count[i].size(); + } else { + result.addAll(count[i].subList(0, remain)); + remain = 0; + } + } + } + + return result; + } + + +} + From ca6829bb3b5f6437be46b223bc626a5822a39c34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 22 Aug 2019 15:20:38 +0800 Subject: [PATCH 147/308] docs: add _347_topKFrequent --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cd4a1d8..4d78fd9 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成200道 +- leetcode练习,坚持每天一道,目前已完成201道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -17,7 +17,7 @@ - [x] [337. 打家劫舍 III -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_337_rob.java) -- [ ] [347. 前 K 个高频元素 -Medium](https://leetcode-cn.com/problems/top-k-frequent-elements/) +- [x] [347. 前 K 个高频元素 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_347_topKFrequent.java) - [ ] [394. 字符串解码 -Medium](https://leetcode-cn.com/problems/decode-string/) @@ -60,9 +60,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成200) +### 题目列表(更新中—已完成201) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_337_rob.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_347_topKFrequent.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -226,6 +226,7 @@ | #337 | [打家劫舍 III](https://leetcode-cn.com/problems/house-robber-iii/) | [Rob](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_337_rob.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #338 | [比特位计数](https://leetcode-cn.com/problems/counting-bits/) | [CountBits](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_338_countBits.java) | [位运算](https://leetcode-cn.com/tag/bit-manipulation/)、[动态规划]() | Medium | | | #343 | [整数拆分](https://leetcode-cn.com/problems/integer-break/) | [IntegerBreak](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_343_integerBreak.java) | [数学]()、[动态规划]() | Medium | | +| #347 | [前 K 个高频元素](https://leetcode-cn.com/problems/top-k-frequent-elements/) | [TopKFrequent](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_347_topKFrequent.java) | [哈希表]()、[堆](https://leetcode-cn.com/tag/heap/) | Medium | | | #354 | [俄罗斯套娃信封问题](https://leetcode-cn.com/problems/russian-doll-envelopes/) | [MaxEnvelopes.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_354_maxEnvelopes_2.java) | [二分查找]()、[动态规划]() | Hard | | | #376 | [摆动序列](https://leetcode-cn.com/problems/wiggle-subsequence/) | [WiggleMaxLength](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_376_wiggleMaxLength.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[动态规划]() | Medium | | | #402 | [移掉K位数字](https://leetcode-cn.com/problems/remove-k-digits/) | [RemoveKdigits](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_402_removeKdigits.java) | [堆](https://leetcode-cn.com/tag/heap/)、[贪心算法](https://leetcode-cn.com/tag/greedy/) | Medium | | From 353298ac6bc481bc57b9db11ea84ad30ba063b50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 23 Aug 2019 11:42:17 +0800 Subject: [PATCH 148/308] feat(MEDIUM): add _394_decodeString --- .../leetcode/_394_decodeString.java | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_394_decodeString.java diff --git a/src/pp/arithmetic/leetcode/_394_decodeString.java b/src/pp/arithmetic/leetcode/_394_decodeString.java new file mode 100644 index 0000000..c99caf8 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_394_decodeString.java @@ -0,0 +1,80 @@ +package pp.arithmetic.leetcode; + +import java.util.LinkedList; + +/** + * Created by wangpeng on 2019-08-23. + * 394. 字符串解码 + *

+ * 给定一个经过编码的字符串,返回它解码后的字符串。 + *

+ * 编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。 + *

+ * 你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。 + *

+ * 此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。 + *

+ * 示例: + *

+ * s = "3[a]2[bc]", 返回 "aaabcbc". + * s = "3[a2[c]]", 返回 "accaccacc". + * s = "2[abc]3[cd]ef", 返回 "abcabccdcdcdef". + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/decode-string + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _394_decodeString { + + public static void main(String[] args) { + _394_decodeString decodeString = new _394_decodeString(); + System.out.println(decodeString.decodeString("3[a2[c]]")); + System.out.println(decodeString.decodeString("2[abc]3[cd]ef")); + } + + /** + * 解题思路: + * 将decodeStr拆解后会有四种可能:数字、字母、[、] + * 使用栈保存遍历的结果,numStack保存数字,stringStack保存字母 + * 例:3[a2[c]] + * 1、遇到数字:计算数字的大小,注意连续数字的情况 + * 2、遇到左括号:将之前得到的数字入栈,之前得到的字母也入栈 + * 3、遇到字母:累加连续字母 + * 4、遇到右括号:将数字出栈,将累加字母根据数字翻倍,将字母也出栈,和翻倍字母拼接 + * 5、循环1-4 + * + * @param s + * @return + */ + public String decodeString(String s) { + StringBuilder builder = new StringBuilder(); + LinkedList numStack = new LinkedList<>(); + LinkedList stringStack = new LinkedList<>(); + int num = 0; + for (char c : s.toCharArray()) { + if (c >= '0' && c <= '9') { + //1 + num = num * 10 + c - '0'; + } else if (c == '[') { + //2 + numStack.addLast(num); + stringStack.addLast(builder.toString()); + builder.delete(0, builder.length()); + num = 0; + } else if (c == ']') { + //4 + String item = builder.toString(); + Integer numItem = numStack.removeLast(); + for (int i = 1; i < numItem; i++) { + builder.append(item); + } + builder.insert(0, stringStack.removeLast()); + } else { + //3 + builder.append(c); + } + } + + return builder.toString(); + } +} From 8e6dd196cfe609dc7f86f272b99109fdf4314251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 23 Aug 2019 11:47:02 +0800 Subject: [PATCH 149/308] docs: add _394_decodeString --- README.md | 9 +++++---- src/pp/arithmetic/leetcode/_394_decodeString.java | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4d78fd9..23eeed1 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成201道 +- leetcode练习,坚持每天一道,目前已完成202道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -19,7 +19,7 @@ - [x] [347. 前 K 个高频元素 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_347_topKFrequent.java) -- [ ] [394. 字符串解码 -Medium](https://leetcode-cn.com/problems/decode-string/) +- [x] [394. 字符串解码 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_394_decodeString.java) - [ ] [399. 除法求值 -Medium](https://leetcode-cn.com/problems/evaluate-division/) @@ -60,9 +60,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成201) +### 题目列表(更新中—已完成202) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_347_topKFrequent.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_394_decodeString.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -229,6 +229,7 @@ | #347 | [前 K 个高频元素](https://leetcode-cn.com/problems/top-k-frequent-elements/) | [TopKFrequent](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_347_topKFrequent.java) | [哈希表]()、[堆](https://leetcode-cn.com/tag/heap/) | Medium | | | #354 | [俄罗斯套娃信封问题](https://leetcode-cn.com/problems/russian-doll-envelopes/) | [MaxEnvelopes.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_354_maxEnvelopes_2.java) | [二分查找]()、[动态规划]() | Hard | | | #376 | [摆动序列](https://leetcode-cn.com/problems/wiggle-subsequence/) | [WiggleMaxLength](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_376_wiggleMaxLength.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[动态规划]() | Medium | | +| #394 | [字符串解码](https://leetcode-cn.com/problems/decode-string/) | [DecodeString](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_394_decodeString.java) | [栈](https://leetcode-cn.com/tag/stack/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #402 | [移掉K位数字](https://leetcode-cn.com/problems/remove-k-digits/) | [RemoveKdigits](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_402_removeKdigits.java) | [堆](https://leetcode-cn.com/tag/heap/)、[贪心算法](https://leetcode-cn.com/tag/greedy/) | Medium | | | #409 | [最长回文串](https://leetcode-cn.com/problems/longest-palindrome/) | [LongestPalindrome](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_409_longestPalindrome.java) | [哈希表]() | Easy | | | #415 | [字符串相加](https://leetcode-cn.com/problems/add-strings/) | [AddStrings](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_415_addStrings.java) | [字符串]() | Easy | | diff --git a/src/pp/arithmetic/leetcode/_394_decodeString.java b/src/pp/arithmetic/leetcode/_394_decodeString.java index c99caf8..b044e0d 100644 --- a/src/pp/arithmetic/leetcode/_394_decodeString.java +++ b/src/pp/arithmetic/leetcode/_394_decodeString.java @@ -38,7 +38,7 @@ public static void main(String[] args) { * 使用栈保存遍历的结果,numStack保存数字,stringStack保存字母 * 例:3[a2[c]] * 1、遇到数字:计算数字的大小,注意连续数字的情况 - * 2、遇到左括号:将之前得到的数字入栈,之前得到的字母也入栈 + * 2、遇到左括号:将之前得到的数字入栈,之前得到的字母也入栈,情况数字和字母 * 3、遇到字母:累加连续字母 * 4、遇到右括号:将数字出栈,将累加字母根据数字翻倍,将字母也出栈,和翻倍字母拼接 * 5、循环1-4 From 399791f37f0f7aa4be695c437657cce514180521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 26 Aug 2019 14:35:18 +0800 Subject: [PATCH 150/308] feat(MEDIUM): add _399_calcEquation --- .../leetcode/_399_calcEquation.java | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_399_calcEquation.java diff --git a/src/pp/arithmetic/leetcode/_399_calcEquation.java b/src/pp/arithmetic/leetcode/_399_calcEquation.java new file mode 100644 index 0000000..882a2b0 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_399_calcEquation.java @@ -0,0 +1,139 @@ +package pp.arithmetic.leetcode; + +import java.util.*; + +/** + * Created by wangpeng on 2019-08-26. + * 399. 除法求值 + *

+ * 给出方程式 A / B = k, 其中 A 和 B 均为代表字符串的变量, k 是一个浮点型数字。根据已知方程式求解问题,并返回计算结果。如果结果不存在,则返回 -1.0。 + *

+ * 示例 : + * 给定 a / b = 2.0, b / c = 3.0 + * 问题: a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ?  + * 返回 [6.0, 0.5, -1.0, 1.0, -1.0 ] + *

+ * 输入为: vector> equations, vector& values, vector> queries(方程式,方程式结果,问题方程式), 其中 equations.size() == values.size(),即方程式的长度与方程式结果长度相等(程式与结果一一对应),并且结果值均为正数。以上为方程式的描述。 返回vector类型。 + *

+ * 基于上述例子,输入如下: + *

+ * equations(方程式) = [ ["a", "b"], ["b", "c"] ], + * values(方程式结果) = [2.0, 3.0], + * queries(问题方程式) = [ ["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"] ]. + * 输入总是有效的。你可以假设除法运算中不会出现除数为0的情况,且不存在任何矛盾的结果。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/evaluate-division + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _399_calcEquation { + + public static void main(String[] args) { + _399_calcEquation calcEquation = new _399_calcEquation(); + List> equations = new ArrayList<>(); + equations.add(generateList("x1", "x2")); + equations.add(generateList("x2", "x3")); + equations.add(generateList("x3", "x4")); + equations.add(generateList("x4", "x5")); + double[] values = new double[]{3.0,4.0,5.0,6.0}; + List> queries = new ArrayList<>(); + queries.add(generateList("x1", "x5")); + queries.add(generateList("x5", "x2")); + queries.add(generateList("x2", "x4")); + queries.add(generateList("x2", "x2")); + queries.add(generateList("x2", "x9")); + queries.add(generateList("x9", "x9")); + + //[["x1","x2"],["x2","x3"],["x3","x4"],["x4","x5"]] + //[3.0,4.0,5.0,6.0] + //[["x1","x5"],["x5","x2"],["x2","x4"],["x2","x2"],["x2","x9"],["x9","x9"]] + //求解 + double[] doubles = calcEquation.calcEquation(equations, values, queries); + for (int i = 0; i < doubles.length; i++) { + System.out.println(doubles[i]); + } + } + + private static List generateList(String divisor, String dividend) { + List list = new ArrayList<>(); + list.add(divisor); + list.add(dividend); + return list; + } + + /** + * 解题思路: + * 利用HashMap保存每个参数与其他参数直接的关系,当要求解新的方程式的时候,通过之前的关系递归求解出结果 + * 方法不是最优,自己完全构思出来的,如需最优的可以参考他人的 + * + * 执行用时 :7 ms, 在所有 Java 提交中击败了 6.74%的用户 + * 内存消耗 : 35.9 MB, 在所有 Java 提交中击败了55.00%的用户 + * + * @param equations + * @param values + * @param queries + * @return + */ + public double[] calcEquation(List> equations, double[] values, List> queries) { + double[] ret = new double[queries.size()]; + HashMap> map = new HashMap(); + //将方程式和结果拆解成map,key为参数,value为对应其他参数的值的集合 + for (int i = 0; i < equations.size(); i++) { + String divisor = equations.get(i).get(0); + String dividend = equations.get(i).get(1); + double result = values[i]; + //保存方程式结果 + List divisorR = map.getOrDefault(divisor, new ArrayList<>()); + divisorR.add(result + "_" + dividend); + map.put(divisor, divisorR); + List dividendR = map.getOrDefault(dividend, new ArrayList<>()); + dividendR.add(1 / result + "_" + divisor); + map.put(dividend, dividendR); + } + + //求解 + for (int i = 0; i < queries.size(); i++) { + String divisor = queries.get(i).get(0); + String dividend = queries.get(i).get(1); + List divisorR = map.get(divisor); + List dividendR = map.get(dividend); + //变量是否存在 + if (divisorR == null || dividendR == null) { + ret[i] = -1.0; + continue; + } + //是否相等 + if (divisor.equals(dividend)) { + ret[i] = 1.0; + continue; + } + List divisors = new LinkedList<>(); + //递归求解 + Double dfs = dfs(map, divisorR, divisors, dividend); + ret[i] = dfs == null ? -1.0 : dfs; + } + return ret; + } + + private Double dfs(Map> map, List divisorR, List divisors, String dividend) { + for (int i = 0; i < divisorR.size(); i++) { + double multi = 1; + String[] split = divisorR.get(i).split("_"); + if (divisors.contains(split[1])) { + continue; + } + multi *= Double.parseDouble(split[0]); + if (split[1].equals(dividend)) { + return multi; + } else { + divisors.add(split[1]); + Double dfs = dfs(map, map.get(split[1]), divisors, dividend); + divisors.remove(split[1]); + if (dfs != null) { + return multi * dfs; + } + } + } + return null; + } +} From 8083c82b2f0240bd9ddd137ef287fdce02dd3d69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 26 Aug 2019 14:39:17 +0800 Subject: [PATCH 151/308] docs: add _399_calcEquation --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 23eeed1..00e9f1d 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成202道 +- leetcode练习,坚持每天一道,目前已完成203道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -21,7 +21,7 @@ - [x] [394. 字符串解码 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_394_decodeString.java) -- [ ] [399. 除法求值 -Medium](https://leetcode-cn.com/problems/evaluate-division/) +- [x] [399. 除法求值 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_399_calcEquation.java) - [ ] [406. 根据身高重建队列 -Medium](https://leetcode-cn.com/problems/queue-reconstruction-by-height/) @@ -60,9 +60,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成202) +### 题目列表(更新中—已完成203) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_394_decodeString.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_399_calcEquation.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -230,6 +230,7 @@ | #354 | [俄罗斯套娃信封问题](https://leetcode-cn.com/problems/russian-doll-envelopes/) | [MaxEnvelopes.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_354_maxEnvelopes_2.java) | [二分查找]()、[动态规划]() | Hard | | | #376 | [摆动序列](https://leetcode-cn.com/problems/wiggle-subsequence/) | [WiggleMaxLength](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_376_wiggleMaxLength.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[动态规划]() | Medium | | | #394 | [字符串解码](https://leetcode-cn.com/problems/decode-string/) | [DecodeString](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_394_decodeString.java) | [栈](https://leetcode-cn.com/tag/stack/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | +| #399 | [除法求值](https://leetcode-cn.com/problems/evaluate-division/) | [CalcEquation](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_399_calcEquation.java) | [并查集](https://leetcode-cn.com/tag/union-find/)、[图](https://leetcode-cn.com/tag/graph/) | Medium | | | #402 | [移掉K位数字](https://leetcode-cn.com/problems/remove-k-digits/) | [RemoveKdigits](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_402_removeKdigits.java) | [堆](https://leetcode-cn.com/tag/heap/)、[贪心算法](https://leetcode-cn.com/tag/greedy/) | Medium | | | #409 | [最长回文串](https://leetcode-cn.com/problems/longest-palindrome/) | [LongestPalindrome](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_409_longestPalindrome.java) | [哈希表]() | Easy | | | #415 | [字符串相加](https://leetcode-cn.com/problems/add-strings/) | [AddStrings](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_415_addStrings.java) | [字符串]() | Easy | | From 9ace1a8a05a4813947150e1a8fcd0271834907f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 27 Aug 2019 11:49:36 +0800 Subject: [PATCH 152/308] feat(MEDIUM): add _406_reconstructQueue --- .../leetcode/_406_reconstructQueue.java | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_406_reconstructQueue.java diff --git a/src/pp/arithmetic/leetcode/_406_reconstructQueue.java b/src/pp/arithmetic/leetcode/_406_reconstructQueue.java new file mode 100644 index 0000000..62f1c89 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_406_reconstructQueue.java @@ -0,0 +1,70 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +/** + * Created by wangpeng on 2019-08-27. + * 406. 根据身高重建队列 + *

+ * 假设有打乱顺序的一群人站成一个队列。 每个人由一个整数对(h, k)表示,其中h是这个人的身高,k是排在这个人前面且身高大于或等于h的人数。 编写一个算法来重建这个队列。 + *

+ * 注意: + * 总人数少于1100人。 + *

+ * 示例 + *

+ * 输入: + * [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]] + *

+ * 输出: + * [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]] + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/queue-reconstruction-by-height + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _406_reconstructQueue { + + public static void main(String[] args) { + _406_reconstructQueue reconstructQueue = new _406_reconstructQueue(); + int[][] ints = reconstructQueue.reconstructQueue(new int[][]{ + {7, 0}, {7, 1}, {6, 1}, {5, 0}, {5, 2}, {4, 4} + }); + for (int i = 0; i < ints.length; i++) { + Util.printArray(ints[i]); + } + } + + /** + * 解题思路:先排序再插入 + * 1.排序规则:按照先H高度降序,K个数升序排序 + * 2.遍历排序后的数组,根据K插入到K的位置上 + * + * 核心思想:高个子先站好位,矮个子插入到K位置上,前面肯定有K个高个子,矮个子再插到前面也满足K的要求 + * + * @param people + * @return + */ + public int[][] reconstructQueue(int[][] people) { + // [7,0], [7,1], [6,1], [5,0], [5,2], [4,4] + // 再一个一个插入。 + // [7,0] + // [7,0], [7,1] + // [7,0], [6,1], [7,1] + // [5,0], [7,0], [6,1], [7,1] + // [5,0], [7,0], [5,2], [6,1], [7,1] + // [5,0], [7,0], [5,2], [6,1], [4,4], [7,1] + Arrays.sort(people, (o1, o2) -> o1[0] == o2[0] ? o1[1] - o2[1] : o2[0] - o1[0]); + + LinkedList list = new LinkedList<>(); + for (int[] i : people) { + list.add(i[1], i); + } + + return list.toArray(new int[list.size()][2]); + } +} From 1fd7c33431b3bc1b0cb0ddf3f2cac1566a264f63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 27 Aug 2019 11:54:47 +0800 Subject: [PATCH 153/308] docs: add _406_reconstructQueue --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 00e9f1d..49735ac 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成203道 +- leetcode练习,坚持每天一道,目前已完成204道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -23,7 +23,7 @@ - [x] [399. 除法求值 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_399_calcEquation.java) -- [ ] [406. 根据身高重建队列 -Medium](https://leetcode-cn.com/problems/queue-reconstruction-by-height/) +- [x] [406. 根据身高重建队列 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_406_reconstructQueue.java) - [ ] [416. 分割等和子集 -Medium](https://leetcode-cn.com/problems/partition-equal-subset-sum/) @@ -60,9 +60,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成203) +### 题目列表(更新中—已完成204) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_399_calcEquation.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_406_reconstructQueue.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -232,6 +232,7 @@ | #394 | [字符串解码](https://leetcode-cn.com/problems/decode-string/) | [DecodeString](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_394_decodeString.java) | [栈](https://leetcode-cn.com/tag/stack/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #399 | [除法求值](https://leetcode-cn.com/problems/evaluate-division/) | [CalcEquation](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_399_calcEquation.java) | [并查集](https://leetcode-cn.com/tag/union-find/)、[图](https://leetcode-cn.com/tag/graph/) | Medium | | | #402 | [移掉K位数字](https://leetcode-cn.com/problems/remove-k-digits/) | [RemoveKdigits](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_402_removeKdigits.java) | [堆](https://leetcode-cn.com/tag/heap/)、[贪心算法](https://leetcode-cn.com/tag/greedy/) | Medium | | +| #406 | [根据身高重建队列](https://leetcode-cn.com/problems/queue-reconstruction-by-height/) | [ReconstructQueue](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_406_reconstructQueue.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/) | Medium | | | #409 | [最长回文串](https://leetcode-cn.com/problems/longest-palindrome/) | [LongestPalindrome](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_409_longestPalindrome.java) | [哈希表]() | Easy | | | #415 | [字符串相加](https://leetcode-cn.com/problems/add-strings/) | [AddStrings](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_415_addStrings.java) | [字符串]() | Easy | | | #424 | [替换后的最长重复字符](https://leetcode-cn.com/problems/longest-repeating-character-replacement/) | [CharacterReplacement](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_424_characterReplacement.java) | [双指针]()、[sliding window]() | Medium | | From c359a8d7cd7c407ba3834e93810a6e0f9f96bd53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 28 Aug 2019 11:57:27 +0800 Subject: [PATCH 154/308] feat(MEDIUM): add _416_canPartition --- .../leetcode/_416_canPartition.java | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_416_canPartition.java diff --git a/src/pp/arithmetic/leetcode/_416_canPartition.java b/src/pp/arithmetic/leetcode/_416_canPartition.java new file mode 100644 index 0000000..a1aa4c1 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_416_canPartition.java @@ -0,0 +1,126 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-08-28. + * 416. 分割等和子集 + *

+ * 给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 + *

+ * 注意: + *

+ * 每个数组中的元素不会超过 100 + * 数组的大小不会超过 200 + * 示例 1: + *

+ * 输入: [1, 5, 11, 5] + *

+ * 输出: true + *

+ * 解释: 数组可以分割成 [1, 5, 5] 和 [11]. + *   + *

+ * 示例 2: + *

+ * 输入: [1, 2, 3, 5] + *

+ * 输出: false + *

+ * 解释: 数组不能分割成两个元素和相等的子集. + *   + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/partition-equal-subset-sum + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _416_canPartition { + + public static void main(String[] args) { + _416_canPartition canPartition = new _416_canPartition(); + System.out.println(canPartition.canPartition(new int[]{1, 5, 11, 5})); + System.out.println(canPartition.canPartition(new int[]{1, 3, 2, 4, 4,1})); + } + + /** + * 解题思路: + * 1、对数组进行求和,如总和为奇数则不可能存在相等的两个集合 + * 2、找到求和为总和一半的集合,则满足拆分 + * 3、对于已存在得数组中求出满足条件的总数,可以将问题拆解成0-1背包问题,转换为动态规划求解 + * 4、对于dp[i][j]代表,0-i中找出总和为j的集合,那么对于nums[i]来说可以选择(nums[i] j) { + dp[i][j] = dp[i - 1][j]; + } else { + dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i]]; + } + } + } + + return dp[nums.length - 1][sum]; + } + + /** + * 优化:将二维降为一维,利用之前的计算判断 + * + * @param nums + * @return + */ + public boolean canPartition2(int[] nums) { + int size = nums.length; + + int s = 0; + for (int num : nums) { + s += num; + } + if ((s & 1) == 1) { + return false; + } + + int target = s / 2; + + // 从第 2 行以后,当前行的结果参考了上一行的结果,因此使用一维数组定义状态就可以了 + boolean[] dp = new boolean[target + 1]; + // 先写第 1 行,看看第 1 个数是不是能够刚好填满容量为 target + for (int j = 1; j < target + 1; j++) { + if (nums[0] == j) { + dp[j] = true; + // 如果等于,后面就不用做判断了,因为 j 会越来越大,肯定不等于 nums[0] + break; + } + } + // 注意:因为后面的参考了前面的,我们从后向前填写 + for (int i = 1; i < size; i++) { + // 后面的容量越来越小,因此没有必要再判断了,退出当前循环 + for (int j = target; j >= 0 && j >= nums[i]; j--) { + dp[j] = dp[j] || dp[j - nums[i]]; + } + } + return dp[target]; + } +} From 82623eb35926b32f9d5f6bc41033b50a86190534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 28 Aug 2019 11:59:28 +0800 Subject: [PATCH 155/308] docs: add _416_canPartition --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 49735ac..b924b4a 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成204道 +- leetcode练习,坚持每天一道,目前已完成205道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -25,7 +25,7 @@ - [x] [406. 根据身高重建队列 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_406_reconstructQueue.java) -- [ ] [416. 分割等和子集 -Medium](https://leetcode-cn.com/problems/partition-equal-subset-sum/) +- [x] [416. 分割等和子集 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_416_canPartition.java) ## 已解题目 @@ -60,9 +60,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成204) +### 题目列表(更新中—已完成205) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_406_reconstructQueue.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_416_canPartition.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -235,6 +235,7 @@ | #406 | [根据身高重建队列](https://leetcode-cn.com/problems/queue-reconstruction-by-height/) | [ReconstructQueue](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_406_reconstructQueue.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/) | Medium | | | #409 | [最长回文串](https://leetcode-cn.com/problems/longest-palindrome/) | [LongestPalindrome](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_409_longestPalindrome.java) | [哈希表]() | Easy | | | #415 | [字符串相加](https://leetcode-cn.com/problems/add-strings/) | [AddStrings](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_415_addStrings.java) | [字符串]() | Easy | | +| #416 | [分割等和子集](https://leetcode-cn.com/problems/partition-equal-subset-sum/) | [CanPartition](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_416_canPartition.java) | [动态规划]() | Medium | | | #424 | [替换后的最长重复字符](https://leetcode-cn.com/problems/longest-repeating-character-replacement/) | [CharacterReplacement](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_424_characterReplacement.java) | [双指针]()、[sliding window]() | Medium | | | #432 | [全 O(1) 的数据结构](https://leetcode-cn.com/problems/all-oone-data-structure/) | [AllOne](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_432_AllOne.java) | [设计](https://leetcode-cn.com/tag/design/) | Hard | | | #438 | [找到字符串中所有字母异位词](https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/) | [FindAnagrams](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_438_findAnagrams.java) | [哈希表]() | Easy | | From ad4aad656e3c9c5ff42666e8a342c9dfbada3fe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 29 Aug 2019 10:17:46 +0800 Subject: [PATCH 156/308] docs: update the topic list --- README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index b924b4a..ef2d923 100644 --- a/README.md +++ b/README.md @@ -15,17 +15,19 @@ 扫题:热题 Hot 100 -- [x] [337. 打家劫舍 III -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_337_rob.java) +- [ ] [437. 路径总和 III -Easy](https://leetcode-cn.com/problems/path-sum-iii/) -- [x] [347. 前 K 个高频元素 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_347_topKFrequent.java) +- [ ] [438. 找到字符串中所有字母异位词 -Easy](https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/) -- [x] [394. 字符串解码 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_394_decodeString.java) +- [ ] [448. 找到所有数组中消失的数字 -Easy](https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array/) -- [x] [399. 除法求值 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_399_calcEquation.java) +- [ ] [461. 汉明距离 -Easy](https://leetcode-cn.com/problems/hamming-distance/) -- [x] [406. 根据身高重建队列 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_406_reconstructQueue.java) +- [ ] [494. 目标和 -Medium](https://leetcode-cn.com/problems/target-sum/) -- [x] [416. 分割等和子集 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_416_canPartition.java) +- [ ] [538. 把二叉搜索树转换为累加树 -Easy](https://leetcode-cn.com/problems/convert-bst-to-greater-tree/) + +- [ ] [543. 二叉树的直径 -Easy](https://leetcode-cn.com/problems/diameter-of-binary-tree/) ## 已解题目 From ccbeb4e9d80c854323349e678faa5abe935802ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 30 Aug 2019 10:32:29 +0800 Subject: [PATCH 157/308] feat(EASY): add _437_pathSum --- src/pp/arithmetic/leetcode/_437_pathSum.java | 108 +++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_437_pathSum.java diff --git a/src/pp/arithmetic/leetcode/_437_pathSum.java b/src/pp/arithmetic/leetcode/_437_pathSum.java new file mode 100644 index 0000000..5fd1be8 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_437_pathSum.java @@ -0,0 +1,108 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.model.TreeNode; + +import java.util.*; + +/** + * Created by wangpeng on 2019-08-29. + * 437. 路径总和 III + *

+ * 给定一个二叉树,它的每个结点都存放着一个整数值。 + *

+ * 找出路径和等于给定数值的路径总数。 + *

+ * 路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。 + *

+ * 二叉树不超过1000个节点,且节点数值范围是 [-1000000,1000000] 的整数。 + *

+ * 示例: + *

+ * root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8 + *

+ * 10 + * / \ + * 5 -3 + * / \ \ + * 3 2 11 + * / \ \ + * 3 -2 1 + *

+ * 返回 3。和等于 8 的路径有: + *

+ * 1. 5 -> 3 + * 2. 5 -> 2 -> 1 + * 3. -3 -> 11 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/path-sum-iii + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _437_pathSum { + public static void main(String[] args) { + _437_pathSum pathSum = new _437_pathSum(); + //[10,5,-3,3,2,null,11,3,-2,null,1], sum = 8 + TreeNode root = new TreeNode(10); + root.left = new TreeNode(5); + root.right = new TreeNode(-3); + root.left.left = new TreeNode(3); + root.left.right = new TreeNode(2); + root.right.right = new TreeNode(11); + root.left.left.left = new TreeNode(3); + root.left.left.right = new TreeNode(-2); + root.left.right.left = new TreeNode(1); + System.out.println(pathSum.pathSum(root, 8)); + //[-2,null,-3],sum=-5 + TreeNode r1 = new TreeNode(-2); + r1.right = new TreeNode(-3); + System.out.println(pathSum.pathSum(r1, -5)); + //[1,-2,-3,1,3,-2,null,-1],sum=3 + TreeNode r2 = new TreeNode(1); + r2.left = new TreeNode(-2); + r2.right = new TreeNode(-3); + r2.left.left = new TreeNode(1); + r2.left.right = new TreeNode(3); + r2.left.left.left = new TreeNode(-1); + r2.right.left = new TreeNode(-2); + System.out.println(pathSum.pathSum(r2, 3)); + //[0,1,1] sum=1 + TreeNode r3 = new TreeNode(0); + r3.left = new TreeNode(1); + r3.right = new TreeNode(1); + System.out.println(pathSum.pathSum(r3, 1)); + } + + int result = 0; + + /** + * 解题思路: + * 1.中序遍历,将遍历结果保存在list中 + * 2.从list的末尾开始累加,如和==sum,则结果+1 + * + * @param root + * @param sum + * @return + */ + public int pathSum(TreeNode root, int sum) { + result = 0; + List list = new LinkedList<>(); + dfs(root, list, sum); + return result; + } + + private void dfs(TreeNode root, List list, int sum) { + if (root == null) return; + int tempSum = 0; + list.add(root); + for (int i = list.size() - 1; i >= 0; i--) { + tempSum += list.get(i).val; + if (tempSum == sum) { + result++; + } + } + dfs(root.left, list, sum); + dfs(root.right, list, sum); + list.remove(root); + } + +} From 89dd96b78b79673ff6c82f8116a9928118e93dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 30 Aug 2019 10:39:22 +0800 Subject: [PATCH 158/308] docs: add _437_pathSum --- README.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index ef2d923..fd3db05 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成205道 +- leetcode练习,坚持每天一道,目前已完成206道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -15,19 +15,19 @@ 扫题:热题 Hot 100 -- [ ] [437. 路径总和 III -Easy](https://leetcode-cn.com/problems/path-sum-iii/) +- [x] [437. 路径总和 III -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_437_pathSum.java) -- [ ] [438. 找到字符串中所有字母异位词 -Easy](https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/) +- [ ] [438. 找到字符串中所有字母异位词 -Easy](https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/) -- [ ] [448. 找到所有数组中消失的数字 -Easy](https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array/) +- [ ] [448. 找到所有数组中消失的数字 -Easy](https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array/) -- [ ] [461. 汉明距离 -Easy](https://leetcode-cn.com/problems/hamming-distance/) +- [ ] [461. 汉明距离 -Easy](https://leetcode-cn.com/problems/hamming-distance/) -- [ ] [494. 目标和 -Medium](https://leetcode-cn.com/problems/target-sum/) +- [ ] [494. 目标和 -Medium](https://leetcode-cn.com/problems/target-sum/) -- [ ] [538. 把二叉搜索树转换为累加树 -Easy](https://leetcode-cn.com/problems/convert-bst-to-greater-tree/) +- [ ] [538. 把二叉搜索树转换为累加树 -Easy](https://leetcode-cn.com/problems/convert-bst-to-greater-tree/) -- [ ] [543. 二叉树的直径 -Easy](https://leetcode-cn.com/problems/diameter-of-binary-tree/) +- [ ] [543. 二叉树的直径 -Easy](https://leetcode-cn.com/problems/diameter-of-binary-tree/) ## 已解题目 @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成205) +### 题目列表(更新中—已完成206) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_416_canPartition.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_437_pathSum.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -240,6 +240,7 @@ | #416 | [分割等和子集](https://leetcode-cn.com/problems/partition-equal-subset-sum/) | [CanPartition](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_416_canPartition.java) | [动态规划]() | Medium | | | #424 | [替换后的最长重复字符](https://leetcode-cn.com/problems/longest-repeating-character-replacement/) | [CharacterReplacement](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_424_characterReplacement.java) | [双指针]()、[sliding window]() | Medium | | | #432 | [全 O(1) 的数据结构](https://leetcode-cn.com/problems/all-oone-data-structure/) | [AllOne](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_432_AllOne.java) | [设计](https://leetcode-cn.com/tag/design/) | Hard | | +| #437 | [路径总和 III](https://leetcode-cn.com/problems/path-sum-iii/) | [PathSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_437_pathSum.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | | #438 | [找到字符串中所有字母异位词](https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/) | [FindAnagrams](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_438_findAnagrams.java) | [哈希表]() | Easy | | | #449 | [序列化和反序列化二叉搜索树](https://leetcode-cn.com/problems/serialize-and-deserialize-bst/) | [Serialize_deserialize](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_449_serialize_deserialize.java) | [树](https://leetcode-cn.com/tag/tree/) | Medium | | | #450 | [删除二叉搜索树中的节点](https://leetcode-cn.com/problems/delete-node-in-a-bst/) | [DeleteNode](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_450_deleteNode.java) | [树](https://leetcode-cn.com/tag/tree/) | Medium | | From ff01f0df205c157ebe3f4d59f53c296dc7f1a5a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 30 Aug 2019 10:42:48 +0800 Subject: [PATCH 159/308] docs: add _438_findAnagrams --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fd3db05..b373f83 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ - [x] [437. 路径总和 III -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_437_pathSum.java) -- [ ] [438. 找到字符串中所有字母异位词 -Easy](https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/) +- [x] [438. 找到字符串中所有字母异位词 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_438_findAnagrams.java) - [ ] [448. 找到所有数组中消失的数字 -Easy](https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array/) From 57939806dacfd7d77f82e5159c0df072ba8d4b41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 30 Aug 2019 11:27:48 +0800 Subject: [PATCH 160/308] feat(EASY): add _448_findDisappearedNumbers --- .../leetcode/_448_findDisappearedNumbers.java | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_448_findDisappearedNumbers.java diff --git a/src/pp/arithmetic/leetcode/_448_findDisappearedNumbers.java b/src/pp/arithmetic/leetcode/_448_findDisappearedNumbers.java new file mode 100644 index 0000000..29bef67 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_448_findDisappearedNumbers.java @@ -0,0 +1,78 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wangpeng on 2019-08-30. + * 448. 找到所有数组中消失的数字 + *

+ * 给定一个范围在  1 ≤ a[i] ≤ n ( n = 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次。 + *

+ * 找到所有在 [1, n] 范围之间没有出现在数组中的数字。 + *

+ * 您能在不使用额外空间且时间复杂度为O(n)的情况下完成这个任务吗? 你可以假定返回的数组不算在额外空间内。 + *

+ * 示例: + *

+ * 输入: + * [4,3,2,7,8,2,3,1] + *

+ * 输出: + * [5,6] + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _448_findDisappearedNumbers { + + public static void main(String[] args) { + _448_findDisappearedNumbers findDisappearedNumbers = new _448_findDisappearedNumbers(); + Util.printList(findDisappearedNumbers.findDisappearedNumbers(new int[]{4, 3, 2, 1, 8, 3, 2, 1})); + Util.printList(findDisappearedNumbers.findDisappearedNumbers2(new int[]{4, 3, 2, 7, 8, 2, 3, 1})); + } + + /** + * 解题思路: + * 简单求解:用一个hash映射表保存出现过的数字,再遍历保存结果找出未出现的数字(使用了O(n)的额外空间)==>{findDisappearedNumbers2} + *

+ * 优化求解:去除O(n)的空间 + * 1.遍历nums,将item对应的位置+n,用于标识是否出现过(注意对item取模) + * 2.再次遍历nums,找到小于n的位置就是未出现的数字了 + * + * @param nums + * @return + */ + public List findDisappearedNumbers(int[] nums) { + List retList = new ArrayList<>(); + + int n = nums.length; + for (int i = 0; i < n; i++) { + int index = (nums[i] - 1) % n; + nums[index] += n; + } + for (int i = 0; i < n; i++) { + if (nums[i] <= n) { + retList.add(i + 1); + } + } + + return retList; + } + + public List findDisappearedNumbers2(int[] nums) { + List retList = new ArrayList<>(); + boolean[] allNums = new boolean[nums.length]; + for (int i = 0; i < nums.length; i++) { + allNums[nums[i] - 1] = true; + } + for (int i = 0; i < allNums.length; i++) { + boolean item = allNums[i]; + if (!item) retList.add(i + 1); + } + return retList; + } +} From 57a74126adc661d294db26869d64b508b38aa290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 30 Aug 2019 11:30:55 +0800 Subject: [PATCH 161/308] docs: add _448_findDisappearedNumbers --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b373f83..45defcc 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成206道 +- leetcode练习,坚持每天一道,目前已完成207道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -19,7 +19,7 @@ - [x] [438. 找到字符串中所有字母异位词 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_438_findAnagrams.java) -- [ ] [448. 找到所有数组中消失的数字 -Easy](https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array/) +- [x] [448. 找到所有数组中消失的数字 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_448_findDisappearedNumbers.java) - [ ] [461. 汉明距离 -Easy](https://leetcode-cn.com/problems/hamming-distance/) @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成206) +### 题目列表(更新中—已完成207) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_437_pathSum.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_448_findDisappearedNumbers.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -242,6 +242,7 @@ | #432 | [全 O(1) 的数据结构](https://leetcode-cn.com/problems/all-oone-data-structure/) | [AllOne](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_432_AllOne.java) | [设计](https://leetcode-cn.com/tag/design/) | Hard | | | #437 | [路径总和 III](https://leetcode-cn.com/problems/path-sum-iii/) | [PathSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_437_pathSum.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | | #438 | [找到字符串中所有字母异位词](https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/) | [FindAnagrams](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_438_findAnagrams.java) | [哈希表]() | Easy | | +| #448 | [找到所有数组中消失的数字](https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array/) | [FindDisappearedNumbers](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_448_findDisappearedNumbers.java) | [数组]() | Easy | | | #449 | [序列化和反序列化二叉搜索树](https://leetcode-cn.com/problems/serialize-and-deserialize-bst/) | [Serialize_deserialize](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_449_serialize_deserialize.java) | [树](https://leetcode-cn.com/tag/tree/) | Medium | | | #450 | [删除二叉搜索树中的节点](https://leetcode-cn.com/problems/delete-node-in-a-bst/) | [DeleteNode](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_450_deleteNode.java) | [树](https://leetcode-cn.com/tag/tree/) | Medium | | | #452 | [用最少数量的箭引爆气球](https://leetcode-cn.com/problems/minimum-number-of-arrows-to-burst-balloons/) | [FindMinArrowShots](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_452_findMinArrowShots.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/) | Medium | | From 96df92ce6de0f2be681204ddb2a74441bacb1583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Sat, 31 Aug 2019 12:00:03 +0800 Subject: [PATCH 162/308] feat(EASY): add _461_hammingDistance --- .../leetcode/_461_hammingDistance.java | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_461_hammingDistance.java diff --git a/src/pp/arithmetic/leetcode/_461_hammingDistance.java b/src/pp/arithmetic/leetcode/_461_hammingDistance.java new file mode 100644 index 0000000..083a7bb --- /dev/null +++ b/src/pp/arithmetic/leetcode/_461_hammingDistance.java @@ -0,0 +1,90 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-08-31. + * 461. 汉明距离 + * + * 两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目。 + * + * 给出两个整数 x 和 y,计算它们之间的汉明距离。 + * + * 注意: + * 0 ≤ x, y < 231. + * + * 示例: + * + * 输入: x = 1, y = 4 + * + * 输出: 2 + * + * 解释: + * 1 (0 0 0 1) + * 4 (0 1 0 0) + * ↑ ↑ + * + * 上面的箭头指出了对应二进制位不同的位置。 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/hamming-distance + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _461_hammingDistance { + public static void main(String[] args) { + _461_hammingDistance hammingDistance = new _461_hammingDistance(); + System.out.println(hammingDistance.hammingDistance(1, 4)); + System.out.println(hammingDistance.hammingDistance1(1, 254)); + } + + /** + * 解题思路: + * 1.x^y做异或操作,得到的结果中不同位置都是1 + * 2.将异或结果转换成二进制字符串 + * 3.遍历二进制字符串得到 1 的个数 + * + * 更优解法{@link _461_hammingDistance#hammingDistance1(int, int)} + * + * @param x + * @param y + * @return + */ + public int hammingDistance(int x, int y) { + int result = 0; + int i = x ^ y; + String s = Integer.toBinaryString(i); + for (int j = 0; j < s.length(); j++) { + if (s.charAt(j) == '1') result++; + } + return result; + } + + /** + * Integer.bitCount源码剖析 + * (>>> 代表无符号右移,对于负数,右移后首位补0而非1) + * 0x55555555 ==> 01010101010101010101010101010101 + * 0x33333333 ==> 00110011001100110011001100110011 + * 0x0f0f0f0f ==> 00001111000011110000111100001111 + * + * //第一步,每两位一个二进制数,每个二进制数的值表示这两位中“1”的数量。00->00,01->01,10->01,11->10 + * i = i - ((i >>> 1) & 0x55555555); + * //第二步,两两分组,计算出两两的总数,保存在4中 + * i = (i & 0x33333333) + ((i >>> 2) & 0x33333333); + * //第三步,四四分组,计算出四四中的总数,保存在8中 + * i = (i + (i >>> 4)) & 0x0f0f0f0f; + * //第四步,八八分组,计算出八八中的总数,保存在16中 + * i = i + (i >>> 8); + * //第五步,16-16分组,计算出16-16总数 + * i = i + (i >>> 16); + * //结果返回 + * return i & 0x3f; + * + * 过程并不是很好理解,可以通过debug和手写模拟下 + * 用一句话就是把二进制数按两位分组,相邻分组两两相加得四位二进制的bitCount,再按四位分组,相邻分组两两相得八位二进制的bitCount,以此类推直到算出32位的bitCount数量。 + * + * @param x + * @param y + * @return + */ + public int hammingDistance1(int x, int y) { + return Integer.bitCount(x ^ y); + } +} From a376289e89139c7ab4a23e48aa26b055d88a058b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Sat, 31 Aug 2019 12:03:00 +0800 Subject: [PATCH 163/308] docs: add _461_hammingDistance --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 45defcc..60fabb8 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成207道 +- leetcode练习,坚持每天一道,目前已完成208道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -21,7 +21,7 @@ - [x] [448. 找到所有数组中消失的数字 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_448_findDisappearedNumbers.java) -- [ ] [461. 汉明距离 -Easy](https://leetcode-cn.com/problems/hamming-distance/) +- [x] [461. 汉明距离 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_461_hammingDistance.java) - [ ] [494. 目标和 -Medium](https://leetcode-cn.com/problems/target-sum/) @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成207) +### 题目列表(更新中—已完成208) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_448_findDisappearedNumbers.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_461_hammingDistance.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -250,6 +250,7 @@ | #455 | [分发饼干](https://leetcode-cn.com/problems/assign-cookies/) | [FindContentChildren](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_455_findContentChildren.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/) | Easy | | | #457 | [环形数组循环](https://leetcode-cn.com/problems/circular-array-loop/) | [CircularArrayLoop](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_457_circularArrayLoop.java) | [数组]()、[双指针]() | Medium | | | #460 | [LFU缓存](https://leetcode-cn.com/problems/lfu-cache/) | [LFUCache](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_460_LFUCache.java) | [设计](https://leetcode-cn.com/tag/design/) | Hard | | +| #461 | [汉明距离](https://leetcode-cn.com/problems/hamming-distance/) | [HammingDistance](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_461_hammingDistance.java) | [位运算](https://leetcode-cn.com/tag/bit-manipulation/) | Easy | | | #485 | [最大连续1的个数](https://leetcode-cn.com/problems/max-consecutive-ones/) | [FindMaxConsecutiveOnes](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_485_findMaxConsecutiveOnes.java) | [数组]() | Easy | | | #516 | [最长回文子序列](https://leetcode-cn.com/problems/longest-palindromic-subsequence/) | [LongestPalindromeSubseq](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_516_longestPalindromeSubseq.java) | [动态规划]() | Medium | | | #538 | [把二叉搜索树转换为累加树](https://leetcode-cn.com/problems/convert-bst-to-greater-tree/) | [ConvertBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_538_convertBST.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | From b2b05bb825e7adad461dc1583c88011c676c1ab9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 2 Sep 2019 21:04:58 +0800 Subject: [PATCH 164/308] feat(MEDIUM): add _494_findTargetSumWays --- .../leetcode/_494_findTargetSumWays.java | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_494_findTargetSumWays.java diff --git a/src/pp/arithmetic/leetcode/_494_findTargetSumWays.java b/src/pp/arithmetic/leetcode/_494_findTargetSumWays.java new file mode 100644 index 0000000..046c0b6 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_494_findTargetSumWays.java @@ -0,0 +1,114 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-09-02. + * 494. 目标和 + *

+ * 给定一个非负整数数组,a1, a2, ..., an, 和一个目标数,S。现在你有两个符号 + 和 -。对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面。 + *

+ * 返回可以使最终数组和为目标数 S 的所有添加符号的方法数。 + *

+ * 示例 1: + *

+ * 输入: nums: [1, 1, 1, 1, 1], S: 3 + * 输出: 5 + * 解释: + *

+ * -1+1+1+1+1 = 3 + * +1-1+1+1+1 = 3 + * +1+1-1+1+1 = 3 + * +1+1+1-1+1 = 3 + * +1+1+1+1-1 = 3 + *

+ * 一共有5种方法让最终目标和为3。 + * 注意: + *

+ * 数组的长度不会超过20,并且数组中的值全为正数。 + * 初始的数组的和不会超过1000。 + * 保证返回的最终结果为32位整数。 + *

+ *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/target-sum + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _494_findTargetSumWays { + + public static void main(String[] args) { + _494_findTargetSumWays findTargetSumWays = new _494_findTargetSumWays(); + System.out.println(findTargetSumWays.findTargetSumWays(new int[]{1, 1, 1, 1, 1}, 3)); + System.out.println(findTargetSumWays.findTargetSumWays1(new int[]{1, 1, 1, 1, 1}, 3)); + } + + /** + * 解题思路: + * 暴力解法:每一位有两种操作(+、-),深度遍历整个数组,得到满足条件的个数,时间复杂度O(2^n) {@link _494_findTargetSumWays#findTargetSumWays1(int[], int)} + * + * 优化解法:0-1背包问题改版 + * 1、求出背包中要取的总数和: + * 假设取正数和P,负数和N,P-N = target + * 两边同时加上 P+N ==> P+N+P-N = target + P+N(其中P+N=nums的总和) + * 2*P = target+sum ==> P = (target+sum)/2(P就是要取得总和) + * 2、dp[i]代表合成i有多少种方法,动态转移方程dp[i] += dp[i - num]; + * dp[i]的总和 == 除了i以外所有可能性总和,举例:[n1,n2,n3],dp[i]=dp[i-n1]+dp[i-n2]+dp[i-n3] + * + * @param nums + * @param target + * @return + */ + public int findTargetSumWays(int[] nums, int target) { + int sum = 0; + + for(int num : nums) { + sum += num; + } + + if(Math.abs(target) > sum || (sum + target) % 2 != 0) { + return 0; + } + + //1 + int P = (sum + target) / 2; + int[] dp = new int[P + 1]; + dp[0] = 1; + + //2、 + for (int num : nums) { + for (int i = P; i >= num; i--) { + dp[i] += dp[i - num]; + } + } + + return dp[P]; + } + + private int result = 0; + + /** + * 暴力解法: + * 执行用时 :673 ms, 在所有 Java 提交中击败了19.31%的用户 + * 内存消耗 :35.2 MB, 在所有 Java 提交中击败了81.70%的用户 + * + * @param nums + * @param S + * @return + */ + private int findTargetSumWays1(int[] nums, int S) { + dfs(nums, S, 0, 0); + return result; + } + + private void dfs(int[] nums, int S, int index, int cS) { + if (cS == S && index == nums.length) { + result++; + return; + } + if (index >= nums.length) { + return; + } + //+ + dfs(nums, S, index + 1, cS + nums[index]); + //- + dfs(nums, S, index + 1, cS - nums[index]); + } +} From cfe65b5470e032d34b022945d7fd712210c2aa77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 2 Sep 2019 21:08:36 +0800 Subject: [PATCH 165/308] docs: add _494_findTargetSumWays --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 60fabb8..ec90594 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成208道 +- leetcode练习,坚持每天一道,目前已完成209道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -23,7 +23,7 @@ - [x] [461. 汉明距离 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_461_hammingDistance.java) -- [ ] [494. 目标和 -Medium](https://leetcode-cn.com/problems/target-sum/) +- [x] [494. 目标和 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_494_findTargetSumWays.java) - [ ] [538. 把二叉搜索树转换为累加树 -Easy](https://leetcode-cn.com/problems/convert-bst-to-greater-tree/) @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成208) +### 题目列表(更新中—已完成209) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_461_hammingDistance.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_494_findTargetSumWays.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -252,6 +252,7 @@ | #460 | [LFU缓存](https://leetcode-cn.com/problems/lfu-cache/) | [LFUCache](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_460_LFUCache.java) | [设计](https://leetcode-cn.com/tag/design/) | Hard | | | #461 | [汉明距离](https://leetcode-cn.com/problems/hamming-distance/) | [HammingDistance](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_461_hammingDistance.java) | [位运算](https://leetcode-cn.com/tag/bit-manipulation/) | Easy | | | #485 | [最大连续1的个数](https://leetcode-cn.com/problems/max-consecutive-ones/) | [FindMaxConsecutiveOnes](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_485_findMaxConsecutiveOnes.java) | [数组]() | Easy | | +| #494 | [目标和](https://leetcode-cn.com/problems/target-sum/) | [FindTargetSumWays](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_494_findTargetSumWays.java) | [动态规划]()、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #516 | [最长回文子序列](https://leetcode-cn.com/problems/longest-palindromic-subsequence/) | [LongestPalindromeSubseq](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_516_longestPalindromeSubseq.java) | [动态规划]() | Medium | | | #538 | [把二叉搜索树转换为累加树](https://leetcode-cn.com/problems/convert-bst-to-greater-tree/) | [ConvertBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_538_convertBST.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | | #547 | [朋友圈](https://leetcode-cn.com/problems/friend-circles/) | [FindCircleNum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_547_findCircleNum_2.java) | [DFS](https://leetcode-cn.com/tag/depth-first-search/)、[并查集](https://leetcode-cn.com/tag/union-find/) | Medium | | From 888e2b6140471c4282dcaace96a87e8fbdf363df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 3 Sep 2019 21:48:27 +0800 Subject: [PATCH 166/308] docs: add _538_convertBST --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ec90594..828c637 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成209道 +- leetcode练习,坚持每天一道,目前已完成210道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -25,7 +25,7 @@ - [x] [494. 目标和 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_494_findTargetSumWays.java) -- [ ] [538. 把二叉搜索树转换为累加树 -Easy](https://leetcode-cn.com/problems/convert-bst-to-greater-tree/) +- [x] [538. 把二叉搜索树转换为累加树 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_538_convertBST.java) - [ ] [543. 二叉树的直径 -Easy](https://leetcode-cn.com/problems/diameter-of-binary-tree/) @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成209) +### 题目列表(更新中—已完成210) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_494_findTargetSumWays.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_538_convertBST.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | From 0279da7b1b86f439a7fa5138c0ba90f92c09b9dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 4 Sep 2019 10:47:11 +0800 Subject: [PATCH 167/308] feat(EASY): add _543_diameterOfBinaryTree --- .../leetcode/_543_diameterOfBinaryTree.java | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_543_diameterOfBinaryTree.java diff --git a/src/pp/arithmetic/leetcode/_543_diameterOfBinaryTree.java b/src/pp/arithmetic/leetcode/_543_diameterOfBinaryTree.java new file mode 100644 index 0000000..97ee3b0 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_543_diameterOfBinaryTree.java @@ -0,0 +1,68 @@ +package pp.arithmetic.leetcode; + +import javafx.util.Pair; +import pp.arithmetic.model.TreeNode; + +/** + * Created by wangpeng on 2019-09-03. + * 543. 二叉树的直径 + * + * 给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过根结点。 + * + * 示例 : + * 给定二叉树 + * + * 1 + * / \ + * 2 3 + * / \ + * 4 5 + * 返回 3, 它的长度是路径 [4,2,1,3] 或者 [5,2,1,3]。 + * + * 注意:两结点之间的路径长度是以它们之间边的数目表示。 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/diameter-of-binary-tree + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _543_diameterOfBinaryTree { + + public static void main(String[] args) { + _543_diameterOfBinaryTree diameterOfBinaryTree = new _543_diameterOfBinaryTree(); + TreeNode root = new TreeNode(1); + root.left = new TreeNode(2); + root.right = new TreeNode(3); + root.left.left = new TreeNode(4); + root.left.right = new TreeNode(5); + + System.out.println(diameterOfBinaryTree.diameterOfBinaryTree(root)); + + } + + private int ret = 0; + + /** + * 解题思路: + * 对于树的问题,正常思路就是遍历,此题也不例外 + * 如题所示,找到最长的路径,有两种可能: + * 一、根节点+左右子树节点 + * 二、根节点+最长的子树节点作为其父节点的子节点 + * 递归遍历过程中,用一个全局变量保存遍历过程中的最大值 + * + * @param root + * @return + */ + public int diameterOfBinaryTree(TreeNode root) { + dfs(root); + return ret; + } + + private int dfs(TreeNode root) { + if (root == null) return 0; + int left = dfs(root.left); + int right = dfs(root.right); + int count = left + right; + ret = Math.max(ret, count); + return Math.max(left, right) + 1; + } +} From 77fe16ac56db630974b301ec4ebdb89d1bbd6230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 4 Sep 2019 10:49:52 +0800 Subject: [PATCH 168/308] docs: add _543_diameterOfBinaryTree --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 828c637..efd6b8c 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成210道 +- leetcode练习,坚持每天一道,目前已完成211道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -27,7 +27,7 @@ - [x] [538. 把二叉搜索树转换为累加树 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_538_convertBST.java) -- [ ] [543. 二叉树的直径 -Easy](https://leetcode-cn.com/problems/diameter-of-binary-tree/) +- [x] [543. 二叉树的直径 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_543_diameterOfBinaryTree.java) ## 已解题目 @@ -62,9 +62,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成210) +### 题目列表(更新中—已完成211) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_538_convertBST.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_543_diameterOfBinaryTree.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -255,6 +255,7 @@ | #494 | [目标和](https://leetcode-cn.com/problems/target-sum/) | [FindTargetSumWays](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_494_findTargetSumWays.java) | [动态规划]()、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #516 | [最长回文子序列](https://leetcode-cn.com/problems/longest-palindromic-subsequence/) | [LongestPalindromeSubseq](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_516_longestPalindromeSubseq.java) | [动态规划]() | Medium | | | #538 | [把二叉搜索树转换为累加树](https://leetcode-cn.com/problems/convert-bst-to-greater-tree/) | [ConvertBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_538_convertBST.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | +| #543 | [二叉树的直径](https://leetcode-cn.com/problems/diameter-of-binary-tree/) | [DiameterOfBinaryTree](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_543_diameterOfBinaryTree.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | | #547 | [朋友圈](https://leetcode-cn.com/problems/friend-circles/) | [FindCircleNum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_547_findCircleNum_2.java) | [DFS](https://leetcode-cn.com/tag/depth-first-search/)、[并查集](https://leetcode-cn.com/tag/union-find/) | Medium | | | #563 | [二叉树的坡度](https://leetcode-cn.com/problems/binary-tree-tilt/) | [FindTilt](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_563_findTilt.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | | #567 | [字符串的排列](https://leetcode-cn.com/problems/permutation-in-string/) | [CheckInclusion](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_567_checkInclusion.java) | [双指针]() | Medium | | From 78721c4d4ddbc3e854b6ad15e6a7db9958738459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 4 Sep 2019 10:53:56 +0800 Subject: [PATCH 169/308] docs: update topic list --- README.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index efd6b8c..2cf8625 100644 --- a/README.md +++ b/README.md @@ -15,19 +15,17 @@ 扫题:热题 Hot 100 -- [x] [437. 路径总和 III -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_437_pathSum.java) +- [ ] [560. 和为K的子数组-Medium ](https://leetcode-cn.com/problems/subarray-sum-equals-k/) -- [x] [438. 找到字符串中所有字母异位词 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_438_findAnagrams.java) +- [ ] [581. 最短无序连续子数组 ——Easy](https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray/) -- [x] [448. 找到所有数组中消失的数字 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_448_findDisappearedNumbers.java) +- [ ] [617. 合并二叉树 -Easy](https://leetcode-cn.com/problems/merge-two-binary-trees/) -- [x] [461. 汉明距离 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_461_hammingDistance.java) +- [ ] [621. 任务调度器 -Medium](https://leetcode-cn.com/problems/task-scheduler/) -- [x] [494. 目标和 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_494_findTargetSumWays.java) +- [ ] [647. 回文子串 -Medium](https://leetcode-cn.com/problems/palindromic-substrings/) -- [x] [538. 把二叉搜索树转换为累加树 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_538_convertBST.java) - -- [x] [543. 二叉树的直径 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_543_diameterOfBinaryTree.java) +- [ ] [739. 每日温度 -Medium](https://leetcode-cn.com/problems/daily-temperatures/) ## 已解题目 From 2a45ed7430eb8c9141a079faf121b916ccc5f3b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 5 Sep 2019 11:34:14 +0800 Subject: [PATCH 170/308] feat(MEDIUM): add _560_subarraySum --- .../arithmetic/leetcode/_560_subarraySum.java | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_560_subarraySum.java diff --git a/src/pp/arithmetic/leetcode/_560_subarraySum.java b/src/pp/arithmetic/leetcode/_560_subarraySum.java new file mode 100644 index 0000000..15952ff --- /dev/null +++ b/src/pp/arithmetic/leetcode/_560_subarraySum.java @@ -0,0 +1,84 @@ +package pp.arithmetic.leetcode; + +import java.util.HashMap; + +/** + * Created by wangpeng on 2019-09-05. + * 560. 和为K的子数组 + *

+ * 给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。 + *

+ * 示例 1 : + *

+ * 输入:nums = [1,1,1], k = 2 + * 输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。 + * 说明 : + *

+ * 数组的长度为 [1, 20,000]。 + * 数组中元素的范围是 [-1000, 1000] ,且整数 k 的范围是 [-1e7, 1e7]。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/subarray-sum-equals-k + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _560_subarraySum { + + public static void main(String[] args) { + _560_subarraySum subarraySum = new _560_subarraySum(); + System.out.println(subarraySum.subarraySum(new int[]{1,1,1,1,1,1},2)); + System.out.println(subarraySum.subarraySum2(new int[]{1,1,1,1,1,1},2)); + } + + /** + * 解题思路: + * 由于数组中存在正数和负数,所以求和必须得所有的0-n之间的所有区间都得统计 + * 暴力就是三层循环,可以利用之前的计算结果 + * sum[i]保存0-i之间的和,求解i-j就使用sum[j]-sum[i] + * + * 执行用时 :488 ms, 在所有 Java 提交中击败了7.40%的用户 + * 内存消耗 :43.4 MB, 在所有 Java 提交中击败了71.76%的用户 + * + * @param nums + * @param k + * @return + */ + public int subarraySum(int[] nums, int k) { + int count = 0; + int[] sum = new int[nums.length + 1]; + sum[0] = 0; + for (int i = 1; i <= nums.length; i++) { + sum[i] = sum[i - 1] + nums[i - 1]; + } + for (int start = 0; start < nums.length; start++) { + for (int end = start + 1; end <= nums.length; end++) { + if (sum[end] - sum[start] == k) + count++; + } + } + return count; + } + + /** + * 优化求解: + * 核心思想:sum[i]代表0-i的总和,如果sum[i]-sum[j]==k,那么sum[j]对于的个数就是区间i-j的满足条件和 + * 使用一个map保存sum<->count之间的对应关系 + * O(n)复杂度就能找出结果 + * + * @param nums + * @param k + * @return + */ + public int subarraySum2(int[] nums, int k) { + int count = 0, sum = 0; + HashMap map = new HashMap<>(); + map.put(0, 1); + for (int i = 0; i < nums.length; i++) { + sum += nums[i]; + if (map.containsKey(sum - k)) + count += map.get(sum - k); + map.put(sum, map.getOrDefault(sum, 0) + 1); + } + return count; + + } +} From 3a611240098c0382fa585db4d1f9b8bd4d02911f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 5 Sep 2019 11:38:58 +0800 Subject: [PATCH 171/308] docs: add _560_subarraySum --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2cf8625..9e7f7ac 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成211道 +- leetcode练习,坚持每天一道,目前已完成212道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -15,7 +15,7 @@ 扫题:热题 Hot 100 -- [ ] [560. 和为K的子数组-Medium ](https://leetcode-cn.com/problems/subarray-sum-equals-k/) +- [x] [560. 和为K的子数组-Medium ](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_560_subarraySum.java) - [ ] [581. 最短无序连续子数组 ——Easy](https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray/) @@ -60,9 +60,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成211) +### 题目列表(更新中—已完成212) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_543_diameterOfBinaryTree.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_560_subarraySum.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -255,6 +255,7 @@ | #538 | [把二叉搜索树转换为累加树](https://leetcode-cn.com/problems/convert-bst-to-greater-tree/) | [ConvertBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_538_convertBST.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | | #543 | [二叉树的直径](https://leetcode-cn.com/problems/diameter-of-binary-tree/) | [DiameterOfBinaryTree](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_543_diameterOfBinaryTree.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | | #547 | [朋友圈](https://leetcode-cn.com/problems/friend-circles/) | [FindCircleNum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_547_findCircleNum_2.java) | [DFS](https://leetcode-cn.com/tag/depth-first-search/)、[并查集](https://leetcode-cn.com/tag/union-find/) | Medium | | +| #560 | [和为K的子数组](https://leetcode-cn.com/problems/subarray-sum-equals-k/) | [SubarraySum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_560_subarraySum.java) | [数组]()、[哈希表]() | Medium | | | #563 | [二叉树的坡度](https://leetcode-cn.com/problems/binary-tree-tilt/) | [FindTilt](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_563_findTilt.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | | #567 | [字符串的排列](https://leetcode-cn.com/problems/permutation-in-string/) | [CheckInclusion](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_567_checkInclusion.java) | [双指针]() | Medium | | | #639 | [解码方法 2](https://leetcode-cn.com/problems/decode-ways-ii/) | [NumDecodings](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_639_numDecodings.java) | [动态规划]() | Hard | | From 5f3859cd1a33ec0df43c6a75818c0d03211ec0ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 20 Sep 2019 10:25:52 +0800 Subject: [PATCH 172/308] feat(EASY): add _581_findUnsortedSubarray --- .../leetcode/_581_findUnsortedSubarray.java | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_581_findUnsortedSubarray.java diff --git a/src/pp/arithmetic/leetcode/_581_findUnsortedSubarray.java b/src/pp/arithmetic/leetcode/_581_findUnsortedSubarray.java new file mode 100644 index 0000000..eba7019 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_581_findUnsortedSubarray.java @@ -0,0 +1,62 @@ +package pp.arithmetic.leetcode; + +import java.util.Stack; + +/** + * Created by wangpeng on 2019-09-12. + * 581. 最短无序连续子数组 + *

+ * 给定一个整数数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。 + *

+ * 你找到的子数组应是最短的,请输出它的长度。 + *

+ * 示例 1: + *

+ * 输入: [2, 6, 4, 8, 10, 9, 15] + * 输出: 5 + * 解释: 你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。 + * 说明 : + *

+ * 输入的数组长度范围在 [1, 10,000]。 + * 输入的数组可能包含重复元素 ,所以升序的意思是<=。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _581_findUnsortedSubarray { + + public static void main(String[] args) { + _581_findUnsortedSubarray findUnsortedSubarray = new _581_findUnsortedSubarray(); + System.out.println(findUnsortedSubarray.findUnsortedSubarray(new int[]{2, 6, 4, 8, 10, 9, 15})); + System.out.println(findUnsortedSubarray.findUnsortedSubarray(new int[]{8, 6, 4, 8, 10, 9, 15})); + System.out.println(findUnsortedSubarray.findUnsortedSubarray(new int[]{2, 3, 3, 2, 4})); + System.out.println(findUnsortedSubarray.findUnsortedSubarray(new int[]{1, 3, 2, 2, 2})); + System.out.println(findUnsortedSubarray.findUnsortedSubarray(new int[]{1, 1})); + System.out.println(findUnsortedSubarray.findUnsortedSubarray(new int[]{1, 2, 4, 5, 3})); + } + + /** + * 解题思路: + * 核心是我们需要找到无序子数组中最小元素和最大元素分别对应的正确位置 + * + * @param nums + * @return + */ + public int findUnsortedSubarray(int[] nums) { + Stack stack = new Stack<>(); + int l = nums.length, r = 0; + for (int i = 0; i < nums.length; i++) { + while (!stack.isEmpty() && nums[stack.peek()] > nums[i]) + l = Math.min(l, stack.pop()); + stack.push(i); + } + stack.clear(); + for (int i = nums.length - 1; i >= 0; i--) { + while (!stack.isEmpty() && nums[stack.peek()] < nums[i]) + r = Math.max(r, stack.pop()); + stack.push(i); + } + return r - l > 0 ? r - l + 1 : 0; + } +} From 6104257471d5eed16b7ce8a9de50310c90099f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 20 Sep 2019 10:28:31 +0800 Subject: [PATCH 173/308] docs: add _581_findUnsortedSubarray --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9e7f7ac..59d9ae7 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) ## 说明 -- leetcode练习,坚持每天一道,目前已完成212道 +- leetcode练习,坚持每天一道,目前已完成213道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -17,7 +17,7 @@ - [x] [560. 和为K的子数组-Medium ](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_560_subarraySum.java) -- [ ] [581. 最短无序连续子数组 ——Easy](https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray/) +- [x] [581. 最短无序连续子数组 ——Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_581_findUnsortedSubarray.java) - [ ] [617. 合并二叉树 -Easy](https://leetcode-cn.com/problems/merge-two-binary-trees/) @@ -60,9 +60,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成212) +### 题目列表(更新中—已完成213) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_560_subarraySum.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_581_findUnsortedSubarray.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -258,6 +258,7 @@ | #560 | [和为K的子数组](https://leetcode-cn.com/problems/subarray-sum-equals-k/) | [SubarraySum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_560_subarraySum.java) | [数组]()、[哈希表]() | Medium | | | #563 | [二叉树的坡度](https://leetcode-cn.com/problems/binary-tree-tilt/) | [FindTilt](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_563_findTilt.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | | #567 | [字符串的排列](https://leetcode-cn.com/problems/permutation-in-string/) | [CheckInclusion](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_567_checkInclusion.java) | [双指针]() | Medium | | +| #581 | [最短无序连续子数组](https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray/) | [FindUnsortedSubarray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_581_findUnsortedSubarray.java) | [数组]() | Easy | | | #639 | [解码方法 2](https://leetcode-cn.com/problems/decode-ways-ii/) | [NumDecodings](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_639_numDecodings.java) | [动态规划]() | Hard | | | #653 | [两数之和 IV - 输入 BST](https://leetcode-cn.com/problems/two-sum-iv-input-is-a-bst/) | [FindTarget](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_653_findTarget.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | | #674 | [最长连续递增序列](https://leetcode-cn.com/problems/longest-continuous-increasing-subsequence/) | [FindLengthOfLCIS](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_674_findLengthOfLCIS_e.java) | [数组]() | Easy | | From 67ec4c5f8c01b2779e504203c3d7f815af749063 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 20 Sep 2019 10:44:34 +0800 Subject: [PATCH 174/308] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=E4=BA=A4?= =?UTF-8?q?=E6=B5=81=E7=BE=A4=E4=BA=8C=E7=BB=B4=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +++-- images/wxg.png | Bin 0 -> 168778 bytes 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 images/wxg.png diff --git a/README.md b/README.md index 59d9ae7..039ab37 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # LeetCode-Java -[![LICENSE](https://img.shields.io/badge/license-NPL%20(The%20996%20Prohibited%20License)-blue.svg)](https://github.com/996icu/996.ICU/blob/master/LICENSE) -[![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) +寻扣友,欢迎扫码入群!! + +![mmqrcode1568947296986](./images/wxg.png) ## 说明 - leetcode练习,坚持每天一道,目前已完成213道 diff --git a/images/wxg.png b/images/wxg.png new file mode 100644 index 0000000000000000000000000000000000000000..b9d9bc3191d962fdda47f752da1bd41d987716b2 GIT binary patch literal 168778 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≠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 literal 0 HcmV?d00001 From a3e03a44764b7f7c2384d091e7e84cd4ea0fe03f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 20 Sep 2019 11:00:17 +0800 Subject: [PATCH 175/308] feat(EASY): add _617_mergeTrees --- .../arithmetic/leetcode/_617_mergeTrees.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_617_mergeTrees.java diff --git a/src/pp/arithmetic/leetcode/_617_mergeTrees.java b/src/pp/arithmetic/leetcode/_617_mergeTrees.java new file mode 100644 index 0000000..ed51f40 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_617_mergeTrees.java @@ -0,0 +1,75 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; +import pp.arithmetic.model.TreeNode; + +/** + * Created by wangpeng on 2019-09-20. + * + * 给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。 + * + * 你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。 + * + * 示例 1: + * + * 输入: + * Tree 1 Tree 2 + * 1 2 + * / \ / \ + * 3 2 1 3 + * / \ \ + * 5 4 7 + * 输出: + * 合并后的树: + * 3 + * / \ + * 4 5 + * / \ \ + * 5 4 7 + * 注意: 合并必须从两个树的根节点开始。 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/merge-two-binary-trees + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _617_mergeTrees { + + public static void main(String[] args) { + TreeNode treeNode1 = new TreeNode(1); + treeNode1.left = new TreeNode(3); + treeNode1.right = new TreeNode(2); + treeNode1.left.left = new TreeNode(5); + TreeNode treeNode2 = new TreeNode(2); + treeNode2.left = new TreeNode(1); + treeNode2.left.right = new TreeNode(4); + treeNode2.right = new TreeNode(3); + treeNode2.right.right = new TreeNode(7); + _617_mergeTrees mergeTrees = new _617_mergeTrees(); + TreeNode treeNode = mergeTrees.mergeTrees(treeNode1, treeNode2); + Util.printTree(treeNode); + } + + /** + * 解题思路: + * 对于数的题目基本是DFS递归 + * 1、构建父节点,如t1、t2的不为null,使其加和 + * 2、构建子树节点,将t2、t2对应位置传递过去,重复步骤1 + * + * @param t1 + * @param t2 + * @return + */ + public TreeNode mergeTrees(TreeNode t1, TreeNode t2) { + if (t1 == null && t2 == null) { + return null; + } + //1、构建父节点 + TreeNode node = new TreeNode(0); + if (t1 != null) node.val += t1.val; + if (t2 != null) node.val += t2.val; + //2、构建子树节点 + node.left = mergeTrees(t1 == null ? null : t1.left, t2 == null ? null : t2.left); + node.right = mergeTrees(t1 == null ? null : t1.right, t2 == null ? null : t2.right); + return node; + } +} From a0fb1cb50ef694d5e95136358725a4d8426b61d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 20 Sep 2019 11:03:20 +0800 Subject: [PATCH 176/308] docs: add _617_mergeTrees --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 039ab37..aa2cbeb 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ![mmqrcode1568947296986](./images/wxg.png) ## 说明 -- leetcode练习,坚持每天一道,目前已完成213道 +- leetcode练习,坚持每天一道,目前已完成214道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -20,7 +20,7 @@ - [x] [581. 最短无序连续子数组 ——Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_581_findUnsortedSubarray.java) -- [ ] [617. 合并二叉树 -Easy](https://leetcode-cn.com/problems/merge-two-binary-trees/) +- [x] [617. 合并二叉树 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_617_mergeTrees.java) - [ ] [621. 任务调度器 -Medium](https://leetcode-cn.com/problems/task-scheduler/) @@ -61,9 +61,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成213) +### 题目列表(更新中—已完成214) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_581_findUnsortedSubarray.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_617_mergeTrees.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -260,6 +260,7 @@ | #563 | [二叉树的坡度](https://leetcode-cn.com/problems/binary-tree-tilt/) | [FindTilt](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_563_findTilt.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | | #567 | [字符串的排列](https://leetcode-cn.com/problems/permutation-in-string/) | [CheckInclusion](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_567_checkInclusion.java) | [双指针]() | Medium | | | #581 | [最短无序连续子数组](https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray/) | [FindUnsortedSubarray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_581_findUnsortedSubarray.java) | [数组]() | Easy | | +| #617 | [合并二叉树](https://leetcode-cn.com/problems/merge-two-binary-trees/) | [MergeTrees](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_617_mergeTrees.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | | #639 | [解码方法 2](https://leetcode-cn.com/problems/decode-ways-ii/) | [NumDecodings](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_639_numDecodings.java) | [动态规划]() | Hard | | | #653 | [两数之和 IV - 输入 BST](https://leetcode-cn.com/problems/two-sum-iv-input-is-a-bst/) | [FindTarget](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_653_findTarget.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | | #674 | [最长连续递增序列](https://leetcode-cn.com/problems/longest-continuous-increasing-subsequence/) | [FindLengthOfLCIS](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_674_findLengthOfLCIS_e.java) | [数组]() | Easy | | From 1baf337d0917729e313678c2d4960a01944d1b09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 25 Sep 2019 14:03:47 +0800 Subject: [PATCH 177/308] feat(MEDIUM): add _621_leastInterval --- README.md | 6 +- .../leetcode/_621_leastInterval.java | 73 +++++++++++++++++++ 2 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 src/pp/arithmetic/leetcode/_621_leastInterval.java diff --git a/README.md b/README.md index aa2cbeb..3e7d142 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,4 @@ # LeetCode-Java -寻扣友,欢迎扫码入群!! - -![mmqrcode1568947296986](./images/wxg.png) - ## 说明 - leetcode练习,坚持每天一道,目前已完成214道 - 解题语言是Java @@ -276,6 +272,8 @@ | #1053 | [交换一次的先前排列](https://leetcode-cn.com/problems/previous-permutation-with-one-swap/) | [PrevPermOpt](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1053_prevPermOpt1.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Medium | | | #1054 | [距离相等的条形码](https://leetcode-cn.com/problems/distant-barcodes/) | [RearrangeBarcodes](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1054_rearrangeBarcodes.java) | [堆](https://leetcode-cn.com/tag/heap/)、[排序](https://leetcode-cn.com/tag/sort/) | Medium | | +寻扣友,欢迎扫码入群!! +![mmqrcode1568947296986](./images/wxg.png) diff --git a/src/pp/arithmetic/leetcode/_621_leastInterval.java b/src/pp/arithmetic/leetcode/_621_leastInterval.java new file mode 100644 index 0000000..166fd3f --- /dev/null +++ b/src/pp/arithmetic/leetcode/_621_leastInterval.java @@ -0,0 +1,73 @@ +package pp.arithmetic.leetcode; + +import java.util.Arrays; +import java.util.Comparator; + +/** + * Created by wangpeng on 2019-09-25. + * 621. 任务调度器 + *

+ * 给定一个用字符数组表示的 CPU 需要执行的任务列表。其中包含使用大写的 A - Z 字母表示的26 种不同种类的任务。任务可以以任意顺序执行, + * 并且每个任务都可以在 1 个单位时间内执行完。CPU 在任何一个单位时间内都可以执行一个任务,或者在待命状态。 + *

+ * 然而,两个相同种类的任务之间必须有长度为 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。 + *

+ * 你需要计算完成所有任务所需要的最短时间。 + *

+ * 示例 1: + *

+ * 输入: tasks = ["A","A","A","B","B","B"], n = 2 + * 输出: 8 + * 执行顺序: A -> B -> (待命) -> A -> B -> (待命) -> A -> B. + * 注: + *

+ * 任务的总个数为 [1, 10000]。 + * n 的取值范围为 [0, 100]。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/task-scheduler + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _621_leastInterval { + + public static void main(String[] args) { + _621_leastInterval leastInterval = new _621_leastInterval(); + System.out.println(leastInterval.leastInterval(new char[]{'A', 'A', 'A', 'B', 'B', 'B'}, 2)); + System.out.println(leastInterval.leastInterval(new char[]{'A', 'A', 'A', 'B', 'B', 'C', 'C', 'D', 'E'}, 2)); + System.out.println(leastInterval.leastInterval(new char[]{'A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C', 'D', 'D', 'D'}, 2)); + } + + /** + * 解题思路: + * 1、将任务按类型分组,正好A-Z用一个int[26]保存任务类型个数 + * 2、对数组进行排序,优先排列个数(count)最大的任务, + * 如题得到的时间至少为 retCount =(count-1)* (n+1) + 1 ==> A->X->X->A->X->X->A(X为其他任务或者待命) + * 3、再排序下一个任务,如果下一个任务B个数和最大任务数一致, + * 则retCount++ ==> A->B->X->A->B->X->A->B + * 4、如果空位都插满之后还有任务,那就随便在这些间隔里面插入就可以,因为间隔长度肯定会大于n,在这种情况下就是任务的总数是最小所需时间 + * + * @param tasks + * @param n + * @return + */ + public int leastInterval(char[] tasks, int n) { + if (tasks.length <= 1 || n < 1) return tasks.length; + //步骤1 + int[] counts = new int[26]; + for (int i = 0; i < tasks.length; i++) { + counts[tasks[i] - 'A']++; + } + //步骤2 + Arrays.sort(counts); + int maxCount = counts[25]; + int retCount = (maxCount - 1) * (n + 1) + 1; + int i = 24; + //步骤3 + while (i >= 0 && counts[i] == maxCount) { + retCount++; + i--; + } + //步骤4 + return Math.max(retCount, tasks.length); + } +} From 3e60c81fecd0dfb33d2ed5df12ba74ccf339c743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 25 Sep 2019 14:08:46 +0800 Subject: [PATCH 178/308] docs: add _621_leastInterval --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3e7d142..4f52e8c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成214道 +- leetcode练习,坚持每天一道,目前已完成215道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -18,7 +18,7 @@ - [x] [617. 合并二叉树 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_617_mergeTrees.java) -- [ ] [621. 任务调度器 -Medium](https://leetcode-cn.com/problems/task-scheduler/) +- [x] [621. 任务调度器 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_621_leastInterval.java) - [ ] [647. 回文子串 -Medium](https://leetcode-cn.com/problems/palindromic-substrings/) @@ -57,9 +57,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成214) +### 题目列表(更新中—已完成215) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_617_mergeTrees.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_621_leastInterval.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -257,6 +257,7 @@ | #567 | [字符串的排列](https://leetcode-cn.com/problems/permutation-in-string/) | [CheckInclusion](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_567_checkInclusion.java) | [双指针]() | Medium | | | #581 | [最短无序连续子数组](https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray/) | [FindUnsortedSubarray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_581_findUnsortedSubarray.java) | [数组]() | Easy | | | #617 | [合并二叉树](https://leetcode-cn.com/problems/merge-two-binary-trees/) | [MergeTrees](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_617_mergeTrees.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | +| #621 | [任务调度器](https://leetcode-cn.com/problems/task-scheduler/) | [LeastInterval](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_621_leastInterval.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[队列]()、[数组]() | Medium | | | #639 | [解码方法 2](https://leetcode-cn.com/problems/decode-ways-ii/) | [NumDecodings](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_639_numDecodings.java) | [动态规划]() | Hard | | | #653 | [两数之和 IV - 输入 BST](https://leetcode-cn.com/problems/two-sum-iv-input-is-a-bst/) | [FindTarget](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_653_findTarget.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | | #674 | [最长连续递增序列](https://leetcode-cn.com/problems/longest-continuous-increasing-subsequence/) | [FindLengthOfLCIS](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_674_findLengthOfLCIS_e.java) | [数组]() | Easy | | From a079c49abd7600cbd080d00481808b76ba06c003 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 26 Sep 2019 13:39:31 +0800 Subject: [PATCH 179/308] feat(MEDIUM): add _647_countSubstrings --- .../leetcode/_647_countSubstrings.java | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_647_countSubstrings.java diff --git a/src/pp/arithmetic/leetcode/_647_countSubstrings.java b/src/pp/arithmetic/leetcode/_647_countSubstrings.java new file mode 100644 index 0000000..9d26fb7 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_647_countSubstrings.java @@ -0,0 +1,138 @@ +package pp.arithmetic.leetcode; + +import java.util.Stack; + +/** + * Created by wangpeng on 2019-09-26. + * 647. 回文子串 + *

+ * 给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。 + *

+ * 具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被计为是不同的子串。 + *

+ * 示例 1: + *

+ * 输入: "abc" + * 输出: 3 + * 解释: 三个回文子串: "a", "b", "c". + * 示例 2: + *

+ * 输入: "aaa" + * 输出: 6 + * 说明: 6个回文子串: "a", "a", "a", "aa", "aa", "aaa". + * 注意: + *

+ * 输入的字符串长度不会超过1000。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/palindromic-substrings + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _647_countSubstrings { + public static void main(String[] args) { + _647_countSubstrings countSubstrings = new _647_countSubstrings(); + //1 + System.out.println(countSubstrings.countSubstrings("abc")); + System.out.println(countSubstrings.countSubstrings("aaa")); + System.out.println(countSubstrings.countSubstrings("abab")); + //2 + System.out.println(countSubstrings.countSubstrings2("abc")); + System.out.println(countSubstrings.countSubstrings2("aaa")); + System.out.println(countSubstrings.countSubstrings2("abab")); + //3 + System.out.println(countSubstrings.countSubstrings3("abc")); + System.out.println(countSubstrings.countSubstrings3("aaa")); + System.out.println(countSubstrings.countSubstrings3("abab")); + + } + + /** + * 解法一: + * 定义两个指针,从0到len判断所有的回文可能性,性能不一定高,结果一定对(时间复杂度O(n^3)) + * 执行用时 :116 ms, 在所有 Java 提交中击败了12.26%的用户 + * 内存消耗 :34.3 MB, 在所有 Java 提交中击败了92.34%的用户 + *

+ * 解法二:{@link _647_countSubstrings#countSubstrings2(String)} + * + * @param s + * @return + */ + public int countSubstrings(String s) { + int retCount = 0; + int start, end; + for (start = 0; start < s.length(); start++) { + for (end = start; end < s.length(); end++) { + if (isPalindrome(s, start, end)) { + retCount++; + } + } + } + + return retCount; + } + + private boolean isPalindrome(String s, int start, int end) { + while (start <= end) { + if (s.charAt(start) != s.charAt(end)) { + return false; + } + start++; + end--; + } + return true; + } + + /** + * 解法二:中心扩展==>时间复杂度O(n^2) + * 从中心(区分1个点的中心还是两个点的中心)向两边同时扩散,如左右两边都相等则是回文,继续扩散 + * + * 执行用时 :2 ms , 在所有 Java 提交中击败了99.02%的用户 + * 内存消耗 :34 MB, 在所有 Java 提交中击败了92.79%的用户 + * + * @param s + * @return + */ + public int countSubstrings2(String s) { + int res = 0; + for (int i = 0; i < s.length(); i++) { + //分奇偶考虑 + res += countSegment(s, i, i); + res += countSegment(s, i, i + 1); + } + return res; + } + + //start往左边跑,end往右边跑, 判断s[start, end]是否为回文 + public int countSegment(String s, int start, int end) { + int count = 0; + while (start >= 0 && end < s.length() && s.charAt(start--) == s.charAt(end++)) + count++; + return count; + } + + /** + * 解法三:动态规划==>时间复杂度O(n^2) + * 基本原理同解法二,只是用动态规划的方式求解出来了 + * + * 执行用时 :11 ms, 在所有 Java 提交中击败了47.66%的用户 + * 内存消耗 :35.6 MB, 在所有 Java 提交中击败了86.94%的用户 + * @param s + * @return + */ + public static int countSubstrings3(String s) { + int result = 0; + boolean[][] dp = new boolean[s.length()][s.length()]; + + for (int i = s.length()-1; i >=0 ; i--) { + for (int j = i; j < s.length(); j++) { + if (i==j) + dp[i][j] = true; + else + dp[i][j] = s.charAt(i)==s.charAt(j) && (j<=i+1 || dp[i+1][j-1]); + if (dp[i][j]) result++; + } + } + + return result; + } +} From 8c521a36ee720a4bed3ecd4e8341824b7ca012e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 26 Sep 2019 13:44:03 +0800 Subject: [PATCH 180/308] docs: add _647_countSubstrings --- README.md | 15 ++++++--------- .../arithmetic/leetcode/_647_countSubstrings.java | 2 ++ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 4f52e8c..0758ae7 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成215道 +- leetcode练习,坚持每天一道,目前已完成216道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 - 每道题会尽量分析一下解题步骤和复杂度 - 欢迎star、fork、交流,一起互勉 -- 微信号:pp_hdsny(备注leetcode) +- 微信号:pp_hdsny(寻扣友,备注leetcode) - 网址:https://leetcode-cn.com/ ## 待解题目列表 @@ -20,7 +20,7 @@ - [x] [621. 任务调度器 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_621_leastInterval.java) -- [ ] [647. 回文子串 -Medium](https://leetcode-cn.com/problems/palindromic-substrings/) +- [x] [647. 回文子串 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_647_countSubstrings.java) - [ ] [739. 每日温度 -Medium](https://leetcode-cn.com/problems/daily-temperatures/) @@ -57,9 +57,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成215) +### 题目列表(更新中—已完成216) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_621_leastInterval.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_647_countSubstrings.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -259,6 +259,7 @@ | #617 | [合并二叉树](https://leetcode-cn.com/problems/merge-two-binary-trees/) | [MergeTrees](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_617_mergeTrees.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | | #621 | [任务调度器](https://leetcode-cn.com/problems/task-scheduler/) | [LeastInterval](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_621_leastInterval.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[队列]()、[数组]() | Medium | | | #639 | [解码方法 2](https://leetcode-cn.com/problems/decode-ways-ii/) | [NumDecodings](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_639_numDecodings.java) | [动态规划]() | Hard | | +| #647 | [回文子串](https://leetcode-cn.com/problems/palindromic-substrings/) | [CountSubstrings](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_647_countSubstrings.java) | [字符串]()、[动态规划]() | Medium | | | #653 | [两数之和 IV - 输入 BST](https://leetcode-cn.com/problems/two-sum-iv-input-is-a-bst/) | [FindTarget](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_653_findTarget.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | | #674 | [最长连续递增序列](https://leetcode-cn.com/problems/longest-continuous-increasing-subsequence/) | [FindLengthOfLCIS](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_674_findLengthOfLCIS_e.java) | [数组]() | Easy | | | #695 | [岛屿的最大面积](https://leetcode-cn.com/problems/max-area-of-island/) | [MaxAreaOfIsland](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_695_maxAreaOfIsland.java) | [DFS](https://leetcode-cn.com/tag/depth-first-search/)、[数组]() | Medium | | @@ -273,8 +274,4 @@ | #1053 | [交换一次的先前排列](https://leetcode-cn.com/problems/previous-permutation-with-one-swap/) | [PrevPermOpt](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1053_prevPermOpt1.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Medium | | | #1054 | [距离相等的条形码](https://leetcode-cn.com/problems/distant-barcodes/) | [RearrangeBarcodes](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1054_rearrangeBarcodes.java) | [堆](https://leetcode-cn.com/tag/heap/)、[排序](https://leetcode-cn.com/tag/sort/) | Medium | | -寻扣友,欢迎扫码入群!! - -![mmqrcode1568947296986](./images/wxg.png) - diff --git a/src/pp/arithmetic/leetcode/_647_countSubstrings.java b/src/pp/arithmetic/leetcode/_647_countSubstrings.java index 9d26fb7..3b02804 100644 --- a/src/pp/arithmetic/leetcode/_647_countSubstrings.java +++ b/src/pp/arithmetic/leetcode/_647_countSubstrings.java @@ -54,6 +54,8 @@ public static void main(String[] args) { *

* 解法二:{@link _647_countSubstrings#countSubstrings2(String)} * + * 解法三:{@link _647_countSubstrings#countSubstrings3(String)} + * * @param s * @return */ From 5f9f0ccde0cc07050564e34bfb621a1232a99f56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 27 Sep 2019 11:05:13 +0800 Subject: [PATCH 181/308] feat(MEDIUM): add _739_dailyTemperatures --- .../leetcode/_739_dailyTemperatures.java | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_739_dailyTemperatures.java diff --git a/src/pp/arithmetic/leetcode/_739_dailyTemperatures.java b/src/pp/arithmetic/leetcode/_739_dailyTemperatures.java new file mode 100644 index 0000000..147f217 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_739_dailyTemperatures.java @@ -0,0 +1,88 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +/** + * Created by wangpeng on 2019-09-27. + * 739. 每日温度 + * + * 根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高超过该日的天数。如果之后都不会升高,请在该位置用 0 来代替。 + * + * 例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。 + * + * 提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/daily-temperatures + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _739_dailyTemperatures { + + public static void main(String[] args) { + _739_dailyTemperatures dailyTemperatures = new _739_dailyTemperatures(); + Util.printArray(dailyTemperatures.dailyTemperatures(new int[]{73, 74, 75, 71, 69, 72, 76, 73})); + Util.printArray(dailyTemperatures.dailyTemperatures2(new int[]{73, 74, 75, 71, 69, 72, 76, 73})); + } + + /** + * 解题思路: + * 暴力求解,每计算一位都向后遍历求出大于其的首位位置 ==>时间复杂度O(n^2) + * 执行用时 :247 ms, 在所有 Java 提交中击败了32.89%的用户 + * 内存消耗 :42 MB, 在所有 Java 提交中击败了 95.19%的用户 + * + * 优化求解:{@link _739_dailyTemperatures#dailyTemperatures2(int[])} + * + * @param T + * @return + */ + public int[] dailyTemperatures(int[] T) { + int[] ret = new int[T.length]; + for (int i = 0; i < T.length; i++) { + for (int j = i+1; j < T.length; j++) { + if (T[j]>T[i]){ + ret[i] = j-i; + break; + } + } + } + + return ret; + } + + /** + * 优化求解: + * 对于求解一来说,存在大量的重复计算,考虑是否可以利用之前的计算结果? + * 1、换个方向进行遍历,从右向左,对于最后一位来说肯定为0 + * 2、对于下一位,如 > 后一位则看后一位对应的是否有大于其的温度,如有则跳到该位置,继续步骤2 + * 3、如下一位 < 后一位,则直接标记为位置的差值 + * 4、如碰到某个位置对应的最大温度数为0,则表示后面不会有更大的值,那当然当前值就应该也为0 + * + * 执行用时 :5 ms, 在所有 Java 提交中击败了99.86%的用户 + * 内存消耗 :42 MB, 在所有 Java 提交中击败了95.19%的用户 + * + * @param T + * @return + */ + public int[] dailyTemperatures2(int[] T) { + int length = T.length; + int[] ret = new int[length]; + + //1 + for (int i = length - 2; i >= 0; i--) { + //2 += ret[j] + for (int j = i + 1; j < length; j+= ret[j]) { + if (T[j] > T[i]) { + //3 + ret[i] = j - i; + break; + } else if (ret[j] == 0) { //4 + ret[i] = 0; + break; + } + } + } + + return ret; + + } +} From 8636655746cd690189629f89e0420bab46a13d95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 27 Sep 2019 11:09:01 +0800 Subject: [PATCH 182/308] docs: add _739_dailyTemperatures --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0758ae7..926f3af 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成216道 +- leetcode练习,坚持每天一道,目前已完成217道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -22,7 +22,7 @@ - [x] [647. 回文子串 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_647_countSubstrings.java) -- [ ] [739. 每日温度 -Medium](https://leetcode-cn.com/problems/daily-temperatures/) +- [x] [739. 每日温度 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_739_dailyTemperatures.java) ## 已解题目 @@ -57,9 +57,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成216) +### 题目列表(更新中—已完成217) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_647_countSubstrings.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_739_dailyTemperatures.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | remark | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -263,6 +263,7 @@ | #653 | [两数之和 IV - 输入 BST](https://leetcode-cn.com/problems/two-sum-iv-input-is-a-bst/) | [FindTarget](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_653_findTarget.java) | [树](https://leetcode-cn.com/tag/tree/) | Easy | | | #674 | [最长连续递增序列](https://leetcode-cn.com/problems/longest-continuous-increasing-subsequence/) | [FindLengthOfLCIS](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_674_findLengthOfLCIS_e.java) | [数组]() | Easy | | | #695 | [岛屿的最大面积](https://leetcode-cn.com/problems/max-area-of-island/) | [MaxAreaOfIsland](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_695_maxAreaOfIsland.java) | [DFS](https://leetcode-cn.com/tag/depth-first-search/)、[数组]() | Medium | | +| #739 | [每日温度](https://leetcode-cn.com/problems/daily-temperatures/) | [DailyTemperatures](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_739_dailyTemperatures.java) | [数组]()、[哈希表]() | Medium | | | #746 | [使用最小花费爬楼梯](https://leetcode-cn.com/problems/min-cost-climbing-stairs/) | [MinCostClimbingStairs](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_746_minCostClimbingStairs.java) | [数组]()、[动态规划]() | Easy | | | #978 | [最长湍流子数组](https://leetcode-cn.com/problems/longest-turbulent-subarray/) | [MaxTurbulenceSize](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_978_maxTurbulenceSize.java) | [数组]()、[动态规划]()、[sliding window]() | Medium | | | #1004 | [最大连续1的个数 III](https://leetcode-cn.com/problems/max-consecutive-ones-iii/) | [LongestOnes](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1004_longestOnes.java) | [双指针]()、[sliding window]() | Medium | | From 991200a03e6ebb0a4c8c71c4cab686c0e0a3d5e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 27 Sep 2019 11:22:21 +0800 Subject: [PATCH 183/308] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=E5=8A=9B?= =?UTF-8?q?=E6=89=A3=E6=9D=AF=E9=A2=98=E7=9B=AE=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 926f3af..4ab21df 100644 --- a/README.md +++ b/README.md @@ -10,19 +10,17 @@ - 网址:https://leetcode-cn.com/ ## 待解题目列表 -扫题:热题 Hot 100 +扫题:力扣杯 -- [x] [560. 和为K的子数组-Medium ](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_560_subarraySum.java) +- [ ] [LCP 2. 分式化简 -Easy](https://leetcode-cn.com/problems/deep-dark-fraction/) -- [x] [581. 最短无序连续子数组 ——Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_581_findUnsortedSubarray.java) +- [ ] [LCP 4. 覆盖 -Hard](https://leetcode-cn.com/problems/broken-board-dominoes/) -- [x] [617. 合并二叉树 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_617_mergeTrees.java) +- [ ] [LCP 5. 发 LeetCoin -Hard](https://leetcode-cn.com/problems/coin-bonus/) -- [x] [621. 任务调度器 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_621_leastInterval.java) +- [ ] [LCP 3. 机器人大冒险 -Medium](https://leetcode-cn.com/problems/programmable-robot/) -- [x] [647. 回文子串 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_647_countSubstrings.java) - -- [x] [739. 每日温度 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_739_dailyTemperatures.java) +- [ ] [LCP 1. 猜数字 -Easy](https://leetcode-cn.com/problems/guess-numbers/) ## 已解题目 From 1708cc27bf18b74ccd11332ce6a840a4edcfe9a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 8 Oct 2019 16:12:48 +0800 Subject: [PATCH 184/308] feat(EASY): add LCP_2_fraction --- src/pp/arithmetic/LCP/_2_fraction.java | 89 ++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 src/pp/arithmetic/LCP/_2_fraction.java diff --git a/src/pp/arithmetic/LCP/_2_fraction.java b/src/pp/arithmetic/LCP/_2_fraction.java new file mode 100644 index 0000000..fd9815d --- /dev/null +++ b/src/pp/arithmetic/LCP/_2_fraction.java @@ -0,0 +1,89 @@ +package pp.arithmetic.LCP; + +import pp.arithmetic.Util; + +/** + * Created by wangpeng on 2019-09-30. + * LCP 2. 分式化简 + *

+ * 有一个同学在学习分式。他需要将一个连分数化成最简分数,你能帮助他吗? + *

+ * https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2019/09/09/fraction_example_1.jpg + *

+ * 连分数是形如上图的分式。在本题中,所有系数都是大于等于0的整数。 + *

+ *   + *

+ * 输入的cont代表连分数的系数(cont[0]代表上图的a0,以此类推)。返回一个长度为2的数组[n, m],使得连分数的值等于n / m,且n, m最大公约数为1。 + *

+ *   + *

+ * 示例 1: + *

+ * 输入:cont = [3, 2, 0, 2] + * 输出:[13, 4] + * 解释:原连分数等价于3 + (1 / (2 + (1 / (0 + 1 / 2))))。注意[26, 8], [-13, -4]都不是正确答案。 + * 示例 2: + *

+ * 输入:cont = [0, 0, 3] + * 输出:[3, 1] + * 解释:如果答案是整数,令分母为1即可。 + * 限制: + *

+ * cont[i] >= 0 + * 1 <= cont的长度 <= 10 + * cont最后一个元素不等于0 + * 答案的n, m的取值都能被32位int整型存下(即不超过2 ^ 31 - 1)。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/deep-dark-fraction + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _2_fraction { + + public static void main(String[] args) { + _2_fraction fraction = new _2_fraction(); + Util.printArray(fraction.fraction(new int[]{3, 2, 0, 2})); + Util.printArray(fraction.fraction(new int[]{0, 0, 3})); + Util.printArray(fraction.fraction(new int[]{3})); + } + + /** + * 解题思路: + * 对整个题目比划比划你会发现,整个解题的过程就是个循环求解分式,为了更好的写代码,逆向求解 + * 1、定义一个length为2的数组result,第一位是分子,第二位是分母 + * 2、逆向遍历数组 + * 3、对于第一位,result[0]=1,result[1]=item + * 4、分式对下一位相加,直接分母*该值加到分子上,并将分子分母求导数 + * 5、由于是逆向求解,还需要对最终结果进行求导数 + * + * @param cont + * @return + */ + public int[] fraction(int[] cont) { + //1 + int[] result = new int[2]; + //2 + for (int i = cont.length - 1; i >= 0; i--) { + int item = cont[i]; + if (result[0] == 0 && result[1] == 0) { + //3 + result[0] = 1; + result[1] = item; + } else { + //4 + result[0] += result[1] * item; + swap(result); + } + } + //5 + swap(result); + return result; + } + + private void swap(int[] arr) { + int temp = arr[0]; + arr[0] = arr[1]; + arr[1] = temp; + } +} From 866dcd8b85cc22bd289c7e5440ded7117ef030c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 8 Oct 2019 16:17:07 +0800 Subject: [PATCH 185/308] docs: add _2_fraction --- README.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4ab21df..dad3baf 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成217道 +- leetcode练习,坚持每天一道,目前已完成218道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -12,7 +12,7 @@ 扫题:力扣杯 -- [ ] [LCP 2. 分式化简 -Easy](https://leetcode-cn.com/problems/deep-dark-fraction/) +- [x] [LCP 2. 分式化简 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_2_fraction.java) - [ ] [LCP 4. 覆盖 -Hard](https://leetcode-cn.com/problems/broken-board-dominoes/) @@ -55,11 +55,11 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成217) +### 题目列表(更新中—已完成218) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_739_dailyTemperatures.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_2_fraction.java) -| No | 题目 | 解决方案 | 相关话题 | 难度 | remark | +| No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | | #1 | [两数之和](https://leetcode-cn.com/problems/two-sum) | [TwoSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1_twoSum.java) | [数组]()、[哈希表]() | Easy | | | #2 | [两数相加](https://leetcode-cn.com/problems/add-two-numbers/) | [AddTwoNumbers](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_2_addTwoNumbers.java) | [数组]()、[数学]() | Easy | | @@ -273,4 +273,9 @@ | #1053 | [交换一次的先前排列](https://leetcode-cn.com/problems/previous-permutation-with-one-swap/) | [PrevPermOpt](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1053_prevPermOpt1.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Medium | | | #1054 | [距离相等的条形码](https://leetcode-cn.com/problems/distant-barcodes/) | [RearrangeBarcodes](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1054_rearrangeBarcodes.java) | [堆](https://leetcode-cn.com/tag/heap/)、[排序](https://leetcode-cn.com/tag/sort/) | Medium | | +LCP + +| No | 题目 | 解决方案 | 难度 | +| ---- | ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | +| #2 | [LCP 2. 分式化简](https://leetcode-cn.com/problems/deep-dark-fraction/) | [Fraction](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_2_fraction.java) | Easy | From bac550945ad0b52b11676e96d93b0d2bac5c4002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 9 Oct 2019 11:18:15 +0800 Subject: [PATCH 186/308] feat(EASY): add LCP_1_game --- src/pp/arithmetic/LCP/_1_game.java | 65 ++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/pp/arithmetic/LCP/_1_game.java diff --git a/src/pp/arithmetic/LCP/_1_game.java b/src/pp/arithmetic/LCP/_1_game.java new file mode 100644 index 0000000..be1b35e --- /dev/null +++ b/src/pp/arithmetic/LCP/_1_game.java @@ -0,0 +1,65 @@ +package pp.arithmetic.LCP; + +/** + * Created by wangpeng on 2019-10-09. + * LCP 1. 猜数字 + * + * 小A 和 小B 在玩猜数字。小B 每次从 1, 2, 3 中随机选择一个,小A 每次也从 1, 2, 3 中选择一个猜。他们一共进行三次这个游戏,请返回 小A 猜对了几次? + * + *   + * + * 输入的guess数组为 小A 每次的猜测,answer数组为 小B 每次的选择。guess和answer的长度都等于3。 + * + *   + * + * 示例 1: + * + * 输入:guess = [1,2,3], answer = [1,2,3] + * 输出:3 + * 解释:小A 每次都猜对了。 + *   + * + * 示例 2: + * + * 输入:guess = [2,2,3], answer = [3,2,1] + * 输出:1 + * 解释:小A 只猜对了第二次。 + *   + * + * 限制: + * + * guess的长度 = 3 + * answer的长度 = 3 + * guess的元素取值为 {1, 2, 3} 之一。 + * answer的元素取值为 {1, 2, 3} 之一。 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/guess-numbers + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _1_game { + + public static void main(String[] args) { + _1_game game = new _1_game(); + System.out.println(game.game(new int[]{1, 2, 3}, new int[]{1, 2, 3})); + System.out.println(game.game(new int[]{2, 2, 3}, new int[]{3, 2, 1})); + } + + /** + * 解题思路: + * 最简单的循环比较是否相等即可 + * + * @param guess + * @param answer + * @return + */ + public int game(int[] guess, int[] answer) { + int ret = 0; + for (int i = 0; i < guess.length; i++) { + if (guess[i] == answer[i]) { + ret++; + } + } + return ret; + } +} From 3b4fb647c5dc0a9b5ec1aceb8544971f69ef358d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 9 Oct 2019 11:21:14 +0800 Subject: [PATCH 187/308] docs: add LCP_1_game --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index dad3baf..08fc636 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成218道 +- leetcode练习,坚持每天一道,目前已完成219道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -20,7 +20,7 @@ - [ ] [LCP 3. 机器人大冒险 -Medium](https://leetcode-cn.com/problems/programmable-robot/) -- [ ] [LCP 1. 猜数字 -Easy](https://leetcode-cn.com/problems/guess-numbers/) +- [x] [LCP 1. 猜数字 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_1_game.java) ## 已解题目 @@ -55,9 +55,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成218) +### 题目列表(更新中—已完成219) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_2_fraction.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_1_game.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -277,5 +277,6 @@ LCP | No | 题目 | 解决方案 | 难度 | | ---- | ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | +| #1 | [LCP 1. 猜数字](https://leetcode-cn.com/problems/guess-numbers/) | [Game](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_1_game.java) | Easy | | #2 | [LCP 2. 分式化简](https://leetcode-cn.com/problems/deep-dark-fraction/) | [Fraction](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_2_fraction.java) | Easy | From 88b1fff9f6462bcc05d2da0c9bdb4d13da0edb55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 11 Oct 2019 11:05:49 +0800 Subject: [PATCH 188/308] feat(MEDIUM): add LCP_3_robot --- src/pp/arithmetic/LCP/_3_robot.java | 165 ++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 src/pp/arithmetic/LCP/_3_robot.java diff --git a/src/pp/arithmetic/LCP/_3_robot.java b/src/pp/arithmetic/LCP/_3_robot.java new file mode 100644 index 0000000..152cac0 --- /dev/null +++ b/src/pp/arithmetic/LCP/_3_robot.java @@ -0,0 +1,165 @@ +package pp.arithmetic.LCP; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * Created by wangpeng on 2019-10-09. + * LCP 3. 机器人大冒险 + *

+ * 力扣团队买了一个可编程机器人,机器人初始位置在原点(0, 0)。小伙伴事先给机器人输入一串指令command,机器人就会无限循环这条指令的步骤进行移动。指令有两种: + *

+ * U: 向y轴正方向移动一格 + * R: 向x轴正方向移动一格。 + * 不幸的是,在 xy 平面上还有一些障碍物,他们的坐标用obstacles表示。机器人一旦碰到障碍物就会被损毁。 + *

+ * 给定终点坐标(x, y),返回机器人能否完好地到达终点。如果能,返回true;否则返回false。 + *

+ *   + *

+ * 示例 1: + *

+ * 输入:command = "URR", obstacles = [], x = 3, y = 2 + * 输出:true + * 解释:U(0, 1) -> R(1, 1) -> R(2, 1) -> U(2, 2) -> R(3, 2)。 + * 示例 2: + *

+ * 输入:command = "URR", obstacles = [[2, 2]], x = 3, y = 2 + * 输出:false + * 解释:机器人在到达终点前会碰到(2, 2)的障碍物。 + * 示例 3: + *

+ * 输入:command = "URR", obstacles = [[4, 2]], x = 3, y = 2 + * 输出:true + * 解释:到达终点后,再碰到障碍物也不影响返回结果。 + *   + *

+ * 限制: + *

+ * 2 <= command的长度 <= 1000 + * command由U,R构成,且至少有一个U,至少有一个R + * 0 <= x <= 1e9, 0 <= y <= 1e9 + * 0 <= obstacles的长度 <= 1000 + * obstacles[i]不为原点或者终点 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/programmable-robot + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _3_robot { + + public static void main(String[] args) { + _3_robot robot = new _3_robot(); + System.out.println(robot.robot("URR", new int[][]{}, 3, 2)); + System.out.println(robot.robot("URR", new int[][]{{2, 2}}, 3, 2)); + System.out.println(robot.robot("URR", new int[][]{{4, 2}}, 3, 2)); + System.out.println(robot.robot("URRURRR", new int[][]{{7, 7}, {0, 5}, {2, 7}, {8, 6}, {8, 7}, {6, 5}, {4, 4}, {0, 3}, {3, 6}}, 4915, 1966)); + //优化解题 + System.out.println(robot.robot2("URR", new int[][]{}, 3, 2)); + System.out.println(robot.robot2("URR", new int[][]{{2, 2}}, 3, 2)); + System.out.println(robot.robot2("URR", new int[][]{{4, 2}}, 3, 2)); + System.out.println(robot.robot2("URRURRR", new int[][]{{7, 7}, {0, 5}, {2, 7}, {8, 6}, {8, 7}, {6, 5}, {4, 4}, {0, 3}, {3, 6}}, 4915, 1966)); + } + + /** + * 解题思路: + * 简单直接能出结果,但是提交超时,主要耗时在障碍物的循环判断上,当障碍物太多了就比较耗时了 + * 比如这个case:https://leetcode-cn.com/submissions/detail/32424313/testcase/ + *

+ * 优化求解:{@link _3_robot#robot2(String, int[][], int, int)} + * + * @param command + * @param obstacles + * @param x + * @param y + * @return + */ + public boolean robot(String command, int[][] obstacles, int x, int y) { + int index = 0; + int length = command.length(); + int SX = 0, SY = 0; + while (true) { + char c = command.charAt(index % length); + if (c == 'U') { + SY++; + } else if (c == 'R') { + SX++; + } else { + break; + } + if (SX == x && SY == y) { + return true; + } + //不考虑内存的话,可以考虑用map保存障碍物位置,本题提交不过x,y太大 + if (isInObstacles(SX, SY, obstacles) || SX > x || SY > y) { + break; + } + index++; + } + + return false; + } + + private boolean isInObstacles(int x, int y, int[][] obstacles) { + if (obstacles.length == 0) return false; + for (int i = 0; i < obstacles.length; i++) { + if (x == obstacles[i][0] && y == obstacles[i][1]) { + return true; + } + } + return false; + } + + /** + * 解题思路: + * 1、鉴于指令是不断走循环的,先算出一个循环内横向走的坐标xx和纵向走的坐标yy,后续的可以通过规则落到第一圈的坐标上 + * 2、利用map将一个循环走的坐标保存下来==>xx+"_"+yy,true + * 3、计算走到目标坐标需要的循环次数,映射到第一圈中是否包含该坐标 + * 4、同理,循环障碍物,看映射到第一圈中是否包含该坐标 + * + * 映射规则:x ==> x - circle * xx + *

+ * 执行用时 : 3 ms, 在所有 Java 提交中击败了69.76%的用户 + * 内存消耗 :36 MB, 在所有 Java 提交中击败了100.00%的用户 + * + * @param command + * @param obstacles + * @param x + * @param y + * @return + */ + public boolean robot2(String command, int[][] obstacles, int x, int y) { + int xx = 0, yy = 0; + Map set = new HashMap<>(); + set.put(xx + "_" + yy, true); + //1 + for (char c : command.toCharArray()) { + switch (c) { + case 'U': + yy++; + break; + case 'R': + xx++; + break; + } + //2 + set.put(xx + "_" + yy, true); + } + //3 + int circle = Math.min(x / xx, y / yy); + if (!set.getOrDefault((x - circle * xx) + "_" + (y - circle * yy), false)) return false; + + //4 + for (int[] item : obstacles) { + if (item.length < 2) continue; + if (item[0] > x || item[1] > y) continue; + circle = Math.min(item[0] / xx, item[1] / yy); + if (set.getOrDefault((item[0] - circle * xx) + "_" + (item[1] - circle * yy), false)) return false; + } + + return true; + } + +} From 5ae3521ef7cb53ed3919eda77ac4069587c64c59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 11 Oct 2019 11:09:47 +0800 Subject: [PATCH 189/308] docs: add _3_robot --- README.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 08fc636..4198551 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成219道 +- leetcode练习,坚持每天一道,目前已完成220道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -18,7 +18,7 @@ - [ ] [LCP 5. 发 LeetCoin -Hard](https://leetcode-cn.com/problems/coin-bonus/) -- [ ] [LCP 3. 机器人大冒险 -Medium](https://leetcode-cn.com/problems/programmable-robot/) +- [x] [LCP 3. 机器人大冒险 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_3_robot.java) - [x] [LCP 1. 猜数字 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_1_game.java) @@ -55,9 +55,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成219) +### 题目列表(更新中—已完成220) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_1_game.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_3_robot.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -275,8 +275,9 @@ LCP -| No | 题目 | 解决方案 | 难度 | -| ---- | ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | -| #1 | [LCP 1. 猜数字](https://leetcode-cn.com/problems/guess-numbers/) | [Game](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_1_game.java) | Easy | -| #2 | [LCP 2. 分式化简](https://leetcode-cn.com/problems/deep-dark-fraction/) | [Fraction](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_2_fraction.java) | Easy | +| No | 题目 | 解决方案 | 难度 | +| ---- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | +| #1 | [LCP 1. 猜数字](https://leetcode-cn.com/problems/guess-numbers/) | [Game](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_1_game.java) | Easy | +| #2 | [LCP 2. 分式化简](https://leetcode-cn.com/problems/deep-dark-fraction/) | [Fraction](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_2_fraction.java) | Easy | +| #3 | [LCP 3. 机器人大冒险](https://leetcode-cn.com/problems/programmable-robot/) | [Robot](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_3_robot.java) | Medium | From bdfd6e239eda1581a6fa4e873f739c5d237fb0e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Sat, 12 Oct 2019 16:30:06 +0800 Subject: [PATCH 190/308] feat(Hard): add LCP_5_bonus --- src/pp/arithmetic/LCP/_5_bonus.java | 151 +++++++++++++++++++++ src/pp/arithmetic/LCP/_5_bonus_2.java | 184 ++++++++++++++++++++++++++ 2 files changed, 335 insertions(+) create mode 100644 src/pp/arithmetic/LCP/_5_bonus.java create mode 100644 src/pp/arithmetic/LCP/_5_bonus_2.java diff --git a/src/pp/arithmetic/LCP/_5_bonus.java b/src/pp/arithmetic/LCP/_5_bonus.java new file mode 100644 index 0000000..00f19ae --- /dev/null +++ b/src/pp/arithmetic/LCP/_5_bonus.java @@ -0,0 +1,151 @@ +package pp.arithmetic.LCP; + +import pp.arithmetic.Util; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wangpeng on 2019-10-11. + * + * 力扣决定给一个刷题团队发LeetCoin作为奖励。同时,为了监控给大家发了多少LeetCoin,力扣有时候也会进行查询。 + * + *   + * + * 该刷题团队的管理模式可以用一棵树表示: + * + * 团队只有一个负责人,编号为1。除了该负责人外,每个人有且仅有一个领导(负责人没有领导); + * 不存在循环管理的情况,如A管理B,B管理C,C管理A。 + *   + * + * 力扣想进行的操作有以下三种: + * + * 给团队的一个成员(也可以是负责人)发一定数量的LeetCoin; + * 给团队的一个成员(也可以是负责人),以及他/她管理的所有人(即他/她的下属、他/她下属的下属,……),发一定数量的LeetCoin; + * 查询某一个成员(也可以是负责人),以及他/她管理的所有人被发到的LeetCoin之和。 + *   + * + * 输入: + * + * N表示团队成员的个数(编号为1~N,负责人为1); + * leadership是大小为(N - 1) * 2的二维数组,其中每个元素[a, b]代表b是a的下属; + * operations是一个长度为Q的二维数组,代表以时间排序的操作,格式如下: + * operations[i][0] = 1: 代表第一种操作,operations[i][1]代表成员的编号,operations[i][2]代表LeetCoin的数量; + * operations[i][0] = 2: 代表第二种操作,operations[i][1]代表成员的编号,operations[i][2]代表LeetCoin的数量; + * operations[i][0] = 3: 代表第三种操作,operations[i][1]代表成员的编号; + * 输出: + * + * 返回一个数组,数组里是每次查询的返回值(发LeetCoin的操作不需要任何返回值)。由于发的LeetCoin很多,请把每次查询的结果模1e9+7 (1000000007)。 + * + *   + * + * 示例 1: + * + * 输入:N = 6, leadership = [[1, 2], [1, 6], [2, 3], [2, 5], [1, 4]], operations = [[1, 1, 500], [2, 2, 50], [3, 1], [2, 6, 15], [3, 1]] + * 输出:[650, 665] + * 解释:团队的管理关系见下图。 + * 第一次查询时,每个成员得到的LeetCoin的数量分别为(按编号顺序):500, 50, 50, 0, 50, 0; + * 第二次查询时,每个成员得到的LeetCoin的数量分别为(按编号顺序):500, 50, 50, 0, 50, 15. + * + * + *   + * + * 限制: + * + * 1 <= N <= 50000 + * 1 <= Q <= 50000 + * operations[i][0] != 3 时,1 <= operations[i][2] <= 5000 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/coin-bonus + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _5_bonus { + + public static void main(String[] args) { + _5_bonus bonus = new _5_bonus(); + Util.printArray(bonus.bonus(6, new int[][]{{1, 2}, {1, 6}, {2, 3}, {2, 5}, {1, 4}}, new int[][]{{1, 1, 500}, {2, 2, 50}, {3, 1}, {2, 6, 15}, {3, 1}})); + } + + /** + * 解题思路: + * 1、构建树及依赖关系 + * 2、按操作赋值 + * 3、保存取值结果 + * + * 提交超时:testCase :https://leetcode-cn.com/submissions/detail/32797078/ + * + * @param n + * @param leadership + * @param operations + * @return + */ + public int[] bonus(int n, int[][] leadership, int[][] operations) { + List retList = new ArrayList<>(); + //创建树 + CoinTree[] trees = new CoinTree[n + 1]; + for (int i = 1; i <= n; i++) { + trees[i] = new CoinTree(i); + } + //构造依赖关系 + for (int i = 0; i < leadership.length; i++) { + int[] item = leadership[i]; + trees[item[0]].child.add(trees[item[1]]); + } + //操作 + for (int i = 0; i < operations.length; i++) { + int[] item = operations[i]; + //操作类型 + int operation = item[0]; + switch (operation){ + case 1://给某个人发币 + addPersonCoin(trees[item[1]],item[2]); + break; + case 2://给某个人和他的团队发币 + addTeamCoin(trees[item[1]],item[2]); + break; + case 3://计算某个人和他的团队币总和,并记录返回 + retList.add(getTeamCoin(trees[item[1]])); + break; + } + } + + //list to array + int[] retArr = new int[retList.size()]; + for (int i = 0; i < retList.size(); i++) { + retArr[i] = retList.get(i); + } + + return retArr; + } + + private int getTeamCoin(CoinTree tree){ + int result = tree.coinCount; + for (int i = 0; i < tree.child.size(); i++) { + result+=getTeamCoin(tree.child.get(i)); + } + return result; + } + + private void addPersonCoin(CoinTree tree, int coin) { + tree.coinCount+=coin; + } + + private void addTeamCoin(CoinTree tree, int coin) { + addPersonCoin(tree,coin); + for (int i = 0; i < tree.child.size(); i++) { + addTeamCoin(tree.child.get(i),coin); + } + } + + class CoinTree{ + int value; + List child; + int coinCount = 0; + + public CoinTree(int value){ + this.value = value; + child = new ArrayList<>(); + } + } +} diff --git a/src/pp/arithmetic/LCP/_5_bonus_2.java b/src/pp/arithmetic/LCP/_5_bonus_2.java new file mode 100644 index 0000000..a3d3bb8 --- /dev/null +++ b/src/pp/arithmetic/LCP/_5_bonus_2.java @@ -0,0 +1,184 @@ +package pp.arithmetic.LCP; + +import pp.arithmetic.Util; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wangpeng on 2019-10-11. + *

+ * 力扣决定给一个刷题团队发LeetCoin作为奖励。同时,为了监控给大家发了多少LeetCoin,力扣有时候也会进行查询。 + *

+ *   + *

+ * 该刷题团队的管理模式可以用一棵树表示: + *

+ * 团队只有一个负责人,编号为1。除了该负责人外,每个人有且仅有一个领导(负责人没有领导); + * 不存在循环管理的情况,如A管理B,B管理C,C管理A。 + *   + *

+ * 力扣想进行的操作有以下三种: + *

+ * 给团队的一个成员(也可以是负责人)发一定数量的LeetCoin; + * 给团队的一个成员(也可以是负责人),以及他/她管理的所有人(即他/她的下属、他/她下属的下属,……),发一定数量的LeetCoin; + * 查询某一个成员(也可以是负责人),以及他/她管理的所有人被发到的LeetCoin之和。 + *   + *

+ * 输入: + *

+ * N表示团队成员的个数(编号为1~N,负责人为1); + * leadership是大小为(N - 1) * 2的二维数组,其中每个元素[a, b]代表b是a的下属; + * operations是一个长度为Q的二维数组,代表以时间排序的操作,格式如下: + * operations[i][0] = 1: 代表第一种操作,operations[i][1]代表成员的编号,operations[i][2]代表LeetCoin的数量; + * operations[i][0] = 2: 代表第二种操作,operations[i][1]代表成员的编号,operations[i][2]代表LeetCoin的数量; + * operations[i][0] = 3: 代表第三种操作,operations[i][1]代表成员的编号; + * 输出: + *

+ * 返回一个数组,数组里是每次查询的返回值(发LeetCoin的操作不需要任何返回值)。由于发的LeetCoin很多,请把每次查询的结果模1e9+7 (1000000007)。 + *

+ *   + *

+ * 示例 1: + *

+ * 输入:N = 6, leadership = [[1, 2], [1, 6], [2, 3], [2, 5], [1, 4]], operations = [[1, 1, 500], [2, 2, 50], [3, 1], [2, 6, 15], [3, 1]] + * 输出:[650, 665] + * 解释:团队的管理关系见下图。 + * 第一次查询时,每个成员得到的LeetCoin的数量分别为(按编号顺序):500, 50, 50, 0, 50, 0; + * 第二次查询时,每个成员得到的LeetCoin的数量分别为(按编号顺序):500, 50, 50, 0, 50, 15. + *

+ *

+ *   + *

+ * 限制: + *

+ * 1 <= N <= 50000 + * 1 <= Q <= 50000 + * operations[i][0] != 3 时,1 <= operations[i][2] <= 5000 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/coin-bonus + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _5_bonus_2 { + + public static void main(String[] args) { + _5_bonus_2 bonus = new _5_bonus_2(); + Util.printArray(bonus.bonus(6, new int[][]{{1, 2}, {1, 6}, {2, 3}, {2, 5}, {1, 4}}, new int[][]{{1, 1, 500}, {2, 2, 50}, {3, 1}, {2, 6, 15}, {3, 1}})); + + int[][] l = new int[][]{{1, 283}, {1, 52}, {1, 273}, {1, 217}, {1, 136}, {1, 211}, {1, 179}, {283, 293}, {283, 292}, {283, 227}, {283, 54}, {283, 404}, {283, 378}, {283, 243}, {283, 270}, {283, 46}, {283, 300}, {52, 376}, {52, 267}, {52, 71}, {52, 406}, {273, 9}, {273, 148}, {273, 51}, {273, 102}, {217, 110}, {217, 370}, {217, 125}, {217, 357}, {136, 360}, {136, 260}, {136, 196}, {136, 228}, {136, 103}, {136, 347}, {136, 384}, {211, 25}, {179, 3}, {179, 140}, {179, 56}, {179, 263}, {179, 231}, {293, 326}, {293, 121}, {293, 116}, {293, 21}, {293, 262}, {293, 369}, {293, 183}, {292, 75}, {292, 303}, {292, 330}, {227, 397}, {227, 35}, {227, 279}, {227, 345}, {227, 139}, {227, 391}, {227, 266}, {54, 16}, {404, 214}, {404, 184}, {404, 68}, {404, 27}, {378, 192}, {378, 87}, {378, 39}, {378, 386}, {378, 259}, {243, 94}, {243, 112}, {243, 99}, {243, 182}, {243, 29}, {243, 197}, {270, 23}, {270, 181}, {270, 297}, {46, 351}, {46, 362}, {46, 22}, {46, 61}, {300, 408}, {376, 332}, {267, 349}, {267, 80}, {267, 367}, {267, 226}, {71, 72}, {71, 389}, {71, 163}, {71, 100}, {71, 107}, {71, 92}, {71, 85}, {406, 353}, {406, 199}, {406, 257}, {406, 242}, {406, 305}, {406, 159}, {406, 77}, {9, 309}, {148, 401}, {148, 65}, {148, 218}, {148, 342}, {148, 331}, {148, 339}, {51, 290}, {51, 150}, {51, 60}, {51, 137}, {51, 160}, {51, 252}, {51, 364}, {51, 335}, {51, 343}, {51, 304}, {102, 180}, {102, 138}, {110, 74}, {110, 171}, {110, 390}, {110, 352}, {110, 37}, {370, 377}, {370, 358}, {370, 36}, {370, 272}, {125, 66}, {125, 301}, {125, 67}, {125, 239}, {125, 175}, {357, 12}, {357, 106}, {357, 282}, {357, 240}, {360, 144}, {360, 393}, {360, 317}, {360, 195}, {260, 264}, {260, 13}, {260, 281}, {260, 400}, {260, 212}, {260, 365}, {260, 402}, {260, 63}, {260, 255}, {196, 193}, {196, 338}, {228, 399}, {228, 202}, {228, 313}, {228, 392}, {228, 208}, {228, 38}, {228, 31}, {103, 203}, {103, 320}, {103, 254}, {103, 275}, {103, 34}, {347, 149}, {347, 222}, {347, 114}, {347, 157}, {347, 325}, {347, 6}, {347, 154}, {347, 250}, {347, 350}, {384, 93}, {384, 123}, {384, 374}, {384, 50}, {25, 285}, {25, 20}, {25, 288}, {25, 251}, {25, 185}, {25, 289}, {3, 241}, {3, 258}, {3, 43}, {140, 58}, {140, 329}, {140, 45}, {140, 287}, {140, 132}, {140, 170}, {140, 355}, {140, 311}, {140, 47}, {140, 168}, {56, 321}, {56, 388}, {56, 32}, {56, 302}, {56, 190}, {56, 48}, {56, 11}, {263, 96}, {263, 30}, {263, 24}, {263, 26}, {231, 229}, {231, 164}, {231, 128}, {231, 295}, {231, 230}, {231, 396}, {231, 81}, {231, 244}, {231, 276}, {231, 141}, {326, 134}, {326, 161}, {326, 97}, {326, 286}, {326, 88}, {326, 221}, {326, 405}, {326, 8}, {326, 156}, {121, 113}, {121, 15}, {121, 348}, {121, 104}, {121, 398}, {121, 91}, {121, 40}, {121, 64}, {121, 318}, {121, 111}, {116, 271}, {21, 83}, {21, 55}, {262, 368}, {262, 336}, {262, 249}, {262, 129}, {262, 145}, {262, 337}, {262, 234}, {262, 79}, {369, 90}, {369, 122}, {369, 395}, {369, 108}, {369, 341}, {369, 334}, {369, 316}, {369, 69}, {369, 278}, {183, 151}, {183, 315}, {183, 17}, {183, 178}, {183, 274}, {183, 269}, {75, 200}, {75, 131}, {75, 126}, {75, 19}, {75, 359}, {75, 70}, {75, 133}, {75, 117}, {75, 33}, {75, 206}, {303, 223}, {303, 324}, {303, 101}, {303, 314}, {303, 135}, {303, 146}, {330, 191}, {330, 194}, {330, 253}, {330, 307}, {330, 225}, {330, 299}, {330, 382}, {330, 82}, {397, 167}, {397, 2}, {397, 308}, {397, 246}, {397, 245}, {397, 265}, {35, 261}, {35, 328}, {35, 224}, {35, 296}, {35, 340}, {35, 186}, {35, 280}, {279, 210}, {279, 4}, {279, 268}, {279, 173}, {279, 284}, {279, 247}, {279, 119}, {279, 89}, {279, 205}, {345, 10}, {345, 124}, {345, 366}, {345, 7}, {345, 98}, {345, 209}, {345, 394}, {345, 385}, {345, 188}, {345, 166}, {139, 153}, {139, 327}, {139, 127}, {139, 155}, {139, 312}, {391, 235}, {391, 76}, {391, 381}, {266, 219}, {266, 5}, {266, 361}, {266, 120}, {266, 344}, {266, 105}, {266, 371}, {266, 165}, {266, 323}, {16, 59}, {16, 237}, {16, 291}, {16, 109}, {214, 383}, {214, 142}, {214, 220}, {214, 215}, {184, 78}, {184, 238}, {184, 57}, {68, 204}, {27, 356}, {27, 322}, {27, 62}, {27, 162}, {27, 407}, {27, 14}, {27, 152}, {27, 86}, {27, 84}, {27, 95}, {192, 42}, {87, 115}, {87, 403}, {87, 118}, {87, 189}, {87, 28}, {87, 277}, {87, 147}, {87, 49}, {39, 73}, {386, 213}, {386, 387}, {386, 306}, {386, 346}, {386, 143}, {386, 363}, {386, 41}, {386, 373}, {259, 216}, {259, 372}, {259, 169}, {259, 248}, {259, 354}, {259, 53}, {259, 44}, {259, 380}, {259, 256}, {94, 333}, {94, 172}, {94, 298}, {94, 18}, {94, 232}, {94, 158}, {94, 207}, {94, 236}, {112, 310}, {112, 130}, {112, 319}, {112, 174}, {99, 177}, {99, 233}, {99, 187}, {99, 198}, {99, 375}, {99, 201}, {99, 176}, {99, 294}, {99, 379}}; + int[][] o = new int[][]{ + {1, 201, 26}, {1, 114, 22}, {2, 366, 42}, {2, 116, 22}, {1, 239, 5}, {1, 11, 38}, {1, 50, 19}, {2, 159, 45}, {1, 242, 12}, {1, 338, 44}, {1, 221, 33}, {2, 268, 21}, {3, 186}, {1, 171, 46}, {2, 41, 15}, {2, 84, 1}, {1, 210, 30}, {2, 109, 28}, {2, 164, 16}, {2, 40, 8}, {1, 129, 30}, {3, 268}, {2, 163, 16}, {2, 345, 44}, {1, 91, 13}, {2, 16, 46}, {2, 304, 15}, {2, 387, 8}, {2, 296, 13}, {1, 293, 1}, {2, 362, 15}, {2, 177, 37}, {1, 11, 50}, {1, 372, 34}, {3, 1}, {3, 268}, {1, 339, 43}, {2, 353, 45}, {2, 121, 19}, {3, 1}, {1, 125, 8}, {1, 160, 44}, {1, 66, 43}, {1, 98, 2}, {3, 52}, {2, 108, 41}, {3, 245}, {1, 66, 45}, {3, 52}, {1, 132, 49}, {2, 135, 32}, {3, 402}, {3, 1}, {2, 234, 23}, {2, 80, 50}, {3, 52}, {3, 283}, {2, 233, 26}, {2, 269, 27}, {1, 388, 45}, {2, 139, 40}, {2, 118, 17}, {2, 329, 37}, {2, 200, 27}, {3, 1}, {1, 9, 23}, {2, 367, 32}, {3, 52}, {2, 314, 23}, {1, 50, 2}, {3, 283}, {1, 320, 25}, {3, 154}, {1, 270, 48}, {1, 213, 30}, {2, 297, 12}, {2, 404, 20}, {3, 283}, {2, 291, 31}, {3, 52}, {1, 278, 43}, {1, 244, 45}, {1, 96, 3}, {3, 1}, {1, 339, 49}, {1, 131, 26}, {2, 75, 9}, {1, 80, 39}, {3, 264}, {1, 69, 7}, {1, 394, 37}, {2, 17, 16}, {1, 290, 44}, {1, 95, 35}, {3, 52}, {2, 361, 8}, {1, 195, 18}, {1, 63, 15}, {3, 52}, {1, 309, 8}, {2, 368, 28}, {3, 1}, {3, 1}, {1, 311, 48}, {3, 125}, {1, 382, 23}, {2, 225, 23}, {2, 309, 24}, {3, 253}, {1, 66, 18}, {2, 137, 26}, {3, 269}, {3, 283}, {3, 283}, {1, 346, 10}, {1, 340, 19}, {1, 105, 13}, {1, 303, 25}, {1, 376, 30}, {3, 52}, {1, 275, 36}, {1, 9, 3}, {1, 190, 36}, {1, 312, 10}, {3, 366}, {1, 248, 24}, {1, 360, 41}, {3, 1}, {3, 1}, {2, 367, 27}, {1, 209, 19}, {2, 255, 3}, {2, 135, 42}, {1, 57, 16}, {2, 121, 8}, {3, 221}, {1, 112, 47}, {2, 42, 23}, {2, 87, 12}, {1, 293, 27}, {1, 309, 28}, {1, 33, 7}, {1, 196, 39}, {3, 314}, {1, 164, 12}, {2, 2, 31}, {3, 52}, {1, 80, 40}, {3, 52}, {3, 283}, {3, 1}, {2, 212, 16}, {3, 1}, {3, 52}, {2, 50, 43}, {3, 1}, {1, 14, 42}, {3, 283}, {2, 404, 32}, {3, 283}, {2, 44, 11}, {2, 70, 18}, {2, 147, 32}, {2, 260, 28}, {1, 144, 9}, {3, 52}, {3, 1}, {3, 283}, {3, 283}, {1, 329, 20}, {1, 45, 13}, {3, 52}, {1, 340, 33}, {2, 14, 11}, {1, 288, 31}, {1, 262, 46}, {1, 145, 42}, {2, 303, 24}, {1, 392, 3}, {1, 295, 24}, {2, 213, 5}, {1, 368, 13}, {1, 228, 14}, {1, 375, 47}, {3, 283}, {3, 161}, {3, 1}, {1, 64, 46}, {2, 102, 5}, {1, 251, 21}, {3, 298}, {1, 223, 24}, {2, 297, 13}, {1, 293, 19}, {2, 99, 26}, {2, 395, 21}, {3, 52}, {3, 52}, {3, 52}, {2, 221, 50}, {3, 1}, {2, 116, 41}, {2, 246, 24}, {1, 233, 39}, {3, 1}, {2, 318, 5}, {2, 63, 43}, {1, 142, 46}, {2, 367, 38}, {2, 193, 47}, {1, 34, 27}, {1, 302, 25}, {3, 1}, {1, 238, 13}, {2, 372, 19}, {3, 311}, {1, 3, 14}, {2, 200, 34}, {3, 52}, {2, 160, 40}, {2, 242, 30}, {1, 273, 27}, {1, 375, 9}, {3, 52}, {1, 66, 15}, {1, 103, 8}, {3, 52}, {1, 400, 48}, {2, 327, 46}, {1, 379, 25}, {2, 164, 4}, {2, 358, 4}, {2, 356, 1}, {2, 175, 7}, {2, 261, 37}, {3, 283}, {1, 155, 7}, {2, 214, 9}, {1, 154, 42}, {1, 12, 22}, {3, 52}, {1, 273, 8}, {3, 52}, {3, 52}, {3, 52}, {1, 364, 38}, {2, 199, 30}, {3, 283}, {1, 70, 18}, {2, 275, 41}, {2, 373, 3}, {2, 260, 2}, {2, 31, 11}, {2, 326, 1}, {2, 244, 34}, {3, 323}, {2, 209, 27}, {1, 163, 5}, {1, 131, 45}, {1, 3, 44}, {2, 311, 34}, {1, 8, 35}, {1, 78, 49}, {2, 342, 32}, {2, 231, 46}, {2, 124, 23}, {1, 85, 30}, {2, 274, 16}, {1, 28, 39}, {3, 283}, {1, 156, 28}, {3, 54}, {1, 100, 1}, {1, 43, 9}, {3, 1}, {2, 85, 3}, {3, 149}, {3, 1}, {3, 187}, {2, 107, 12}, {1, 374, 9}, {3, 52}, {3, 52}, {3, 283}, {3, 1}, {3, 283}, {2, 365, 10}, {1, 89, 27}, {3, 52}, {2, 145, 44}, {1, 220, 33}, {2, 116, 8}, {1, 94, 26}, {3, 283}, {3, 52}, {3, 371}, {2, 185, 29}, {1, 93, 37}, {2, 203, 36}, {2, 181, 46}, {1, 313, 14}, {3, 283}, {2, 191, 34}, {3, 283}, {1, 206, 6}, {3, 235}, {1, 56, 31}, {2, 361, 11}, {1, 244, 27}, {2, 241, 12}, {1, 214, 41}, {2, 358, 20}, {1, 340, 37}, {2, 126, 18}, {2, 101, 44}, {1, 23, 46}, {2, 323, 24}, {3, 52}, {1, 301, 12}, {2, 224, 43}, {1, 24, 26}, {2, 326, 50}, {3, 52}, {3, 52}, {3, 52}, {2, 177, 37}, {1, 240, 41}, {1, 320, 12}, {3, 239}, {2, 369, 31}, {1, 372, 19}, {2, 179, 23}, {2, 180, 23}, {1, 170, 10}, {1, 252, 1}, {2, 42, 39}, {2, 124, 13}, {1, 263, 19}, {1, 244, 1}, {1, 84, 37}, {1, 187, 8}, {3, 283}, {2, 175, 43}, {1, 203, 38}, {3, 1}, {2, 19, 29}, {1, 301, 19}, {3, 41}, {3, 46}, {2, 26, 21}, {1, 325, 7}, {1, 343, 47}, {2, 81, 49}, {2, 395, 29}, {3, 52}, {3, 283}, {2, 114, 47}, {2, 6, 38}, {1, 219, 37}, {2, 154, 23}, {1, 188, 6}, {1, 116, 25}, {2, 385, 7}, {1, 289, 3}, {2, 295, 2}, {3, 1}, {3, 1}, {3, 52}, {3, 283}, {3, 52}, {2, 140, 2}, {3, 1}, {1, 248, 40}, {1, 379, 18}, {1, 224, 7}, {2, 63, 24}, {3, 283}, {2, 207, 13}, {1, 333, 6}, {2, 332, 20}, {3, 222}, {2, 52, 14}, {1, 158, 4}, {3, 52}, {1, 271, 35}, {1, 75, 10}, {2, 322, 11}, {2, 315, 3}, {2, 26, 7}, {1, 10, 11}, {2, 401, 50}, {1, 9, 18}, {3, 1}, {1, 28, 39}, {1, 185, 3}, {3, 52}, {1, 162, 20}, {1, 247, 5}, {3, 52}, {1, 308, 9}, {2, 103, 33}, {3, 1}, {3, 344}, {3, 283}, {2, 124, 29}, {3, 1}, {2, 121, 23}, {1, 122, 23}, {1, 381, 37}, {2, 185, 35}, {2, 285, 5}, {2, 190, 25}, {2, 122, 25}, {1, 293, 38}, {1, 75, 41}, {2, 138, 15}, {1, 202, 9}, {1, 121, 42}, {3, 52}, {2, 83, 23}, {3, 325}, {3, 1}, {2, 350, 41}, {2, 337, 50}, {2, 198, 19}, {1, 221, 32}, {1, 309, 4}, {3, 1}, {1, 310, 44}, {2, 22, 34}, {1, 247, 29}, {2, 187, 22}, {3, 283}, {1, 366, 16}, {3, 52}, {3, 52}, {1, 8, 36}, {2, 83, 18}, {1, 134, 36}, {2, 291, 27}, {2, 352, 16}, {2, 281, 27}, {1, 397, 15}, {2, 215, 40}, {2, 190, 4}, {2, 98, 17}, {3, 331}, {2, 21, 32}, {1, 56, 10}, {1, 388, 42}, {1, 225, 3}, {1, 225, 42}, {1, 185, 18}, {3, 347}, {1, 184, 23}, {3, 52}, {1, 137, 30}, {1, 187, 39}, {1, 249, 46}, {1, 137, 16}, {1, 160, 7}, {2, 148, 11}, {1, 384, 13}, {2, 389, 27}, {2, 308, 16}, {2, 384, 39}, {2, 235, 1}, {2, 117, 6}, {2, 222, 11}, {3, 1}, {3, 52}, {1, 249, 5}, {2, 321, 28}, {2, 365, 14}, {2, 2, 34}, {3, 362}, {3, 52}, {2, 93, 25}, {3, 1}, {2, 359, 10}, {3, 52}, {3, 1}, {2, 408, 4}, {1, 193, 45}, {3, 52}, {1, 97, 11}, {1, 75, 2}, {3, 1}, {3, 52}, {3, 283}, {3, 273}, {3, 105}, {1, 95, 14}, {3, 1}, {3, 100}, {2, 176, 33}, {2, 121, 26}, {3, 52}, {1, 331, 21}, {2, 83, 14}}; + Util.printArray(bonus.bonus(408 ,l,o)); + } + + private int mod = 1000000007; + + /** + * 解题思路: + * 1、构建树及依赖关系 + * 2、按操作赋值 + * 3、保存取值结果 + *

+ * 比较{@link _5_bonus}优化:、 + * 发团队币,全部发给团队负责人,负责人统一保存 + * 1、为了让取币总和更快,在发币的时候就保存了团队币总和 + * 2、由于发币团队成员都是一致的,所以负责人中可以保存下属的同样的币(每个人还可以有自己特有的币) + * + * 执行用时 :47 ms , 在所有 Java 提交中击败了93.62% 的用户 + * 内存消耗 :89.6 MB, 在所有 Java 提交中击败了100.00%的用户 + * + * @param n + * @param leadership + * @param operations + * @return + */ + public int[] bonus(int n, int[][] leadership, int[][] operations) { + List retList = new ArrayList<>(); + //创建树 + CoinTree[] trees = new CoinTree[n + 1]; + for (int i = 1; i <= n; i++) { + trees[i] = new CoinTree(i); + } + //构造依赖关系 + for (int i = 0; i < leadership.length; i++) { + int[] item = leadership[i]; + //计算团队成员 + CoinTree parent = trees[item[0]]; + trees[item[1]].parent = parent; + while (parent != null) { + parent.teamSize++; + parent = parent.parent; + } + } + //操作 + for (int i = 0; i < operations.length; i++) { + int[] item = operations[i]; + //操作类型 + int operation = item[0]; + switch (operation) { + case 1://给某个人发币 + addPersonCoin(trees[item[1]], item[2]); + break; + case 2://给某个人和他的团队发币 + addTeamCoin(trees[item[1]], item[2]); + break; + case 3://计算某个人和他的团队币总和,并记录返回 + retList.add(getTeamCoin(trees[item[1]])); + break; + } + } + + //list to array + int[] retArr = new int[retList.size()]; + for (int i = 0; i < retList.size(); i++) { + retArr[i] = retList.get(i); + } + + return retArr; + } + + private int getTeamCoin(CoinTree tree) { + long result = tree.teamCoinAll; + int size = tree.teamSize; + CoinTree parent = tree.parent; + while (parent != null) { + result += parent.teamCoin * size; + parent = parent.parent; + } + return (int) (result % mod); + } + + private void addPersonCoin(CoinTree tree, int coin) { + tree.teamCoinAll += coin; + CoinTree parent = tree.parent; + while (parent != null) { + parent.teamCoinAll += coin; + parent = parent.parent; + } + } + + private void addTeamCoin(CoinTree tree, int coin) { + tree.teamCoin += coin; + int teamAddCoin = coin * tree.teamSize; + tree.teamCoinAll += teamAddCoin; + CoinTree parent = tree.parent; + while (parent != null) { + parent.teamCoinAll += teamAddCoin; + parent = parent.parent; + } + } + + class CoinTree { + int value; + int teamSize; //团队成员(包括自己) + long teamCoin; //团队每个人共有 + long teamCoinAll;//团队总共有的 + CoinTree parent; + + public CoinTree(int value) { + this.value = value; + teamSize = 1;//自己 + } + } +} From 96a0f812110b44fa4dbebe3630b8974c85ce038c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Sat, 12 Oct 2019 16:45:55 +0800 Subject: [PATCH 191/308] docs: add _5_bonus --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4198551..e9c00c7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成220道 +- leetcode练习,坚持每天一道,目前已完成221道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -16,7 +16,7 @@ - [ ] [LCP 4. 覆盖 -Hard](https://leetcode-cn.com/problems/broken-board-dominoes/) -- [ ] [LCP 5. 发 LeetCoin -Hard](https://leetcode-cn.com/problems/coin-bonus/) +- [x] [LCP 5. 发 LeetCoin -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_5_bonus_2.java) - [x] [LCP 3. 机器人大冒险 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_3_robot.java) @@ -55,9 +55,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成220) +### 题目列表(更新中—已完成221) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_3_robot.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_5_bonus_2.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -280,4 +280,5 @@ LCP | #1 | [LCP 1. 猜数字](https://leetcode-cn.com/problems/guess-numbers/) | [Game](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_1_game.java) | Easy | | #2 | [LCP 2. 分式化简](https://leetcode-cn.com/problems/deep-dark-fraction/) | [Fraction](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_2_fraction.java) | Easy | | #3 | [LCP 3. 机器人大冒险](https://leetcode-cn.com/problems/programmable-robot/) | [Robot](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_3_robot.java) | Medium | +| #5 | [LCP 5. 发 LeetCoin](https://leetcode-cn.com/problems/coin-bonus/) | [Bonus](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_5_bonus_2.java) | Hard | From a217f12af351bf5e482f488588c060295eaffb12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 16 Oct 2019 11:16:10 +0800 Subject: [PATCH 192/308] feat(HARD): add LCP_4_domino --- src/pp/arithmetic/LCP/_4_domino.java | 137 +++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 src/pp/arithmetic/LCP/_4_domino.java diff --git a/src/pp/arithmetic/LCP/_4_domino.java b/src/pp/arithmetic/LCP/_4_domino.java new file mode 100644 index 0000000..cd6f956 --- /dev/null +++ b/src/pp/arithmetic/LCP/_4_domino.java @@ -0,0 +1,137 @@ +package pp.arithmetic.LCP; + +/** + * Created by wangpeng on 2019-10-14. + * LCP 4. 覆盖 + *

+ * 你有一块棋盘,棋盘上有一些格子已经坏掉了。你还有无穷块大小为1 * 2的多米诺骨牌,你想把这些骨牌不重叠地覆盖在完好的格子上,请找出你最多能在棋盘上放多少块骨牌?这些骨牌可以横着或者竖着放。 + *

+ *   + *

+ * 输入:n, m代表棋盘的大小;broken是一个b * 2的二维数组,其中每个元素代表棋盘上每一个坏掉的格子的位置。 + *

+ * 输出:一个整数,代表最多能在棋盘上放的骨牌数。 + *

+ *   + *

+ * 示例 1: + *

+ * 输入:n = 2, m = 3, broken = [[1, 0], [1, 1]] + * 输出:2 + * 解释:我们最多可以放两块骨牌:[[0, 0], [0, 1]]以及[[0, 2], [1, 2]]。(见下图) + *

+ *   + *   + *

+ * 示例 2: + *

+ * 输入:n = 3, m = 3, broken = [] + * 输出:4 + * 解释:下 图是其中一种可行的摆放方式 + *

+ *   + *

+ * 限制: + *

+ * 1 <= n <= 8 + * 1 <= m <= 8 + * 0 <= b <= n * m + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/broken-board-dominoes + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _4_domino { + + public static void main(String[] args) { + _4_domino domino = new _4_domino(); + System.out.println(domino.domino(2, 3, new int[][]{{1, 0}, {1, 1}})); + System.out.println(domino.domino(3, 3, new int[][]{})); + System.out.println(domino.domino(8, 8, new int[][]{ + {1, 0}, {2, 5}, {3, 1}, {3, 2}, {3, 4}, {4, 0}, {4, 3}, {4, 6}, {4, 7}, {5, 3}, {5, 5}, {5, 6}, {6, 3}, {7, 2}, {7, 7} + })); + } + + int ret = 0; //摆放计数 + int max = 0; //最大值计数 + + /** + * 解题思路: + * 1、构建棋盘,将棋盘上正常的为0,坏了的位置为2,摆放了骨牌的为1 + * 2、对于一个位置和骨牌有三种组合:横着放、竖着放、不放,如需计算正确的值需要所有的情况都计算到,所以回溯实现 + *

+ * 执行耗时不是很好,但是自己写出来的好理解 + * 执行用时 :1297 ms, 在所有 java 提交中击败了12.90%的用户 + * 内存消耗 :35.6 MB, 在所有 java 提交中击败了100.00%的用户 + * + * @param n + * @param m + * @param broken + * @return + */ + public int domino(int n, int m, int[][] broken) { + ret = 0; + max = 0; + //构造棋盘 + int[][] map = new int[n][m]; + for (int i = 0; i < broken.length; i++) { + int[] item = broken[i]; + map[item[0]][item[1]] = 2; + } + dfs(map, 0, 0); + + return max; + } + + /** + * 循环的过程是横向一行行逐格摆放,如到一行的末尾无法摆放则换行,如超过行数则计算摆放的最大个数 + * + * @param map + * @param row + * @param col + */ + private void dfs(int[][] map, int row, int col) { + if (row >= map.length) { //如超过行数则计算摆放的最大个数 + max = Math.max(max, ret); + return; + } + if (col >= map[row].length) {//如到一行的末尾无法摆放则换行 + dfs(map, row + 1, 0); + return; + } + if (map[row][col] > 0) {//遇坏格子则跳过 + dfs(map, row, col + 1); + return; + } + //试着横着放 + boolean h = false; + if (col < map[row].length - 1 && map[row][col + 1] == 0) { + h = true; + map[row][col]++; + map[row][col + 1]++; + ret++; + dfs(map, row, col + 2); + //横向状态重置 + ret--; + map[row][col]--; + map[row][col + 1]--; + } + //试着竖着放 + boolean v = false; + if (row < map.length - 1 && map[row + 1][col] == 0) { + v = true; + map[row][col]++; + map[row + 1][col]++; + ret++; + dfs(map, row, col + 1); + //竖向状态重置 + ret--; + map[row][col]--; + map[row + 1][col]--; + } + //如横着和竖着都不行,试着不放,跳2格 + if (!h && !v) { + dfs(map, row, col + 2); + } + } +} From 2a503e4de2e04eb56c8e6184d7f9210dabb9a9aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 16 Oct 2019 12:03:12 +0800 Subject: [PATCH 193/308] docs: add _4_domino --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e9c00c7..741ff11 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成221道 +- leetcode练习,坚持每天一道,目前已完成222道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -14,7 +14,7 @@ - [x] [LCP 2. 分式化简 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_2_fraction.java) -- [ ] [LCP 4. 覆盖 -Hard](https://leetcode-cn.com/problems/broken-board-dominoes/) +- [x] [LCP 4. 覆盖 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_4_domino.java) - [x] [LCP 5. 发 LeetCoin -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_5_bonus_2.java) @@ -55,9 +55,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成221) +### 题目列表(更新中—已完成222) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_5_bonus_2.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_4_domino.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -280,5 +280,6 @@ LCP | #1 | [LCP 1. 猜数字](https://leetcode-cn.com/problems/guess-numbers/) | [Game](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_1_game.java) | Easy | | #2 | [LCP 2. 分式化简](https://leetcode-cn.com/problems/deep-dark-fraction/) | [Fraction](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_2_fraction.java) | Easy | | #3 | [LCP 3. 机器人大冒险](https://leetcode-cn.com/problems/programmable-robot/) | [Robot](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_3_robot.java) | Medium | +| #4 | [LCP 4. 覆盖](https://leetcode-cn.com/problems/broken-board-dominoes/) | [Domino](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_4_domino.java) | Hard | | #5 | [LCP 5. 发 LeetCoin](https://leetcode-cn.com/problems/coin-bonus/) | [Bonus](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_5_bonus_2.java) | Hard | From 6a43866294d71ebc939a14d60234e8c6ec0df767 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 17 Oct 2019 09:42:31 +0800 Subject: [PATCH 194/308] docs: update topic list --- README.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 741ff11..c082dff 100644 --- a/README.md +++ b/README.md @@ -10,17 +10,21 @@ - 网址:https://leetcode-cn.com/ ## 待解题目列表 -扫题:力扣杯 +扫题:顺序 -- [x] [LCP 2. 分式化简 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_2_fraction.java) +- [ ] [65. 有效数字 -Hard](https://leetcode-cn.com/problems/valid-number/) -- [x] [LCP 4. 覆盖 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_4_domino.java) +- [ ] [66. 加一 -Easy](https://leetcode-cn.com/problems/plus-one/) -- [x] [LCP 5. 发 LeetCoin -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_5_bonus_2.java) +- [ ] [68. 文本左右对齐 -Hard](https://leetcode-cn.com/problems/text-justification/) -- [x] [LCP 3. 机器人大冒险 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_3_robot.java) +- [ ] [73. 矩阵置零 -Medium](https://leetcode-cn.com/problems/set-matrix-zeroes/) -- [x] [LCP 1. 猜数字 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_1_game.java) +- [ ] [74. 搜索二维矩阵 -Medium](https://leetcode-cn.com/problems/search-a-2d-matrix/) + +- [ ] [81. 搜索旋转排序数组 II -Medium](https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/) + +- [ ] [82. 删除排序链表中的重复元素 II -Medium](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/) ## 已解题目 From f80fd65e7806447ea188be888ea36572638a9915 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 18 Oct 2019 16:28:42 +0800 Subject: [PATCH 195/308] feat(HARD): add _65_isNumber --- src/pp/arithmetic/leetcode/_65_isNumber.java | 167 +++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_65_isNumber.java diff --git a/src/pp/arithmetic/leetcode/_65_isNumber.java b/src/pp/arithmetic/leetcode/_65_isNumber.java new file mode 100644 index 0000000..abc25b4 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_65_isNumber.java @@ -0,0 +1,167 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-10-18. + * 65. 有效数字 + *

+ * 验证给定的字符串是否可以解释为十进制数字。 + *

+ * 例如: + *

+ * "0" => true + * " 0.1 " => true + * "abc" => false + * "1 a" => false + * "2e10" => true + * " -90e3   " => true + * " 1e" => false + * "e3" => false + * " 6e-1" => true + * " 99e2.5 " => false + * "53.5e93" => true + * " --6 " => false + * "-+3" => false + * "95a54e53" => false + *

+ * 说明: 我们有意将问题陈述地比较模糊。在实现代码之前,你应当事先思考所有可能的情况。这里给出一份可能存在于有效十进制数字中的字符列表: + *

+ * 数字 0-9 + * 指数 - "e" + * 正/负号 - "+"/"-" + * 小数点 - "." + * 当然,在输入中,这些字符的上下文也很重要。 + *

+ * 更新于 2015-02-10: + * C++函数的形式已经更新了。如果你仍然看见你的函数接收 const char * 类型的参数,请点击重载按钮重置你的代码 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/valid-number + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _65_isNumber { + + public static void main(String[] args) { + _65_isNumber isNumber = new _65_isNumber(); + /** + * + * "0" => true + * " 0.1 " => true + * "abc" => false + * "1 a" => false + * "2e10" => true + * " -90e3   " => true + * " 1e" => false + * "e3" => false + * " 6e-1" => true + * " 99e2.5 " => false + * "53.5e93" => true + * " --6 " => false + * "-+3" => false + * "95a54e53" => false + */ + System.out.println(isNumber.isNumber("+.8")); //true + System.out.println(isNumber.isNumber("-e58 ")); //false + System.out.println(isNumber.isNumber("3.")); //true + System.out.println(isNumber.isNumber("01")); //true + System.out.println(isNumber.isNumber(".1")); //true + System.out.println(isNumber.isNumber("0")); //true + System.out.println(isNumber.isNumber("0.1")); //true + System.out.println(isNumber.isNumber("abc")); //false + System.out.println(isNumber.isNumber("1 a")); //false + System.out.println(isNumber.isNumber("2e10")); //true + System.out.println(isNumber.isNumber("-90e3")); //true + System.out.println(isNumber.isNumber(" 1e")); //false + System.out.println(isNumber.isNumber("e3")); //false + System.out.println(isNumber.isNumber(" 6e-1")); //true + System.out.println(isNumber.isNumber(" 99e2.5"));//false + System.out.println(isNumber.isNumber("53.5e93"));//true + System.out.println(isNumber.isNumber(" --6")); //false + System.out.println(isNumber.isNumber("-+3")); //false + System.out.println(isNumber.isNumber("95a54e53"));//false + } + + /** + * 解题思路: + * 本题最大的难点在于各种情况互相依赖,后面想了想,每种情况只关注自己该放的位置就可以了 + * caseTest有1400多个,情况比较多,导致提交多次,比较全的caseTest参考上面链接 + * 1、输入左右可能有空格,先去除左右空格 + * 2、对于length==1的情况,直接判断是否是0-9 + * 3、添加几个计数器减少循环次数(e的个数、小数点的个数、+,-的个数) + * 4、开始循环 + * 5、对于数字:直接continue,01都是满足条件的 + * 6、对于+\-:最多出现2次(最前面和e的后面),出现直接可以跟数字和. + * 7、对于e:最多出现1次,出现的位置不能在头和尾 + * 8、对于.:最多1个点,如果之前出现过 e ,则后续不允许有点,出现以后其前后至少有一个数字 .1 + * + * + * 执行用时 :3 ms, 在所有 java 提交中击败了94.47%的用户 + * 内存消耗 :36 MB, 在所有 java 提交中击败了89.15%的用户 + * @param s + * @return + */ + public boolean isNumber(String s) { + //1、输入左右可能有空格,先去除左右空格 + s = s.trim(); + //2、对于length==1的情况,直接判断是否是0-9 + if (s.length() == 0) return false; + if (s.length() == 1) { + return isNumber(s.charAt(0)); + } + + //3、添加几个计数器减少循环次数 + //e的个数 + int eCount = 0; + //小数点的个数 + int dCount = 0; + //+,-的个数 + int oCount = 0; + + //4 + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (isNumber(c)) { + //5:直接continue,01都是满足条件的 + } else if (c == '-' || c == '+') { + //6:最多出现2次(最前面和e的后面),出现直接可以跟数字和. + if (oCount > 1) return false; + //对满足条件的取反 + if (!((i == 0 && (isNumber(s.charAt(i + 1)) || s.charAt(i + 1) == '.')) || (i > 0 && i < s.length() - 1 && s.charAt(i - 1) == 'e'))) { + return false; + } + oCount++; + } else if (c == 'e') { + //7、对于e:最多出现1次,出现的位置不能在头和尾 + if (eCount > 0) return false; + if (!(i > 0 && i < s.length() - 1)) { + return false; + } + eCount++; + } else if (c == '.') { + //8、对于.:最多1个点,如果之前出现过 e ,则后续不允许有点,出现以后其前后至少有一个数字 .1 + if (dCount > 0 || eCount > 0) return false; + //点前后必须有一个数字 + if (i == 0) { + if (!isNumber(s.charAt(i + 1))) + return false; + } else if (i == s.length() - 1) { + if (!isNumber(s.charAt(i - 1))) + return false; + } else { + if (!isNumber(s.charAt(i + 1)) && !isNumber(s.charAt(i - 1))) { + return false; + } + } + dCount++; + } else { + return false; + } + } + + return true; + } + + private boolean isNumber(char c) { + return c >= '0' && c <= '9'; + } + +} From 65f62a4c6259e79ce5b886b845d0ed6114647a49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 18 Oct 2019 16:46:38 +0800 Subject: [PATCH 196/308] docs: add _65_isNumber --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c082dff..2e7daf5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成222道 +- leetcode练习,坚持每天一道,目前已完成223道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -12,7 +12,7 @@ 扫题:顺序 -- [ ] [65. 有效数字 -Hard](https://leetcode-cn.com/problems/valid-number/) +- [x] [65. 有效数字 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_65_isNumber.java) - [ ] [66. 加一 -Easy](https://leetcode-cn.com/problems/plus-one/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成222) +### 题目列表(更新中—已完成223) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_4_domino.java) +[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_65_isNumber.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -129,6 +129,7 @@ | #62 | [不同路径](https://leetcode-cn.com/problems/unique-paths/) | [UniquePaths](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_62_uniquePaths.java) | [数组]()、[动态规划]() | Medium | | | #63 | [不同路径 II](https://leetcode-cn.com/problems/unique-paths-ii/) | [UniquePathsWithObstacles](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_63_uniquePathsWithObstacles.java) | [数组]()、[动态规划]() | Medium | | | #64 | [最小路径和](https://leetcode-cn.com/problems/minimum-path-sum/) | [MinPathSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_64_minPathSum.java) | [数组]()、[动态规划]() | Medium | | +| #65 | [有效数字](https://leetcode-cn.com/problems/valid-number/) | [IsNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_65_isNumber.java) | [数组]()、[字符串]() | Hard | | | #69 | [x 的平方根](https://leetcode-cn.com/problems/sqrtx/) | [MySqrt](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_69_mySqrt.java) | [数学]()、[二分查找]() | Easy | | | #70 | [爬楼梯](https://leetcode-cn.com/problems/climbing-stairs/) | [ClimbStairs](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_70_climbStairs.java) | [动态规划]() | Easy | 经典题 | | #71 | [简化路径](https://leetcode-cn.com/problems/simplify-path/) | [SimplifyPath](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_71_simplifyPath.java) | [栈](https://leetcode-cn.com/tag/stack/)、[字符串]() | Medium | | From 0e151683005febd34f52c577df44ef4896de0438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Sat, 19 Oct 2019 10:44:22 +0800 Subject: [PATCH 197/308] feat(EASY): add _66_plusOne --- src/pp/arithmetic/leetcode/_66_plusOne.java | 71 +++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_66_plusOne.java diff --git a/src/pp/arithmetic/leetcode/_66_plusOne.java b/src/pp/arithmetic/leetcode/_66_plusOne.java new file mode 100644 index 0000000..4a52270 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_66_plusOne.java @@ -0,0 +1,71 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wangpeng on 2019-10-19. + * 66. 加一 + *

+ * 给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。 + *

+ * 最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。 + *

+ * 你可以假设除了整数 0 之外,这个整数不会以零开头。 + *

+ * 示例 1: + *

+ * 输入: [1,2,3] + * 输出: [1,2,4] + * 解释: 输入数组表示数字 123。 + * 示例 2: + *

+ * 输入: [4,3,2,1] + * 输出: [4,3,2,2] + * 解释: 输入数组表示数字 4321。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/plus-one + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _66_plusOne { + + public static void main(String[] args) { + _66_plusOne plusOne = new _66_plusOne(); + Util.printArray(plusOne.plusOne(new int[]{1, 2, 3})); + Util.printArray(plusOne.plusOne(new int[]{4, 3, 2, 1})); + Util.printArray(plusOne.plusOne(new int[]{9, 9, 9})); + Util.printArray(plusOne.plusOne(new int[]{0})); + Util.printArray(plusOne.plusOne(new int[]{9})); + } + + /** + * 解题思路: + * 一道算数加法+1,需要注意两种情况: + * 1、低位向高位进位 ==> 从末尾开始遍历 + * 2、整数头需要进位 ==> 构建一个新数组保存返回结果 + * + * @param digits + * @return + */ + public int[] plusOne(int[] digits) { + List retList = new ArrayList<>(); + int highAdd = 1; //进位 + for (int i = digits.length - 1; i >= 0; i--) { + int newDigit = digits[i] + highAdd; + highAdd = newDigit / 10; + newDigit = newDigit % 10; + retList.add(0, newDigit); + } + if (highAdd > 0) retList.add(0, highAdd); + //listToArr + int[] retArr = new int[retList.size()]; + for (int i = 0; i < retList.size(); i++) { + retArr[i] = retList.get(i); + } + + return retArr; + } +} From 3c7be97efe6d834ac40d52177fdcfafc13a10870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Sat, 19 Oct 2019 10:48:07 +0800 Subject: [PATCH 198/308] docs: add _66_plusOne --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2e7daf5..d48a4b7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成223道 +- leetcode练习,坚持每天一道,目前已完成224道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -14,7 +14,7 @@ - [x] [65. 有效数字 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_65_isNumber.java) -- [ ] [66. 加一 -Easy](https://leetcode-cn.com/problems/plus-one/) +- [x] [66. 加一 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_66_plusOne.java) - [ ] [68. 文本左右对齐 -Hard](https://leetcode-cn.com/problems/text-justification/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成223) +### 题目列表(更新中—已完成224) -[Leetcode-Java(200+题解,持续更新、欢迎star)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_65_isNumber.java) +[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_66_plusOne.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -130,6 +130,7 @@ | #63 | [不同路径 II](https://leetcode-cn.com/problems/unique-paths-ii/) | [UniquePathsWithObstacles](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_63_uniquePathsWithObstacles.java) | [数组]()、[动态规划]() | Medium | | | #64 | [最小路径和](https://leetcode-cn.com/problems/minimum-path-sum/) | [MinPathSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_64_minPathSum.java) | [数组]()、[动态规划]() | Medium | | | #65 | [有效数字](https://leetcode-cn.com/problems/valid-number/) | [IsNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_65_isNumber.java) | [数组]()、[字符串]() | Hard | | +| #66 | [加一](https://leetcode-cn.com/problems/plus-one/) | [PlusOne](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_66_plusOne.java) | [数组]() | Easy | | | #69 | [x 的平方根](https://leetcode-cn.com/problems/sqrtx/) | [MySqrt](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_69_mySqrt.java) | [数学]()、[二分查找]() | Easy | | | #70 | [爬楼梯](https://leetcode-cn.com/problems/climbing-stairs/) | [ClimbStairs](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_70_climbStairs.java) | [动态规划]() | Easy | 经典题 | | #71 | [简化路径](https://leetcode-cn.com/problems/simplify-path/) | [SimplifyPath](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_71_simplifyPath.java) | [栈](https://leetcode-cn.com/tag/stack/)、[字符串]() | Medium | | From 9ad64b201b3398dde9684fb813c6cc56457c8046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 21 Oct 2019 11:05:24 +0800 Subject: [PATCH 199/308] feat(EASY): add _67_addBinary --- src/pp/arithmetic/leetcode/_67_addBinary.java | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_67_addBinary.java diff --git a/src/pp/arithmetic/leetcode/_67_addBinary.java b/src/pp/arithmetic/leetcode/_67_addBinary.java new file mode 100644 index 0000000..fc0eec9 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_67_addBinary.java @@ -0,0 +1,69 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-10-21. + * 67. 二进制求和 + *

+ * 给定两个二进制字符串,返回他们的和(用二进制表示)。 + *

+ * 输入为非空字符串且只包含数字 1 和 0。 + *

+ * 示例 1: + *

+ * 输入: a = "11", b = "1" + * 输出: "100" + * 示例 2: + *

+ * 输入: a = "1010", b = "1011" + * 输出: "10101" + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/add-binary + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _67_addBinary { + + public static void main(String[] args) { + _67_addBinary addBinary = new _67_addBinary(); + System.out.println(addBinary.addBinary("11", "1")); + System.out.println(addBinary.addBinary("1010", "1011")); + System.out.println(addBinary.addBinary("1111", "1111")); + } + + /** + * 解题思路: + * 从低位开始累加,注意两边字符串不一致,提高执行效率不要使用StringBuilder + * + * 执行用时 :1 ms, 在所有 java 提交中击败了100.00%的用户 + * 内存消耗 :36 MB, 在所有 java 提交中击败了55.45%的用户 + * + * @param a + * @param b + * @return + */ + public String addBinary(String a, String b) { + int i = a.length() - 1; + int j = b.length() - 1; + int carry = 0; + char[] result = new char[Math.max(i, j) + 1]; + int pos = result.length - 1; + while (i >= 0 || j >= 0) { + int sum = carry; + if (i >= 0) { + sum += a.charAt(i--) - '0'; + } + if (j >= 0) { + sum += b.charAt(j--) - '0'; + } + //>>1 代表 /2,进位 + carry = sum >> 1; + //sum & 0x01 ==> 进位后只取低位 + result[pos--] = (char) ((sum & 0x01) + '0'); + } + if (carry > 0) { //最后有进位,直接进行数据拼接,防止数组越界 + return "1" + String.valueOf(result); + } + return String.valueOf(result); + } +} + From 13e1768a7c1b7bd954d37866ff956ef717f90c36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 21 Oct 2019 11:10:13 +0800 Subject: [PATCH 200/308] docs: add _67_addBinary --- README.md | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index d48a4b7..600cc45 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成224道 +- leetcode练习,坚持每天一道,目前已完成225道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -12,19 +12,14 @@ 扫题:顺序 -- [x] [65. 有效数字 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_65_isNumber.java) - -- [x] [66. 加一 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_66_plusOne.java) - -- [ ] [68. 文本左右对齐 -Hard](https://leetcode-cn.com/problems/text-justification/) - -- [ ] [73. 矩阵置零 -Medium](https://leetcode-cn.com/problems/set-matrix-zeroes/) - -- [ ] [74. 搜索二维矩阵 -Medium](https://leetcode-cn.com/problems/search-a-2d-matrix/) - -- [ ] [81. 搜索旋转排序数组 II -Medium](https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/) - -- [ ] [82. 删除排序链表中的重复元素 II -Medium](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/) +- [x] [65. 有效数字 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_65_isNumber.java) +- [x] [66. 加一 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_66_plusOne.java) +- [x] [67. 二进制求和](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_67_addBinary.java) +- [ ] [68. 文本左右对齐 -Hard](https://leetcode-cn.com/problems/text-justification/) +- [ ] [73. 矩阵置零 -Medium](https://leetcode-cn.com/problems/set-matrix-zeroes/) +- [ ] [74. 搜索二维矩阵 -Medium](https://leetcode-cn.com/problems/search-a-2d-matrix/) +- [ ] [81. 搜索旋转排序数组 II -Medium](https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/) +- [ ] [82. 删除排序链表中的重复元素 II -Medium](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/) ## 已解题目 @@ -59,9 +54,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成224) +### 题目列表(更新中—已完成225) -[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_66_plusOne.java) +[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_67_addBinary.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -131,6 +126,7 @@ | #64 | [最小路径和](https://leetcode-cn.com/problems/minimum-path-sum/) | [MinPathSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_64_minPathSum.java) | [数组]()、[动态规划]() | Medium | | | #65 | [有效数字](https://leetcode-cn.com/problems/valid-number/) | [IsNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_65_isNumber.java) | [数组]()、[字符串]() | Hard | | | #66 | [加一](https://leetcode-cn.com/problems/plus-one/) | [PlusOne](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_66_plusOne.java) | [数组]() | Easy | | +| #67 | [二进制求和](https://leetcode-cn.com/problems/add-binary/) | [AddBinary](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_67_addBinary.java) | [数学]()、[字符串]() | Easy | | | #69 | [x 的平方根](https://leetcode-cn.com/problems/sqrtx/) | [MySqrt](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_69_mySqrt.java) | [数学]()、[二分查找]() | Easy | | | #70 | [爬楼梯](https://leetcode-cn.com/problems/climbing-stairs/) | [ClimbStairs](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_70_climbStairs.java) | [动态规划]() | Easy | 经典题 | | #71 | [简化路径](https://leetcode-cn.com/problems/simplify-path/) | [SimplifyPath](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_71_simplifyPath.java) | [栈](https://leetcode-cn.com/tag/stack/)、[字符串]() | Medium | | From fb57de72d5c6a5a3ef3f318ca1663c874a377d72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 22 Oct 2019 11:36:32 +0800 Subject: [PATCH 201/308] feat(HARD): add _68_fullJustify --- src/pp/arithmetic/Util.java | 2 +- .../arithmetic/leetcode/_68_fullJustify.java | 178 ++++++++++++++++++ 2 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 src/pp/arithmetic/leetcode/_68_fullJustify.java diff --git a/src/pp/arithmetic/Util.java b/src/pp/arithmetic/Util.java index 9999552..4db874e 100644 --- a/src/pp/arithmetic/Util.java +++ b/src/pp/arithmetic/Util.java @@ -126,7 +126,7 @@ public static void printStringList(List nums) { return; } for (int i = 0; i < nums.size(); i++) { - System.out.print(nums.get(i) + " "); + System.out.println(nums.get(i)); } System.out.println(); } diff --git a/src/pp/arithmetic/leetcode/_68_fullJustify.java b/src/pp/arithmetic/leetcode/_68_fullJustify.java new file mode 100644 index 0000000..7758884 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_68_fullJustify.java @@ -0,0 +1,178 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wangpeng on 2019-10-22. + * 68. 文本左右对齐 + * + * 给定一个单词数组和一个长度 maxWidth,重新排版单词,使其成为每行恰好有 maxWidth 个字符,且左右两端对齐的文本。 + * + * 你应该使用“贪心算法”来放置给定的单词;也就是说,尽可能多地往每行中放置单词。必要时可用空格 ' ' 填充,使得每行恰好有 maxWidth 个字符。 + * + * 要求尽可能均匀分配单词间的空格数量。如果某一行单词间的空格不能均匀分配,则左侧放置的空格数要多于右侧的空格数。 + * + * 文本的最后一行应为左对齐,且单词之间不插入额外的空格。 + * + * 说明: + * + * 单词是指由非空格字符组成的字符序列。 + * 每个单词的长度大于 0,小于等于 maxWidth。 + * 输入单词数组 words 至少包含一个单词。 + * 示例: + * + * 输入: + * words = ["This", "is", "an", "example", "of", "text", "justification."] + * maxWidth = 16 + * 输出: + * [ + *    "This    is    an", + *    "example  of text", + *    "justification.  " + * ] + * 示例 2: + * + * 输入: + * words = ["What","must","be","acknowledgment","shall","be"] + * maxWidth = 16 + * 输出: + * [ + *   "What   must   be", + *   "acknowledgment  ", + *   "shall be        " + * ] + * 解释: 注意最后一行的格式应为 "shall be " 而不是 "shall be", + *   因为最后一行应为左对齐,而不是左右两端对齐。 + * 第二行同样为左对齐,这是因为这行只包含一个单词。 + * 示例 3: + * + * 输入: + * words = ["Science","is","what","we","understand","well","enough","to","explain", + *   "to","a","computer.","Art","is","everything","else","we","do"] + * maxWidth = 20 + * 输出: + * [ + *   "Science  is  what we", + * "understand      well", + *   "enough to explain to", + *   "a  computer.  Art is", + *   "everything  else  we", + *   "do                  " + * ] + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/text-justification + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _68_fullJustify { + + public static void main(String[] args) { + _68_fullJustify fullJustify = new _68_fullJustify(); + Util.printStringList(fullJustify.fullJustify(new String[]{"This", "is", "an", "example", "of", "text", "justification."},16)); + Util.printStringList(fullJustify.fullJustify(new String[]{"What","must","be","acknowledgment","shall","be"},16)); + Util.printStringList(fullJustify.fullJustify(new String[]{"Science","is","what","we","understand","well","enough","to","explain", "to","a","computer.","Art","is","everything","else","we","do"},20)); + } + + /** + * 解题思路: + * 大致想法:先确定一行放几个单词,再跟根据条件对单词进行排序 + * 1、一行能放几个单词: + * 1.1:一个单词放下去之后占的位置是length+1(单词和单词直接至少有一个空格) + * 1.2:按照1.1的规则循环直到需要的长度>maxWidth + * 2、跟根据条件对单词进行排序: + * 2.1:对于只有一个单词的行,直接从左开始摆放 + * 2.2:对于只有2个单词的行,最左和最右摆放 + * 2.3:对于多余2个单词的行,先计算单词直接平均空格有多少个,剩余空格从左到右一个单词后逐个排布(肯定不会超过总单词数) + * 2.4:如是最后一行,则直接从左开始排序 + *

+ * 存储结构:maxWidth长度的数组保存 + * + * 执行用时 :1 ms, 在所有 java 提交中击败了99.05%的用户 + * 内存消耗 :34.9 MB, 在所有 java 提交中击败了40.26%的用户 + * + * @param words + * @param maxWidth + * @return + */ + public List fullJustify(String[] words, int maxWidth) { + List retList = new ArrayList<>(); + List lineList = new ArrayList<>(); + int leftWidth = maxWidth; + for (int i = 0; i < words.length; i++) { + String word = words[i]; + int wordWidth = word.length(); + if (leftWidth - wordWidth - lineList.size() < 0) { + //超过了需要换行了 + retList.add(handleSort(lineList, leftWidth, false)); + //换行重置 + leftWidth = maxWidth; + lineList.clear(); + } + lineList.add(word); + leftWidth -= wordWidth; + } + if (lineList.size()>0){ + retList.add(handleSort(lineList, leftWidth, true)); + } + + return retList; + } + + /** + * 2.1:对于只有一个单词的行,直接从左开始摆放 + * 2.2:对于只有2个单词的行,最左和最右摆放 + * 2.3:对于多余2个单词的行,先计算单词直接平均空格有多少个,剩余空格从左到右一个单词后逐个排布(肯定不会超过总单词数) + * 2.4:如是最后一行,则直接从左开始排序 + * + * @param lineList + * @param leftWidth + * @param isLastLine + * @return + */ + private String handleSort(List lineList, int leftWidth, boolean isLastLine) { + StringBuilder builder = new StringBuilder(); + if (isLastLine) { + for (int i = 0; i < lineList.size(); i++) { + builder.append(lineList.get(i)); + if (i != lineList.size() - 1) { + builder.append(" "); + leftWidth--; + } else { + for (int j = 0; j < leftWidth; j++) { + builder.append(" "); + } + } + } + } else { + //剩余空格数 + int empty = leftWidth; + //相等空格数 + int equalEmpty; + //左侧多余空格数 + int leftEmpty; + if (lineList.size() == 1) { + equalEmpty = empty; + leftEmpty = 0; + } else { + equalEmpty = empty / (lineList.size() - 1); + leftEmpty = empty % (lineList.size() - 1); + } + for (int i = 0; i < lineList.size(); i++) { + builder.append(lineList.get(i)); + if (i != lineList.size() - 1 || lineList.size() == 1) { + for (int j = 0; j < equalEmpty; j++) { + builder.append(" "); + } + if (leftEmpty-- > 0) { + builder.append(" "); + } + } + } + } + + return builder.toString(); + } +} From 04eb2c3570de2f19761b6cc34a30f46d0d07b0aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 22 Oct 2019 11:40:59 +0800 Subject: [PATCH 202/308] docs: add _68_fullJustify --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 600cc45..7bde261 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成225道 +- leetcode练习,坚持每天一道,目前已完成226道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -15,7 +15,7 @@ - [x] [65. 有效数字 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_65_isNumber.java) - [x] [66. 加一 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_66_plusOne.java) - [x] [67. 二进制求和](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_67_addBinary.java) -- [ ] [68. 文本左右对齐 -Hard](https://leetcode-cn.com/problems/text-justification/) +- [x] [68. 文本左右对齐 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_68_fullJustify.java) - [ ] [73. 矩阵置零 -Medium](https://leetcode-cn.com/problems/set-matrix-zeroes/) - [ ] [74. 搜索二维矩阵 -Medium](https://leetcode-cn.com/problems/search-a-2d-matrix/) - [ ] [81. 搜索旋转排序数组 II -Medium](https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/) @@ -54,9 +54,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成225) +### 题目列表(更新中—已完成226) -[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_67_addBinary.java) +[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_68_fullJustify.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -127,6 +127,7 @@ | #65 | [有效数字](https://leetcode-cn.com/problems/valid-number/) | [IsNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_65_isNumber.java) | [数组]()、[字符串]() | Hard | | | #66 | [加一](https://leetcode-cn.com/problems/plus-one/) | [PlusOne](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_66_plusOne.java) | [数组]() | Easy | | | #67 | [二进制求和](https://leetcode-cn.com/problems/add-binary/) | [AddBinary](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_67_addBinary.java) | [数学]()、[字符串]() | Easy | | +| #68 | [文本左右对齐](https://leetcode-cn.com/problems/text-justification/) | [FullJustify](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_68_fullJustify.java) | [字符串]() | Hard | | | #69 | [x 的平方根](https://leetcode-cn.com/problems/sqrtx/) | [MySqrt](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_69_mySqrt.java) | [数学]()、[二分查找]() | Easy | | | #70 | [爬楼梯](https://leetcode-cn.com/problems/climbing-stairs/) | [ClimbStairs](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_70_climbStairs.java) | [动态规划]() | Easy | 经典题 | | #71 | [简化路径](https://leetcode-cn.com/problems/simplify-path/) | [SimplifyPath](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_71_simplifyPath.java) | [栈](https://leetcode-cn.com/tag/stack/)、[字符串]() | Medium | | From fd630031eb29afd5af457dd5bdbbef8d74fb7130 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 23 Oct 2019 13:52:15 +0800 Subject: [PATCH 203/308] feat(MEDIUM): add _73_setZeroes --- src/pp/arithmetic/leetcode/_73_setZeroes.java | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_73_setZeroes.java diff --git a/src/pp/arithmetic/leetcode/_73_setZeroes.java b/src/pp/arithmetic/leetcode/_73_setZeroes.java new file mode 100644 index 0000000..9575df4 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_73_setZeroes.java @@ -0,0 +1,121 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-10-23. + * 73. 矩阵置零 + * + * 给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法。 + * + * 示例 1: + * + * 输入: + * [ + *   [1,1,1], + *   [1,0,1], + *   [1,1,1] + * ] + * 输出: + * [ + *   [1,0,1], + *   [0,0,0], + *   [1,0,1] + * ] + * 示例 2: + * + * 输入: + * [ + *   [0,1,2,0], + *   [3,4,5,2], + *   [1,3,1,5] + * ] + * 输出: + * [ + *   [0,0,0,0], + *   [0,4,5,0], + *   [0,3,1,0] + * ] + * 进阶: + * + * 一个直接的解决方案是使用  O(mn) 的额外空间,但这并不是一个好的解决方案。 + * 一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。 + * 你能想出一个常数空间的解决方案吗? + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/set-matrix-zeroes + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _73_setZeroes { + + public static void main(String[] args) { + _73_setZeroes setZeroes = new _73_setZeroes(); + int[][] matrix = new int[][]{ + {1, 1, 1}, + {0, 1, 2} + }; + setZeroes.setZeroes(matrix); + int[][] matrix1 = new int[][]{ + {1, 1, 1}, + {1, 0, 1}, + {1, 1, 1} + }; + setZeroes.setZeroes(matrix1); + int[][] matrix2 = new int[][]{ + {0, 1, 2, 0}, + {3, 4, 5, 2}, + {1, 3, 1, 5} + }; + setZeroes.setZeroes(matrix2); + } + + /** + * 难点在于:使用常数空间,我们先来看不适用常数空间咋解决 + * O(mn):直接生成一个同等大小的矩阵,遍历原始矩阵,遇0将新矩阵横竖都设置为0 + * O(m+n):两个set分别保存有0的横和竖列,遍历结束直接将set中的横竖设0 + * 解题思路: + * 1、利用矩阵的第一行和第一列保存有0的行和列 + * 2、需要考虑下特殊情况的[0,0],这个位置可能是横列、纵列、自身导致赋的0 + * + * 执行用时 :1 ms, 在所有 java 提交中击败了100.00%的用户 + * 内存消耗 :43.3 MB, 在所有 java 提交中击败了97.83%的用户 + * + * @param matrix + */ + public void setZeroes(int[][] matrix) { + boolean isCol = false; + int row = matrix.length; + int col = matrix[0].length; + + //使用第一行、第一列标记0 + for (int i = 0; i < row; i++) { + if (matrix[i][0] == 0) { + isCol = true; + } + for (int j = 1; j < col; j++) { + if (matrix[i][j] == 0) { + matrix[i][0] = 0; + matrix[0][j] = 0; + } + } + } + //横、竖列置0 + for (int i = 1; i < row; i++) { + for (int j = 1; j < col; j++) { + if (matrix[i][0] ==0 || matrix[0][j] == 0) { + matrix[i][j] = 0; + } + } + } + //[0,0]为0的时候,需要特殊判断下是横还是纵 + if (matrix[0][0] == 0) { + for (int j = 0; j < col; j++) { + matrix[0][j] = 0; + } + } + + if (isCol) { + for (int i = 0; i < row; i++) { + matrix[i][0] = 0; + } + } + } +} From 36c339917d5f29fa8eb09ab936c02447a102c490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 23 Oct 2019 13:57:29 +0800 Subject: [PATCH 204/308] docs: add _73_setZeroes --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7bde261..8ebb1d9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成226道 +- leetcode练习,坚持每天一道,目前已完成227道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -16,7 +16,7 @@ - [x] [66. 加一 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_66_plusOne.java) - [x] [67. 二进制求和](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_67_addBinary.java) - [x] [68. 文本左右对齐 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_68_fullJustify.java) -- [ ] [73. 矩阵置零 -Medium](https://leetcode-cn.com/problems/set-matrix-zeroes/) +- [x] [73. 矩阵置零 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_73_setZeroes.java) - [ ] [74. 搜索二维矩阵 -Medium](https://leetcode-cn.com/problems/search-a-2d-matrix/) - [ ] [81. 搜索旋转排序数组 II -Medium](https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/) - [ ] [82. 删除排序链表中的重复元素 II -Medium](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/) @@ -54,9 +54,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成226) +### 题目列表(更新中—已完成227) -[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_68_fullJustify.java) +[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_73_setZeroes.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -132,6 +132,7 @@ | #70 | [爬楼梯](https://leetcode-cn.com/problems/climbing-stairs/) | [ClimbStairs](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_70_climbStairs.java) | [动态规划]() | Easy | 经典题 | | #71 | [简化路径](https://leetcode-cn.com/problems/simplify-path/) | [SimplifyPath](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_71_simplifyPath.java) | [栈](https://leetcode-cn.com/tag/stack/)、[字符串]() | Medium | | | #72 | [编辑距离](https://leetcode-cn.com/problems/edit-distance/) | [MinDistance](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_72_minDistance.java) | [字符串]()、[动态规划]() | Hard | | +| #73 | [矩阵置零](https://leetcode-cn.com/problems/set-matrix-zeroes/) | [SetZeroes](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_73_setZeroes.java) | [数组]() | Medium | | | #75 | [颜色分类](https://leetcode-cn.com/problems/sort-colors/) | [SortColors](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_75_sortColors.java) | [排序](https://leetcode-cn.com/tag/sort/)、[数组]()、[双指针]() | Medium | | | #76 | [最小覆盖子串](https://leetcode-cn.com/problems/minimum-window-substring/) | [MinWindow](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_76_minWindow.java) | [哈希表]()、[双指针]()、[字符串]()、[sliding window]() | Hard | | | #77 | [组合](https://leetcode-cn.com/problems/combinations/) | [Combine](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_77_combine.java) | [回溯算法]() | Medium | | From 07bcf9e25d993730b6a3822fc7da60cac1498b68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 24 Oct 2019 12:50:35 +0800 Subject: [PATCH 205/308] feat(MEDIUM): add _74_searchMatrix --- .../arithmetic/leetcode/_74_searchMatrix.java | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_74_searchMatrix.java diff --git a/src/pp/arithmetic/leetcode/_74_searchMatrix.java b/src/pp/arithmetic/leetcode/_74_searchMatrix.java new file mode 100644 index 0000000..e63ee26 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_74_searchMatrix.java @@ -0,0 +1,107 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-10-24. + * 74. 搜索二维矩阵 + * + * 编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性: + * + * 每行中的整数从左到右按升序排列。 + * 每行的第一个整数大于前一行的最后一个整数。 + * 示例 1: + * + * 输入: + * matrix = [ + * [1, 3, 5, 7], + * [10, 11, 16, 20], + * [23, 30, 34, 50] + * ] + * target = 3 + * 输出: true + * 示例 2: + * + * 输入: + * matrix = [ + * [1, 3, 5, 7], + * [10, 11, 16, 20], + * [23, 30, 34, 50] + * ] + * target = 13 + * 输出: false + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/search-a-2d-matrix + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _74_searchMatrix { + + public static void main(String[] args) { + int[][] matrix = new int[][]{ + {1, 3, 5, 7}, + {10, 11, 16, 20}, + {23, 30, 34, 50} + }; + _74_searchMatrix searchMatrix = new _74_searchMatrix(); + System.out.println(searchMatrix.searchMatrix(matrix,1)); + System.out.println(searchMatrix.searchMatrix(matrix,3)); + System.out.println(searchMatrix.searchMatrix(matrix,5)); + System.out.println(searchMatrix.searchMatrix(matrix,7)); + System.out.println(searchMatrix.searchMatrix(matrix,10)); + System.out.println(searchMatrix.searchMatrix(matrix,11)); + System.out.println(searchMatrix.searchMatrix(matrix,16)); + System.out.println(searchMatrix.searchMatrix(matrix,20)); + System.out.println(searchMatrix.searchMatrix(matrix,23)); + System.out.println(searchMatrix.searchMatrix(matrix,50)); + System.out.println(searchMatrix.searchMatrix(matrix,13)); + System.out.println(searchMatrix.searchMatrix(matrix,40)); + } + + /** + * 解题思路: + * 整个矩阵类似一个有序的升序数组,考虑使用二分查找是否存在目标值 + * 难点:中间点的计算 + * 1.利用公式计算起点和终点之间的差:(ex - sx) * col + ey - sy, + * 2.中间点距离起点的步数:ml = ((ex - sx) * col + ey - sy) / 2 + * 3.mx = sx + (ml + sy) / col <== 起点+偏移计算出中间点的x + * 4.my = ml + sy - (mx - sx) * col <== 根据第一步的公式,代入mx,计算出my + * 5.利用二分查找的规则判断出结果 + * + * 执行用时 :0 ms, 在所有 java 提交中击败了100.00%的用户 + * 内存消耗 :42.6 MB, 在所有 java 提交中击败了39.56%的用户 + * + * @param matrix + * @param target + * @return + */ + public boolean searchMatrix(int[][] matrix, int target) { + if (matrix == null || matrix.length == 0) return false; + int row = matrix.length; + int col = matrix[0].length; + if (col == 0) return false; + int sx = 0, sy = 0, ex = row - 1, ey = col - 1; + if (target < matrix[sx][sy] || target > matrix[ex][ey]) return false; + int mx, my, ml; + while (sx * col + sy <= ex * col + ey) { + //计算中间点 + ml = ((ex - sx) * col + ey - sy) / 2; + mx = sx + (ml + sy) / col; + my = ml + sy - (mx - sx) * col; + int middle = matrix[mx][my]; + if (middle == target) return true; + //防止无法退出 + if (ml == 0) { + if (matrix[ex][ey] == target) return true; + return false; + } + if (middle > target) { + ex = mx; + ey = my; + } else { + sx = mx; + sy = my; + } + } + + return false; + } +} From fdcdff627107070d5fb4b9917349a3ba65c6f2cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 24 Oct 2019 12:54:35 +0800 Subject: [PATCH 206/308] docs: add _74_searchMatrix --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8ebb1d9..fd80778 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成227道 +- leetcode练习,坚持每天一道,目前已完成228道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -17,7 +17,7 @@ - [x] [67. 二进制求和](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_67_addBinary.java) - [x] [68. 文本左右对齐 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_68_fullJustify.java) - [x] [73. 矩阵置零 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_73_setZeroes.java) -- [ ] [74. 搜索二维矩阵 -Medium](https://leetcode-cn.com/problems/search-a-2d-matrix/) +- [x] [74. 搜索二维矩阵 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_74_searchMatrix.java) - [ ] [81. 搜索旋转排序数组 II -Medium](https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/) - [ ] [82. 删除排序链表中的重复元素 II -Medium](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/) @@ -54,9 +54,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成227) +### 题目列表(更新中—已完成228) -[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_73_setZeroes.java) +[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_74_searchMatrix.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -133,6 +133,7 @@ | #71 | [简化路径](https://leetcode-cn.com/problems/simplify-path/) | [SimplifyPath](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_71_simplifyPath.java) | [栈](https://leetcode-cn.com/tag/stack/)、[字符串]() | Medium | | | #72 | [编辑距离](https://leetcode-cn.com/problems/edit-distance/) | [MinDistance](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_72_minDistance.java) | [字符串]()、[动态规划]() | Hard | | | #73 | [矩阵置零](https://leetcode-cn.com/problems/set-matrix-zeroes/) | [SetZeroes](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_73_setZeroes.java) | [数组]() | Medium | | +| #74 | [搜索二维矩阵](https://leetcode-cn.com/problems/search-a-2d-matrix/) | [SearchMatrix](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_74_searchMatrix.java) | [数组]()、[二分查找]() | Medium | | | #75 | [颜色分类](https://leetcode-cn.com/problems/sort-colors/) | [SortColors](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_75_sortColors.java) | [排序](https://leetcode-cn.com/tag/sort/)、[数组]()、[双指针]() | Medium | | | #76 | [最小覆盖子串](https://leetcode-cn.com/problems/minimum-window-substring/) | [MinWindow](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_76_minWindow.java) | [哈希表]()、[双指针]()、[字符串]()、[sliding window]() | Hard | | | #77 | [组合](https://leetcode-cn.com/problems/combinations/) | [Combine](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_77_combine.java) | [回溯算法]() | Medium | | From c433e59936a0e0911f19f62e4ad7992963e2a0c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 30 Oct 2019 11:54:56 +0800 Subject: [PATCH 207/308] feat(MEDIUM): add _81_search --- src/pp/arithmetic/leetcode/_81_search.java | 71 ++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_81_search.java diff --git a/src/pp/arithmetic/leetcode/_81_search.java b/src/pp/arithmetic/leetcode/_81_search.java new file mode 100644 index 0000000..fe1de19 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_81_search.java @@ -0,0 +1,71 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-10-25. + * 81. 搜索旋转排序数组 II + * + * 假设按照升序排序的数组在预先未知的某个点上进行了旋转。 + * + * ( 例如,数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] )。 + * + * 编写一个函数来判断给定的目标值是否存在于数组中。若存在返回 true,否则返回 false。 + * + * 示例 1: + * + * 输入: nums = [2,5,6,0,0,1,2], target = 0 + * 输出: true + * 示例 2: + * + * 输入: nums = [2,5,6,0,0,1,2], target = 3 + * 输出: false + * 进阶: + * + * 这是 搜索旋转排序数组 的延伸题目,本题中的 nums  可能包含重复元素。 + * 这会影响到程序的时间复杂度吗?会有怎样的影响,为什么? + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _81_search { + + public static void main(String[] args) { + _81_search search = new _81_search(); + System.out.println(search.search(new int[]{2, 5, 6, 0, 0, 1, 2}, 0)); + System.out.println(search.search(new int[]{2, 5, 6, 0, 0, 1, 2}, 4)); + System.out.println(search.search(new int[]{1, 1, 3, 1}, 3)); + System.out.println(search.search(new int[]{3, 1, 1}, 3)); + } + + /** + * 解题思路: + * 整体解法类似 {@link _33_search},有序的数组使用二分查找效率最高,注意相同位置的判断 + * + * @param nums + * @param target + * @return + */ + public boolean search(int[] nums, int target) { + int left = 0; + int right = nums.length - 1; + while (left <= right) { + int mid = left + (right - left) / 2; + if (nums[mid] == target) return true; + if (nums[left] == nums[mid] && nums[mid] == nums[right]) { + left++; + right--; + } else if (nums[left] <= nums[mid]) { //确定左区间 + if (nums[left] <= target && target < nums[mid]) + right = mid - 1; + else + left = mid + 1; + } else { //确定右区间 + if (nums[mid] < target && target <= nums[right]) + left = mid + 1; + else + right = mid - 1; + } + } + return false; + } +} From 0d6abd64f5a30e6e1006120aea93dcf294c3b481 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 30 Oct 2019 11:57:45 +0800 Subject: [PATCH 208/308] docs: add _81_search --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index fd80778..2d7cb44 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成228道 +- leetcode练习,坚持每天一道,目前已完成229道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -18,7 +18,7 @@ - [x] [68. 文本左右对齐 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_68_fullJustify.java) - [x] [73. 矩阵置零 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_73_setZeroes.java) - [x] [74. 搜索二维矩阵 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_74_searchMatrix.java) -- [ ] [81. 搜索旋转排序数组 II -Medium](https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/) +- [x] [81. 搜索旋转排序数组 II -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_81_search.java) - [ ] [82. 删除排序链表中的重复元素 II -Medium](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/) ## 已解题目 @@ -54,9 +54,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成228) +### 题目列表(更新中—已完成229) -[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_74_searchMatrix.java) +[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_81_search.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -140,6 +140,7 @@ | #78 | [子集](https://leetcode-cn.com/problems/subsets/) | [Subsets](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_78_subsets.java) | [位运算](https://leetcode-cn.com/tag/bit-manipulation/)、[数组]()、[回溯算法]() | Medium | | | #79 | [单词搜索](https://leetcode-cn.com/problems/word-search/) | [Exist](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_79_exist.java) | [数组]()、[回溯算法]() | Medium | 经典题(回溯) | | #80 | [删除排序数组中的重复项 II](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array-ii/) | [RemoveDuplicates](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_80_removeDuplicates.java) | [数组]()、[双指针]() | Medium | | +| #81 | [搜索旋转排序数组 II](https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/) | [Search](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_81_search.java) | [数组]()、[二分查找]() | Medium | | | #84 | [柱状图中最大的矩形](https://leetcode-cn.com/problems/largest-rectangle-in-histogram/) | [LargestRectangleArea](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_84_largestRectangleArea.java) | [栈](https://leetcode-cn.com/tag/stack/)、[数组]() | Hard | 经典题(栈、分治) | | #85 | [最大矩形](https://leetcode-cn.com/problems/maximal-rectangle/) | [MaximalRectangle](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_85_maximalRectangle.java) | [栈](https://leetcode-cn.com/tag/stack/)、[数组]() | Hard | | | #86 | [分隔链表](https://leetcode-cn.com/problems/partition-list/) | [Partition](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_86_Partition.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Medium | | From 53d1e269698b322b200023b47e01898546c702a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 31 Oct 2019 10:59:48 +0800 Subject: [PATCH 209/308] feat(MEDIUM): add _82_deleteDuplicates --- .../leetcode/_82_deleteDuplicates.java | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_82_deleteDuplicates.java diff --git a/src/pp/arithmetic/leetcode/_82_deleteDuplicates.java b/src/pp/arithmetic/leetcode/_82_deleteDuplicates.java new file mode 100644 index 0000000..879d121 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_82_deleteDuplicates.java @@ -0,0 +1,93 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; +import pp.arithmetic.model.ListNode; + +/** + * Created by wangpeng on 2019-10-31. + * 82. 删除排序链表中的重复元素 II + * + * 给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。 + * + * 示例 1: + * + * 输入: 1->2->3->3->4->4->5 + * 输出: 1->2->5 + * 示例 2: + * + * 输入: 1->1->1->2->3 + * 输出: 2->3 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _82_deleteDuplicates { + + public static void main(String[] args) { + _82_deleteDuplicates deleteDuplicates = new _82_deleteDuplicates(); + //1->2->3->3->4->4->5 + ListNode head1 = new ListNode(1); + head1.next = new ListNode(2); + head1.next.next = new ListNode(3); + head1.next.next.next = new ListNode(3); + head1.next.next.next.next = new ListNode(4); + head1.next.next.next.next.next = new ListNode(4); + head1.next.next.next.next.next.next = new ListNode(5); + Util.printListNode(deleteDuplicates.deleteDuplicates(head1)); + //1->1->1->2->3 + ListNode head2 = new ListNode(1); + head2.next = new ListNode(1); + head2.next.next = new ListNode(1); + head2.next.next.next = new ListNode(2); + head2.next.next.next.next = new ListNode(3); + Util.printListNode(deleteDuplicates.deleteDuplicates(head2)); + } + + /** + * 解题思路: + * 对于链表类型的题目,就是按照next的指针进行遍历,找到题目要求 + * 1、定义四个指针: + * 一个头结点的前置虚拟指针==>方便返回结果的头结点, + * 一个前置指针==>方便切断遍历相同节点, + * 一个遍历指针, + * 一个搜寻相同指针的尾结点==>定位结尾 + * 2、找到满足条件的,将前置指针的next指向尾结点的next + * + * 执行用时 :1 ms, 在所有 java 提交中击败了99.26%的用户 + * 内存消耗 :37 MB, 在所有 java 提交中击败了57.65%的用户 + * + * @param head + * @return + */ + public ListNode deleteDuplicates(ListNode head) { + //头结点的前置虚拟指针 + ListNode dummy = new ListNode(0); + dummy.next = head; + //前置指针 + ListNode preNode = head; + //遍历指针 + ListNode node = head; + //尾结点指针 + ListNode endNode ; + while (node != null ) { + endNode = node.next; + while (endNode != null && endNode.val == node.val) { + endNode = endNode.next; + } + if (node.next == endNode){ + //不是重复的 + preNode = node; + }else{ + //存在重复的 + preNode.next = endNode; + if (dummy.next == node){ + dummy.next = endNode; + } + } + node = endNode; + } + + return dummy.next; + } +} From f2d0bbd2f491039375734d0618be83ed397e7b47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 4 Nov 2019 21:21:38 +0800 Subject: [PATCH 210/308] feat(EASY): add _83_deleteDuplicates --- .../leetcode/_83_deleteDuplicates.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_83_deleteDuplicates.java diff --git a/src/pp/arithmetic/leetcode/_83_deleteDuplicates.java b/src/pp/arithmetic/leetcode/_83_deleteDuplicates.java new file mode 100644 index 0000000..ff232d3 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_83_deleteDuplicates.java @@ -0,0 +1,63 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; +import pp.arithmetic.model.ListNode; + +/** + * Created by wangpeng on 2019-11-04. + * 83. 删除排序链表中的重复元素 + * + * 给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。 + * + * 示例 1: + * + * 输入: 1->1->2 + * 输出: 1->2 + * 示例 2: + * + * 输入: 1->1->2->3->3 + * 输出: 1->2->3 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _83_deleteDuplicates { + + public static void main(String[] args) { + _83_deleteDuplicates deleteDuplicates = new _83_deleteDuplicates(); + ListNode node = new ListNode(1); + node.next = new ListNode(1); + node.next.next = new ListNode(2); + Util.printListNode(deleteDuplicates.deleteDuplicates(node)); + ListNode node1 = new ListNode(1); + node1.next = new ListNode(1); + node1.next.next = new ListNode(2); + node1.next.next.next = new ListNode(3); + node1.next.next.next.next = new ListNode(3); + Util.printListNode(deleteDuplicates.deleteDuplicates(node1)); + } + + /** + * 解题思路:典型的列表遍历 + * + * @param head + * @return + */ + public ListNode deleteDuplicates(ListNode head) { + ListNode dummy = new ListNode(0); + dummy.next = head; + ListNode next = head; + ListNode preEqual; + while (next != null) { + preEqual = next.next; + while (preEqual!=null&&preEqual.val == next.val){ + preEqual = preEqual.next; + } + next.next = preEqual; + next = preEqual; + } + + return dummy.next; + } +} From bd1448850883bd24783e47ebd66ec08858d6f4f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 4 Nov 2019 21:31:18 +0800 Subject: [PATCH 211/308] docs: add deleteDuplicates --- README.md | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 2d7cb44..5b5dc5a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成229道 +- leetcode练习,坚持每天一道,目前已完成231道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -12,20 +12,25 @@ 扫题:顺序 -- [x] [65. 有效数字 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_65_isNumber.java) -- [x] [66. 加一 -Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_66_plusOne.java) -- [x] [67. 二进制求和](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_67_addBinary.java) -- [x] [68. 文本左右对齐 -Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_68_fullJustify.java) -- [x] [73. 矩阵置零 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_73_setZeroes.java) -- [x] [74. 搜索二维矩阵 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_74_searchMatrix.java) -- [x] [81. 搜索旋转排序数组 II -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_81_search.java) -- [ ] [82. 删除排序链表中的重复元素 II -Medium](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/) +- [x] [83. 删除排序链表中的重复元素](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_83_deleteDuplicates.java) + +- [ ] [87. 扰乱字符串](https://leetcode-cn.com/problems/scramble-string/) + +- [ ] [88. 合并两个有序数组](https://leetcode-cn.com/problems/merge-sorted-array/) + +- [ ] [89. 格雷编码](https://leetcode-cn.com/problems/gray-code/) + +- [ ] [97. 交错字符串](https://leetcode-cn.com/problems/interleaving-string/) + +- [ ] [99. 恢复二叉搜索树](https://leetcode-cn.com/problems/recover-binary-search-tree/) + +- [ ] [100. 相同的树](https://leetcode-cn.com/problems/same-tree/) ## 已解题目 > 20190404# leetcode目前已有题目1020道,免费852道 -### 题目类型(更新中) +### 题目类型(更新中...) - [数组]()(168) - [哈希表]()(102) @@ -54,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成229) +### 题目列表(更新中—已完成231) -[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_81_search.java) +[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_83_deleteDuplicates.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -141,6 +146,8 @@ | #79 | [单词搜索](https://leetcode-cn.com/problems/word-search/) | [Exist](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_79_exist.java) | [数组]()、[回溯算法]() | Medium | 经典题(回溯) | | #80 | [删除排序数组中的重复项 II](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array-ii/) | [RemoveDuplicates](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_80_removeDuplicates.java) | [数组]()、[双指针]() | Medium | | | #81 | [搜索旋转排序数组 II](https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/) | [Search](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_81_search.java) | [数组]()、[二分查找]() | Medium | | +| #82 | [删除排序链表中的重复元素 II](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/) | [DeleteDuplicates](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_82_deleteDuplicates.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | +| #83 | [删除排序链表中的重复元素](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/) | [DeleteDuplicates](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_83_deleteDuplicates.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Easy | | | #84 | [柱状图中最大的矩形](https://leetcode-cn.com/problems/largest-rectangle-in-histogram/) | [LargestRectangleArea](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_84_largestRectangleArea.java) | [栈](https://leetcode-cn.com/tag/stack/)、[数组]() | Hard | 经典题(栈、分治) | | #85 | [最大矩形](https://leetcode-cn.com/problems/maximal-rectangle/) | [MaximalRectangle](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_85_maximalRectangle.java) | [栈](https://leetcode-cn.com/tag/stack/)、[数组]() | Hard | | | #86 | [分隔链表](https://leetcode-cn.com/problems/partition-list/) | [Partition](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_86_Partition.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Medium | | From 4d42e089a37078ce9312edf4c6eb1e521606a85d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 6 Nov 2019 14:56:27 +0800 Subject: [PATCH 212/308] feat(HARD): add _87_isScramble --- .../arithmetic/leetcode/_87_isScramble.java | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_87_isScramble.java diff --git a/src/pp/arithmetic/leetcode/_87_isScramble.java b/src/pp/arithmetic/leetcode/_87_isScramble.java new file mode 100644 index 0000000..82e2664 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_87_isScramble.java @@ -0,0 +1,110 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-11-05. + * 87. 扰乱字符串 + * + * 下图是字符串 s1 = "great" 的一种可能的表示形式。 + * + * great + * / \ + * gr eat + * / \ / \ + * g r e at + * / \ + * a t + * 在扰乱这个字符串的过程中,我们可以挑选任何一个非叶节点,然后交换它的两个子节点。 + * + * 例如,如果我们挑选非叶节点 "gr" ,交换它的两个子节点,将会产生扰乱字符串 "rgeat" 。 + * + * rgeat + * / \ + * rg eat + * / \ / \ + * r g e at + * / \ + * a t + * 我们将 "rgeat” 称作 "great" 的一个扰乱字符串。 + * + * 同样地,如果我们继续交换节点 "eat" 和 "at" 的子节点,将会产生另一个新的扰乱字符串 "rgtae" 。 + * + * rgtae + * / \ + * rg tae + * / \ / \ + * r g ta e + * / \ + * t a + * 我们将 "rgtae” 称作 "great" 的一个扰乱字符串。 + * + * 给出两个长度相等的字符串 s1 和 s2,判断 s2 是否是 s1 的扰乱字符串。 + * + * 示例 1: + * + * 输入: s1 = "great", s2 = "rgeat" + * 输出: true + * 示例 2: + * + * 输入: s1 = "abcde", s2 = "caebd" + * 输出: false + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/scramble-string + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _87_isScramble { + + public static void main(String[] args) { + _87_isScramble isScramble = new _87_isScramble(); + System.out.println(isScramble.isScramble("great","rgeat")); + System.out.println(isScramble.isScramble("abcde","caebd")); + } + + /** + * 解题思路: + * 对于两个字符串,比较是否相等,有两种情景 + * 1:字符串本身就相等 + * 2:基于某个节点交换后相等==>此种情况可以将旋转后的子字符串代入第一种情况进行判断 + * + * 对于上述两种情况可以将字符串分解成两部分(从0开始拆解) + * + * @param s1 + * @param s2 + * @return + */ + public boolean isScramble(String s1, String s2) { + if (s1.length() != s2.length()) { + return false; + } + if (s1.equals(s2)) { + return true; + } + + //判断两个字符串每个字母出现的次数是否一致 + int[] letters = new int[26]; + for (int i = 0; i < s1.length(); i++) { + letters[s1.charAt(i) - 'a']++; + letters[s2.charAt(i) - 'a']--; + } + //如果两个字符串的字母出现不一致直接返回 false + for (int i = 0; i < 26; i++) { + if (letters[i] != 0) { + return false; + } + } + + //遍历每个切割位置 + for (int i = 1; i < s1.length(); i++) { + //对应情况 1 ,判断 S1 的子树能否变为 S2 相应部分 + if (isScramble(s1.substring(0, i), s2.substring(0, i)) && isScramble(s1.substring(i), s2.substring(i))) { + return true; + } + //对应情况 2 ,S1 两个子树先进行了交换,然后判断 S1 的子树能否变为 S2 相应部分 + if (isScramble(s1.substring(i), s2.substring(0, s2.length() - i)) && + isScramble(s1.substring(0, i), s2.substring(s2.length() - i)) ) { + return true; + } + } + return false; + } +} From e1a831624651346f87f1d8e1148b895927fc259d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 6 Nov 2019 15:10:03 +0800 Subject: [PATCH 213/308] docs: add _87_isScramble --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5b5dc5a..bc8677e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成231道 +- leetcode练习,坚持每天一道,目前已完成232道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -14,7 +14,7 @@ - [x] [83. 删除排序链表中的重复元素](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_83_deleteDuplicates.java) -- [ ] [87. 扰乱字符串](https://leetcode-cn.com/problems/scramble-string/) +- [x] [87. 扰乱字符串](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_87_isScramble.java) - [ ] [88. 合并两个有序数组](https://leetcode-cn.com/problems/merge-sorted-array/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成231) +### 题目列表(更新中—已完成232) -[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_83_deleteDuplicates.java) +[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_87_isScramble.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -151,6 +151,7 @@ | #84 | [柱状图中最大的矩形](https://leetcode-cn.com/problems/largest-rectangle-in-histogram/) | [LargestRectangleArea](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_84_largestRectangleArea.java) | [栈](https://leetcode-cn.com/tag/stack/)、[数组]() | Hard | 经典题(栈、分治) | | #85 | [最大矩形](https://leetcode-cn.com/problems/maximal-rectangle/) | [MaximalRectangle](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_85_maximalRectangle.java) | [栈](https://leetcode-cn.com/tag/stack/)、[数组]() | Hard | | | #86 | [分隔链表](https://leetcode-cn.com/problems/partition-list/) | [Partition](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_86_Partition.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Medium | | +| #87 | [扰乱字符串](https://leetcode-cn.com/problems/scramble-string/) | [IsScramble](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_87_isScramble.java) | [字符串]()、[动态规划]() | Hard | | | #90 | [子集 II](https://leetcode-cn.com/problems/subsets-ii/) | [SubsetsWithDup](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_90_subsetsWithDup.java) | [数组]()、[回溯算法]() | Medium | | | #91 | [解码方法](https://leetcode-cn.com/problems/decode-ways/) | [NumDecodings](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_91_numDecodings.java) | [字符串]()、[动态规划]() | Medium | | | #92 | [反转链表 II](https://leetcode-cn.com/problems/reverse-linked-list-ii/) | [ReverseBetween](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_92_ReverseBetween.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | From 1c0c2a7a8db336a1509823c1859d6f0f705ddf2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 7 Nov 2019 11:53:38 +0800 Subject: [PATCH 214/308] feat(EASY): add _88_merge --- src/pp/arithmetic/leetcode/_88_merge.java | 69 +++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_88_merge.java diff --git a/src/pp/arithmetic/leetcode/_88_merge.java b/src/pp/arithmetic/leetcode/_88_merge.java new file mode 100644 index 0000000..1719058 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_88_merge.java @@ -0,0 +1,69 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +/** + * Created by wangpeng on 2019-11-07. + * 88. 合并两个有序数组 + * + * 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。 + * + * 说明: + * + * 初始化 nums1 和 nums2 的元素数量分别为 m 和 n。 + * 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。 + * 示例: + * + * 输入: + * nums1 = [1,2,3,0,0,0], m = 3 + * nums2 = [2,5,6], n = 3 + * + * 输出: [1,2,2,3,5,6] + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/merge-sorted-array + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _88_merge { + + public static void main(String[] args) { + _88_merge merge = new _88_merge(); + int[] nums1 = new int[]{1, 2, 3, 0, 0, 0, 0, 0}; + int[] nums2 = new int[]{1, 1, 2, 5, 6}; + merge.merge(nums1, 0, nums2, 5); + Util.printArray(nums1); + } + + /** + * 解题思路: + * 同时遍历两个数组,比较各自的大小,插入到相应的位置,由于nums1有额外的位置,所以从后面开始插入大元素可以减少元素的移动 + * + * @param nums1 + * @param m + * @param nums2 + * @param n + */ + public void merge(int[] nums1, int m, int[] nums2, int n) { + while (m > 0 || n > 0) { + int numM; + int numN; + if (m > 0 && n > 0) { + numM = nums1[m - 1]; + numN = nums2[n - 1]; + if (numM > numN) { + nums1[m + n - 1] = numM; + m--; + } else { + nums1[m + n - 1] = numN; + n--; + } + } else if (m > 0) { + //只剩下nums1,肯定是有序的 + break; + } else { + nums1[n - 1] = nums2[n - 1]; + n--; + } + } + } +} From 29afa3b19346900cb860d45e7423bcf63f53a7e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 7 Nov 2019 11:56:37 +0800 Subject: [PATCH 215/308] docs: add _88_merge --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index bc8677e..37d9a0f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成232道 +- leetcode练习,坚持每天一道,目前已完成233道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -16,7 +16,7 @@ - [x] [87. 扰乱字符串](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_87_isScramble.java) -- [ ] [88. 合并两个有序数组](https://leetcode-cn.com/problems/merge-sorted-array/) +- [x] [88. 合并两个有序数组](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_88_merge.java) - [ ] [89. 格雷编码](https://leetcode-cn.com/problems/gray-code/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成232) +### 题目列表(更新中—已完成233) -[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_87_isScramble.java) +[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_88_merge.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -152,6 +152,7 @@ | #85 | [最大矩形](https://leetcode-cn.com/problems/maximal-rectangle/) | [MaximalRectangle](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_85_maximalRectangle.java) | [栈](https://leetcode-cn.com/tag/stack/)、[数组]() | Hard | | | #86 | [分隔链表](https://leetcode-cn.com/problems/partition-list/) | [Partition](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_86_Partition.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Medium | | | #87 | [扰乱字符串](https://leetcode-cn.com/problems/scramble-string/) | [IsScramble](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_87_isScramble.java) | [字符串]()、[动态规划]() | Hard | | +| #88 | [合并两个有序数组](https://leetcode-cn.com/problems/merge-sorted-array/) | [Merge](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_88_merge.java) | [数组]()、[双指针]() | Easy | | | #90 | [子集 II](https://leetcode-cn.com/problems/subsets-ii/) | [SubsetsWithDup](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_90_subsetsWithDup.java) | [数组]()、[回溯算法]() | Medium | | | #91 | [解码方法](https://leetcode-cn.com/problems/decode-ways/) | [NumDecodings](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_91_numDecodings.java) | [字符串]()、[动态规划]() | Medium | | | #92 | [反转链表 II](https://leetcode-cn.com/problems/reverse-linked-list-ii/) | [ReverseBetween](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_92_ReverseBetween.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | From c4d9223a3fb47c2ea425760da64a32cae5ca9426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 26 Nov 2019 15:50:05 +0800 Subject: [PATCH 216/308] feat(MEDIUM): add _89_grayCode --- src/pp/arithmetic/leetcode/_89_grayCode.java | 71 ++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_89_grayCode.java diff --git a/src/pp/arithmetic/leetcode/_89_grayCode.java b/src/pp/arithmetic/leetcode/_89_grayCode.java new file mode 100644 index 0000000..2abc394 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_89_grayCode.java @@ -0,0 +1,71 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wangpeng on 2019-11-09. + * 89. 格雷编码 + *

+ * 格雷编码是一个二进制数字系统,在该系统中,两个连续的数值仅有一个位数的差异。 + *

+ * 给定一个代表编码总位数的非负整数 n,打印其格雷编码序列。格雷编码序列必须以 0 开头。 + *

+ * 示例 1: + *

+ * 输入: 2 + * 输出: [0,1,3,2] + * 解释: + * 00 - 0 + * 01 - 1 + * 11 - 3 + * 10 - 2 + *

+ * 对于给定的 n,其格雷编码序列并不唯一。 + * 例如,[0,2,3,1] 也是一个有效的格雷编码序列。 + *

+ * 00 - 0 + * 10 - 2 + * 11 - 3 + * 01 - 1 + * 示例 2: + *

+ * 输入: 0 + * 输出: [0] + * 解释: 我们定义格雷编码序列必须以 0 开头。 + *   给定编码总位数为 n 的格雷编码序列,其长度为 2^n。当 n = 0 时,长度为 2^0 = 1。 + *   因此,当 n = 0 时,其格雷编码序列为 [0]。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/gray-code + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _89_grayCode { + + public static void main(String[] args) { + _89_grayCode grayCode = new _89_grayCode(); + Util.printList(grayCode.grayCode(2)); + } + + /** + * 解题思路: + * + * @param n + * @return + */ + public List grayCode(int n) { + List gray = new ArrayList<>(); + gray.add(0); //初始化 n = 0 的解 + for (int i = 0; i < n; i++) { + int add = 1 << i; //要加的数 + //倒序遍历,并且加上一个值添加到结果中 + for (int j = gray.size() - 1; j >= 0; j--) { + gray.add(gray.get(j) + add); + } + } + return gray; + } + +} From ee3880ce39b2c838bf55f6aa35f10bc6838edf62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 26 Nov 2019 15:52:20 +0800 Subject: [PATCH 217/308] docs: add _89_grayCode --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 37d9a0f..db4c481 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成233道 +- leetcode练习,坚持每天一道,目前已完成234道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -18,7 +18,7 @@ - [x] [88. 合并两个有序数组](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_88_merge.java) -- [ ] [89. 格雷编码](https://leetcode-cn.com/problems/gray-code/) +- [x] [89. 格雷编码](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_89_grayCode.java) - [ ] [97. 交错字符串](https://leetcode-cn.com/problems/interleaving-string/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成233) +### 题目列表(更新中—已完成234) -[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_88_merge.java) +[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_89_grayCode.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -153,6 +153,7 @@ | #86 | [分隔链表](https://leetcode-cn.com/problems/partition-list/) | [Partition](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_86_Partition.java) | [链表](https://leetcode-cn.com/tag/linked-list/)、[双指针]() | Medium | | | #87 | [扰乱字符串](https://leetcode-cn.com/problems/scramble-string/) | [IsScramble](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_87_isScramble.java) | [字符串]()、[动态规划]() | Hard | | | #88 | [合并两个有序数组](https://leetcode-cn.com/problems/merge-sorted-array/) | [Merge](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_88_merge.java) | [数组]()、[双指针]() | Easy | | +| #89 | [格雷编码](https://leetcode-cn.com/problems/gray-code/) | [GrayCode](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_89_grayCode.java) | [回溯算法]() | Medium | | | #90 | [子集 II](https://leetcode-cn.com/problems/subsets-ii/) | [SubsetsWithDup](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_90_subsetsWithDup.java) | [数组]()、[回溯算法]() | Medium | | | #91 | [解码方法](https://leetcode-cn.com/problems/decode-ways/) | [NumDecodings](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_91_numDecodings.java) | [字符串]()、[动态规划]() | Medium | | | #92 | [反转链表 II](https://leetcode-cn.com/problems/reverse-linked-list-ii/) | [ReverseBetween](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_92_ReverseBetween.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | From a173301f46d8fc1e3e00b7a3fe70f260cfbe57aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 28 Nov 2019 10:08:27 +0800 Subject: [PATCH 218/308] feat(HARD): add _97_isInterleave --- .../arithmetic/leetcode/_97_isInterleave.java | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_97_isInterleave.java diff --git a/src/pp/arithmetic/leetcode/_97_isInterleave.java b/src/pp/arithmetic/leetcode/_97_isInterleave.java new file mode 100644 index 0000000..4862a18 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_97_isInterleave.java @@ -0,0 +1,65 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-11-27. + * 97. 交错字符串 + *

+ * 给定三个字符串 s1, s2, s3, 验证 s3 是否是由 s1 和 s2 交错组成的。 + *

+ * 示例 1: + *

+ * 输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac" + * 输出: true + * 示例 2: + *

+ * 输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc" + * 输出: false + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/interleaving-string + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _97_isInterleave { + + public static void main(String[] args) { + _97_isInterleave isInterleave = new _97_isInterleave(); + System.out.println(isInterleave.isInterleave("a", "bbbbbbb", "abbbbbba")); + System.out.println(isInterleave.isInterleave("aabcc", "dbbca", "aadbbcbcac")); + System.out.println(isInterleave.isInterleave("aabcc", "dbbca", "aadbbbaccc")); + System.out.println(isInterleave.isInterleave("a", "", "c")); + System.out.println(isInterleave.isInterleave("ab", "bc", "bbac")); + } + + /** + * 解题思路:循环比较,回溯算法 + * 先比较第i位+比较后面的位,如果第i位后面的都能匹配上,加上第i位也能匹配上,那么就能完全匹配。i从0开始 + * + * 执行用时 :1362 ms, 在所有 java 提交中击败了5.10%的用户 + * 内存消耗 :34.7 MB, 在所有 java 提交中击败了42.29%的用户 + * + * @param s1、 + * @param s2 + * @param s3 + * @return + */ + public boolean isInterleave(String s1, String s2, String s3) { + if (s3.length() != s1.length() + s2.length()) return false; + return isInterleave(s1, s2, s3, 0, 0, 0); + } + + private boolean isInterleave(String s1, String s2, String s3, int i1, int i2, int i3) { + if (i3 == s3.length()) return true; + char c3 = s3.charAt(i3); + if (((i1 < s1.length() && s1.charAt(i1) != c3) || "".equals(s1)) && + ((i2 < s2.length() && s2.charAt(i2) != c3) || "".equals(s2))) { + return false; + } + if (i1 < s1.length() && s1.charAt(i1) == c3 && isInterleave(s1, s2, s3, i1 + 1, i2, i3 + 1)) { + return true; + } + if (i2 < s2.length() && s2.charAt(i2) == c3 && isInterleave(s1, s2, s3, i1, i2 + 1, i3 + 1)) { + return true; + } + return false; + } +} From 90ea0810c985f4552513bf1386f339dfedb3db27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 28 Nov 2019 10:12:56 +0800 Subject: [PATCH 219/308] docs: add _97_isInterleave --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index db4c481..f195313 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成234道 +- leetcode练习,坚持每天一道,目前已完成235道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -20,7 +20,7 @@ - [x] [89. 格雷编码](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_89_grayCode.java) -- [ ] [97. 交错字符串](https://leetcode-cn.com/problems/interleaving-string/) +- [x] [97. 交错字符串](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_97_isInterleave.java) - [ ] [99. 恢复二叉搜索树](https://leetcode-cn.com/problems/recover-binary-search-tree/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成234) +### 题目列表(更新中—已完成235) -[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_89_grayCode.java) +[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_97_isInterleave.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -160,6 +160,7 @@ | #93 | [复原IP地址](https://leetcode-cn.com/problems/restore-ip-addresses/) | [RestoreIpAddresses](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_93_restoreIpAddresses.java) | [字符串]()、[回溯算法]() | Medium | | | #94 | [二叉树的中序遍历](https://leetcode-cn.com/problems/binary-tree-inorder-traversal/) | [InorderTraversal](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_94_inorderTraversal.java) | [栈](https://leetcode-cn.com/tag/stack/)、[树](https://leetcode-cn.com/tag/tree/)、[哈希表]() | Medium | | | #95 | [不同的二叉搜索树 II](https://leetcode-cn.com/problems/unique-binary-search-trees-ii/) | [GenerateTrees](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_95_generateTrees.java) | [树](https://leetcode-cn.com/tag/tree/)、[动态规划]() | Medium | DP实现未想到 | +| #97 | [交错字符串](https://leetcode-cn.com/problems/interleaving-string/) | [IsInterleave](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_97_isInterleave.java) | [字符串]()、[动态规划]() | Hard | | | #98 | [验证二叉搜索树](https://leetcode-cn.com/problems/validate-binary-search-tree/) | [IsValidBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_98_isValidBST.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #101 | [对称二叉树](https://leetcode-cn.com/problems/symmetric-tree/) | [IsSymmetric](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_101_isSymmetric.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Easy | | | #102 | [二叉树的层次遍历](https://leetcode-cn.com/problems/binary-tree-level-order-traversal/) | [LevelOrder](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_102_levelOrder.java) | [树](https://leetcode-cn.com/tag/tree/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Medium | | From 131403a66aa9bc431c77791a52fdcf65e18f7547 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 3 Dec 2019 14:34:32 +0800 Subject: [PATCH 220/308] feat(HARD): add _99_recoverTree --- .../arithmetic/leetcode/_99_recoverTree.java | 153 ++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_99_recoverTree.java diff --git a/src/pp/arithmetic/leetcode/_99_recoverTree.java b/src/pp/arithmetic/leetcode/_99_recoverTree.java new file mode 100644 index 0000000..50d5d6e --- /dev/null +++ b/src/pp/arithmetic/leetcode/_99_recoverTree.java @@ -0,0 +1,153 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; +import pp.arithmetic.model.TreeNode; + +/** + * Created by wangpeng on 2019-12-01. + * 99. 恢复二叉搜索树 + * + * 二叉搜索树中的两个节点被错误地交换。 + * + * 请在不改变其结构的情况下,恢复这棵树。 + * + * 示例 1: + * + * 输入: [1,3,null,null,2] + * + *   1 + *   / + *  3 + *   \ + *   2 + * + * 输出: [3,1,null,null,2] + * + *   3 + *   / + *  1 + *   \ + *   2 + * 示例 2: + * + * 输入: [3,1,4,null,null,2] + * + * 3 + * / \ + * 1 4 + *   / + *   2 + * + * 输出: [2,1,4,null,null,3] + * + * 2 + * / \ + * 1 4 + *   / + *  3 + * 进阶: + * + * 使用 O(n) 空间复杂度的解法很容易实现。 + * 你能想出一个只使用常数空间的解决方案吗? + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/recover-binary-search-tree + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _99_recoverTree { + + public static void main(String[] args) { + TreeNode treeNode = new TreeNode(1); + treeNode.left = new TreeNode(3); + treeNode.left.right = new TreeNode(2); + _99_recoverTree recoverTree = new _99_recoverTree(); + recoverTree.recoverTree(treeNode); + Util.printTree(treeNode); + } + + /** + * 解题思路: + * 分:几种情况 + * 1、根节点和左子树的某个数字交换 -> 由于根节点大于左子树中的所有数,所以交换后我们只要找左子树中最大的那个数,就是所交换的那个数 + * 2、根节点和右子树的某个数字交换 -> 由于根节点小于右子树中的所有数,所以交换后我们只要在右子树中最小的那个数,就是所交换的那个数 + * 3、左子树和右子树的两个数字交换 -> 找左子树中最大的数,右子树中最小的数,即对应两个交换的数 + * 4、左子树中的两个数字交换 + * 5、右子树中的两个数字交换 + * @param root + */ + public void recoverTree(TreeNode root) { + if (root == null) { + return; + } + //寻找左子树中最大的节点 + TreeNode maxLeft = getMaxOfBST(root.left); + //寻找右子树中最小的节点 + TreeNode minRight = getMinOfBST(root.right); + + if (minRight != null && maxLeft != null) { + //左边的大于根节点,右边的小于根节点,对应情况 3,左右子树中的两个数字交换 + if ( maxLeft.val > root.val && minRight.val < root.val) { + int temp = minRight.val; + minRight.val = maxLeft.val; + maxLeft.val = temp; + } + } + + if (maxLeft != null) { + //左边最大的大于根节点,对应情况 1,根节点和左子树的某个数做了交换 + if (maxLeft.val > root.val) { + int temp = maxLeft.val; + maxLeft.val = root.val; + root.val = temp; + } + } + + if (minRight != null) { + //右边最小的小于根节点,对应情况 2,根节点和右子树的某个数做了交换 + if (minRight.val < root.val) { + int temp = minRight.val; + minRight.val = root.val; + root.val = temp; + } + } + //对应情况 4,左子树中的两个数进行了交换 + recoverTree(root.left); + //对应情况 5,右子树中的两个数进行了交换 + recoverTree(root.right); + + } + //寻找树中最小的节点 + private TreeNode getMinOfBST(TreeNode root) { + if (root == null) { + return null; + } + TreeNode minLeft = getMinOfBST(root.left); + TreeNode minRight = getMinOfBST(root.right); + TreeNode min = root; + if (minLeft != null && min.val > minLeft.val) { + min = minLeft; + } + if (minRight != null && min.val > minRight.val) { + min = minRight; + } + return min; + } + + //寻找树中最大的节点 + private TreeNode getMaxOfBST(TreeNode root) { + if (root == null) { + return null; + } + TreeNode maxLeft = getMaxOfBST(root.left); + TreeNode maxRight = getMaxOfBST(root.right); + TreeNode max = root; + if (maxLeft != null && max.val < maxLeft.val) { + max = maxLeft; + } + if (maxRight != null && max.val < maxRight.val) { + max = maxRight; + } + return max; + } + +} From 91143ae06c6f8395dbd9dd5e028ef301186cb45b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 3 Dec 2019 14:36:42 +0800 Subject: [PATCH 221/308] feat: add _99_recoverTree --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f195313..eae50d0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成235道 +- leetcode练习,坚持每天一道,目前已完成236道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -22,7 +22,7 @@ - [x] [97. 交错字符串](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_97_isInterleave.java) -- [ ] [99. 恢复二叉搜索树](https://leetcode-cn.com/problems/recover-binary-search-tree/) +- [x] [99. 恢复二叉搜索树](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_99_recoverTree.java) - [ ] [100. 相同的树](https://leetcode-cn.com/problems/same-tree/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成235) +### 题目列表(更新中—已完成236) -[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_97_isInterleave.java) +[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_99_recoverTree.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -162,6 +162,7 @@ | #95 | [不同的二叉搜索树 II](https://leetcode-cn.com/problems/unique-binary-search-trees-ii/) | [GenerateTrees](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_95_generateTrees.java) | [树](https://leetcode-cn.com/tag/tree/)、[动态规划]() | Medium | DP实现未想到 | | #97 | [交错字符串](https://leetcode-cn.com/problems/interleaving-string/) | [IsInterleave](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_97_isInterleave.java) | [字符串]()、[动态规划]() | Hard | | | #98 | [验证二叉搜索树](https://leetcode-cn.com/problems/validate-binary-search-tree/) | [IsValidBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_98_isValidBST.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | +| #99 | [恢复二叉搜索树](https://leetcode-cn.com/problems/recover-binary-search-tree/) | [RecoverTree](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_99_recoverTree.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Hard | | | #101 | [对称二叉树](https://leetcode-cn.com/problems/symmetric-tree/) | [IsSymmetric](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_101_isSymmetric.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Easy | | | #102 | [二叉树的层次遍历](https://leetcode-cn.com/problems/binary-tree-level-order-traversal/) | [LevelOrder](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_102_levelOrder.java) | [树](https://leetcode-cn.com/tag/tree/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Medium | | | #103 | [二叉树的锯齿形层次遍历](https://leetcode-cn.com/problems/binary-tree-zigzag-level-order-traversal/) | [ZigzagLevelOrder](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_103_zigzagLevelOrder.java) | [栈](https://leetcode-cn.com/tag/stack/)、[树](https://leetcode-cn.com/tag/tree/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Medium | | From 8785b165847e57413839c2df5d28d8463c49c18e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 4 Dec 2019 10:22:35 +0800 Subject: [PATCH 222/308] feat(EASY): add _100_isSameTree --- .../arithmetic/leetcode/_100_isSameTree.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_100_isSameTree.java diff --git a/src/pp/arithmetic/leetcode/_100_isSameTree.java b/src/pp/arithmetic/leetcode/_100_isSameTree.java new file mode 100644 index 0000000..9e65ab0 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_100_isSameTree.java @@ -0,0 +1,75 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.model.TreeNode; + +/** + * Created by wangpeng on 2019-12-04. + * 100. 相同的树 + * + * 给定两个二叉树,编写一个函数来检验它们是否相同。 + * + * 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。 + * + * 示例 1: + * + * 输入: 1 1 + * / \ / \ + * 2 3 2 3 + * + * [1,2,3], [1,2,3] + * + * 输出: true + * 示例 2: + * + * 输入: 1 1 + * / \ + * 2 2 + * + * [1,2], [1,null,2] + * + * 输出: false + * 示例 3: + * + * 输入: 1 1 + * / \ / \ + * 2 1 1 2 + * + * [1,2,1], [1,1,2] + * + * 输出: false + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/same-tree + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _100_isSameTree { + + public static void main(String[] args) { + _100_isSameTree isSameTree = new _100_isSameTree(); + TreeNode p = new TreeNode(1); + p.left = new TreeNode(2); + p.right = new TreeNode(3); + TreeNode q = new TreeNode(1); + q.left = new TreeNode(2); +// q.right = new TreeNode(3); + + System.out.println(isSameTree.isSameTree(p,q)); + } + + /** + * 解题思路: + * 典型的树的深度遍历(DFS) + * 1、判断左子树是否相同 + * 2、判断右子树是否相同 + * 3、判断父节点是否相同 + * + * @param p + * @param q + * @return + */ + public boolean isSameTree(TreeNode p, TreeNode q) { + if (p== null && q == null) return true; + if (p == null || q == null) return false; + return isSameTree(p.left,q.left) && isSameTree(p.right,q.right) && p.val == q.val; + } +} From 555fa0fd01d5ce198c43d5e94fc286b82b9d5df6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 4 Dec 2019 10:26:07 +0800 Subject: [PATCH 223/308] docs: add _100_isSameTree --- README.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index eae50d0..816e31a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成236道 +- leetcode练习,坚持每天一道,目前已完成237道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -14,17 +14,19 @@ - [x] [83. 删除排序链表中的重复元素](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_83_deleteDuplicates.java) -- [x] [87. 扰乱字符串](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_87_isScramble.java) +- [x] [87. 扰乱字符串](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_87_isScramble.java) -- [x] [88. 合并两个有序数组](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_88_merge.java) +- [x] [88. 合并两个有序数组](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_88_merge.java) -- [x] [89. 格雷编码](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_89_grayCode.java) +- [x] [89. 格雷编码](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_89_grayCode.java) -- [x] [97. 交错字符串](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_97_isInterleave.java) +- [ ] [96. 不同的二叉搜索树](https://leetcode-cn.com/problems/unique-binary-search-trees/) -- [x] [99. 恢复二叉搜索树](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_99_recoverTree.java) +- [x] [97. 交错字符串](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_97_isInterleave.java) -- [ ] [100. 相同的树](https://leetcode-cn.com/problems/same-tree/) +- [x] [99. 恢复二叉搜索树](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_99_recoverTree.java) + +- [x] [100. 相同的树](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_100_isSameTree.java) ## 已解题目 @@ -59,9 +61,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成236) +### 题目列表(更新中—已完成237) -[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_99_recoverTree.java) +[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_100_isSameTree.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -163,6 +165,7 @@ | #97 | [交错字符串](https://leetcode-cn.com/problems/interleaving-string/) | [IsInterleave](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_97_isInterleave.java) | [字符串]()、[动态规划]() | Hard | | | #98 | [验证二叉搜索树](https://leetcode-cn.com/problems/validate-binary-search-tree/) | [IsValidBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_98_isValidBST.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #99 | [恢复二叉搜索树](https://leetcode-cn.com/problems/recover-binary-search-tree/) | [RecoverTree](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_99_recoverTree.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Hard | | +| #100 | [相同的树](https://leetcode-cn.com/problems/same-tree/) | [IsSameTree](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_100_isSameTree.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | | #101 | [对称二叉树](https://leetcode-cn.com/problems/symmetric-tree/) | [IsSymmetric](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_101_isSymmetric.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Easy | | | #102 | [二叉树的层次遍历](https://leetcode-cn.com/problems/binary-tree-level-order-traversal/) | [LevelOrder](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_102_levelOrder.java) | [树](https://leetcode-cn.com/tag/tree/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Medium | | | #103 | [二叉树的锯齿形层次遍历](https://leetcode-cn.com/problems/binary-tree-zigzag-level-order-traversal/) | [ZigzagLevelOrder](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_103_zigzagLevelOrder.java) | [栈](https://leetcode-cn.com/tag/stack/)、[树](https://leetcode-cn.com/tag/tree/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Medium | | From da801259ad695b8c2104a6ae3cb9141b5e6694a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 5 Dec 2019 10:58:43 +0800 Subject: [PATCH 224/308] feat(MEDIUM): add _96_numTrees --- src/pp/arithmetic/leetcode/_96_numTrees.java | 97 ++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_96_numTrees.java diff --git a/src/pp/arithmetic/leetcode/_96_numTrees.java b/src/pp/arithmetic/leetcode/_96_numTrees.java new file mode 100644 index 0000000..934d2f7 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_96_numTrees.java @@ -0,0 +1,97 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-12-04. + * + * 给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种? + * + * 示例: + * + * 输入: 3 + * 输出: 5 + * 解释: + * 给定 n = 3, 一共有 5 种不同结构的二叉搜索树: + * + * 1 3 3 2 1 + * \ / / / \ \ + * 3 2 1 1 3 2 + * / / \ \ + * 2 1 2 3 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/unique-binary-search-trees + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _96_numTrees { + + public static void main(String[] args) { + _96_numTrees numTrees = new _96_numTrees(); + System.out.println(numTrees.numTrees(1)); + System.out.println(numTrees.numTrees(2)); + System.out.println(numTrees.numTrees(3)); + System.out.println(numTrees.numTrees(4)); + System.out.println(numTrees.numTrees(5)); + } + + /** + * 解法一:{@link _96_numTrees#dfs(int, int)},直接利用DFS进行求解,待优化 + * 解法二:{@link _96_numTrees#dp(int)},将二叉树编译转换为动态规范转换 + * + * @param n + * @return + */ + public int numTrees(int n) { + return dp(n); + } + + /** + * 解题思路(动态规划) + * 1、将大问题转换为小问题:第i位的个数,再求和 + * 2、第i位的个数 += dp[j](左) * dp[i - j - 1](右) (j=0,j= ei) return 1; + int sum = 0; + for (int i = si; i <= ei; i++) { + int leftCount = dfs(si, i - 1); + int rightCount = dfs(i + 1, ei); + sum += (leftCount * rightCount); + } + return sum; + } +} From 0b2661c6fc6960813944a3cd91c74c16b717c3b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Sat, 7 Dec 2019 18:05:19 +0800 Subject: [PATCH 225/308] docs: add _96_numTrees --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 816e31a..f873046 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成237道 +- leetcode练习,坚持每天一道,目前已完成238道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -20,7 +20,7 @@ - [x] [89. 格雷编码](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_89_grayCode.java) -- [ ] [96. 不同的二叉搜索树](https://leetcode-cn.com/problems/unique-binary-search-trees/) +- [x] [96. 不同的二叉搜索树](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_96_numTrees.java) - [x] [97. 交错字符串](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_97_isInterleave.java) @@ -61,9 +61,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成237) +### 题目列表(更新中—已完成238) -[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_100_isSameTree.java) +[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_96_numTrees.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -162,6 +162,7 @@ | #93 | [复原IP地址](https://leetcode-cn.com/problems/restore-ip-addresses/) | [RestoreIpAddresses](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_93_restoreIpAddresses.java) | [字符串]()、[回溯算法]() | Medium | | | #94 | [二叉树的中序遍历](https://leetcode-cn.com/problems/binary-tree-inorder-traversal/) | [InorderTraversal](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_94_inorderTraversal.java) | [栈](https://leetcode-cn.com/tag/stack/)、[树](https://leetcode-cn.com/tag/tree/)、[哈希表]() | Medium | | | #95 | [不同的二叉搜索树 II](https://leetcode-cn.com/problems/unique-binary-search-trees-ii/) | [GenerateTrees](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_95_generateTrees.java) | [树](https://leetcode-cn.com/tag/tree/)、[动态规划]() | Medium | DP实现未想到 | +| #96 | [不同的二叉搜索树](https://leetcode-cn.com/problems/unique-binary-search-trees/) | [NumTrees](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_96_numTrees.java) | [树](https://leetcode-cn.com/tag/tree/)、[动态规划]() | Medium | | | #97 | [交错字符串](https://leetcode-cn.com/problems/interleaving-string/) | [IsInterleave](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_97_isInterleave.java) | [字符串]()、[动态规划]() | Hard | | | #98 | [验证二叉搜索树](https://leetcode-cn.com/problems/validate-binary-search-tree/) | [IsValidBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_98_isValidBST.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #99 | [恢复二叉搜索树](https://leetcode-cn.com/problems/recover-binary-search-tree/) | [RecoverTree](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_99_recoverTree.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Hard | | From aad3745cbac1c06a791271077d729408b68a9dbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 9 Dec 2019 10:00:00 +0800 Subject: [PATCH 226/308] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E9=A2=98?= =?UTF-8?q?=E7=9B=AE=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index f873046..4fde0b7 100644 --- a/README.md +++ b/README.md @@ -12,21 +12,19 @@ 扫题:顺序 -- [x] [83. 删除排序链表中的重复元素](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_83_deleteDuplicates.java) +- [ ] [106. 从中序与后序遍历序列构造二叉树 -Medium](https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/) -- [x] [87. 扰乱字符串](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_87_isScramble.java) +- [ ] [107. 二叉树的层次遍历 II --Easy](https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/) -- [x] [88. 合并两个有序数组](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_88_merge.java) +- [ ] [109. 有序链表转换二叉搜索树 --Medium](https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree/) -- [x] [89. 格雷编码](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_89_grayCode.java) +- [ ] [112. 路径总和 --Easy](https://leetcode-cn.com/problems/path-sum/) -- [x] [96. 不同的二叉搜索树](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_96_numTrees.java) +- [ ] [115. 不同的子序列 --Hard](https://leetcode-cn.com/problems/distinct-subsequences/) -- [x] [97. 交错字符串](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_97_isInterleave.java) +- [ ] [116. 填充每个节点的下一个右侧节点指针 --Medium](https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/) -- [x] [99. 恢复二叉搜索树](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_99_recoverTree.java) - -- [x] [100. 相同的树](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_100_isSameTree.java) +- [ ] [117. 填充每个节点的下一个右侧节点指针 II --Medium](https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii/) ## 已解题目 From 81d62fdab7f9c0e714cd193826dc4d5ed71adf65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 9 Dec 2019 10:47:42 +0800 Subject: [PATCH 227/308] feat(MEDIUM): add _106_buildTree --- .../arithmetic/leetcode/_106_buildTree.java | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_106_buildTree.java diff --git a/src/pp/arithmetic/leetcode/_106_buildTree.java b/src/pp/arithmetic/leetcode/_106_buildTree.java new file mode 100644 index 0000000..069bdc8 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_106_buildTree.java @@ -0,0 +1,69 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; +import pp.arithmetic.model.TreeNode; + +import java.util.Arrays; + +/** + * Created by wangpeng on 2019-12-09. + * 106. 从中序与后序遍历序列构造二叉树 + * + * 根据一棵树的中序遍历与后序遍历构造二叉树。 + * + * 注意: + * 你可以假设树中没有重复的元素。 + * + * 例如,给出 + * + * 中序遍历 inorder = [9,3,15,20,7] + * 后序遍历 postorder = [9,15,7,20,3] + * 返回如下的二叉树: + * + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _106_buildTree { + + public static void main(String[] args) { + _106_buildTree buildTree = new _106_buildTree(); + TreeNode treeNode = buildTree.buildTree(new int[]{9, 3, 15, 20, 7}, new int[]{9, 15, 7, 20, 3}); + Util.printTree(treeNode); + } + + /** + * 解题思路: + * 中序:左->中->右,后序:左->右->中 + * 1、取后序的最后一位就是根节点 + * 2、遍历中序,找到根节点在中序中的位置I,I左边的就是左子树,右边就是右子树 + * 3、分别取中序和后续的0-I位置,得到的就是左子树的中序和后续遍历接通,重复步骤1、2将左子树构造出来 + * 4、同理步骤3,将右子树构造出来 + * + * @param inorder + * @param postorder + * @return + */ + public TreeNode buildTree(int[] inorder, int[] postorder) { + if (inorder.length == 0) return null; + int rootVal = postorder[postorder.length - 1]; + TreeNode rootNode = new TreeNode(rootVal); + int rootIndex = 0; + for (int i = 0; i < inorder.length; i++) { + if (inorder[i] == rootVal){ + rootIndex = i; + break; + } + } + rootNode.left = buildTree(Arrays.copyOfRange(inorder, 0, rootIndex), Arrays.copyOfRange(postorder, 0, rootIndex)); + rootNode.right = buildTree(Arrays.copyOfRange(inorder, rootIndex + 1, inorder.length), Arrays.copyOfRange(postorder, rootIndex, postorder.length - 1)); + return rootNode; + } + +} From 8ff61e88ff485dfc3659428a29e64a40d1bf19d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 9 Dec 2019 10:50:27 +0800 Subject: [PATCH 228/308] docs: add _106_buildTree --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4fde0b7..6f8fda8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成238道 +- leetcode练习,坚持每天一道,目前已完成239道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -12,7 +12,7 @@ 扫题:顺序 -- [ ] [106. 从中序与后序遍历序列构造二叉树 -Medium](https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/) +- [x] [106. 从中序与后序遍历序列构造二叉树 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_106_buildTree.java) - [ ] [107. 二叉树的层次遍历 II --Easy](https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成238) +### 题目列表(更新中—已完成239) -[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_96_numTrees.java) +[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_106_buildTree.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -170,6 +170,7 @@ | #103 | [二叉树的锯齿形层次遍历](https://leetcode-cn.com/problems/binary-tree-zigzag-level-order-traversal/) | [ZigzagLevelOrder](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_103_zigzagLevelOrder.java) | [栈](https://leetcode-cn.com/tag/stack/)、[树](https://leetcode-cn.com/tag/tree/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Medium | | | #104 | [二叉树的最大深度](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/) | [MaxDepth](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_104_maxDepth.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | | #105 | [从前序与中序遍历序列构造二叉树](https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) | [BuildTree](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_105_buildTree.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/)、[数组]() | Medium | | +| #106 | [从中序与后序遍历序列构造二叉树](https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/) | [BuildTree](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_106_buildTree.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/)、[数组]() | Medium | | | #108 | [将有序数组转换为二叉搜索树](https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/) | [SortedArrayToBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_108_sortedArrayToBST.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | | #113 | [路径总和 II](https://leetcode-cn.com/problems/path-sum-ii/) | [PathSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_113_pathSum.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #114 | [二叉树展开为链表](https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/) | [Flatten](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_114_flatten.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | From f06fab2971678ac74266015e663606839f586190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 9 Dec 2019 10:52:23 +0800 Subject: [PATCH 229/308] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E5=BB=BA=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pp/arithmetic/leetcode/_106_buildTree.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pp/arithmetic/leetcode/_106_buildTree.java b/src/pp/arithmetic/leetcode/_106_buildTree.java index 069bdc8..5a3d6dc 100644 --- a/src/pp/arithmetic/leetcode/_106_buildTree.java +++ b/src/pp/arithmetic/leetcode/_106_buildTree.java @@ -46,6 +46,11 @@ public static void main(String[] args) { * 3、分别取中序和后续的0-I位置,得到的就是左子树的中序和后续遍历接通,重复步骤1、2将左子树构造出来 * 4、同理步骤3,将右子树构造出来 * + * 执行用时 :19 ms, 在所有 java 提交中击败了29.64%的用户 + * 内存消耗 :77.3 MB, 在所有 java 提交中击败了5.17%的用户 + * + * 用时耗时优化建议:Arrays.copy可以转换为数组的index下标遍历 + * * @param inorder * @param postorder * @return From ded30987f3b49d9d4b721ed9458c73c589e45274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 10 Dec 2019 17:40:14 +0800 Subject: [PATCH 230/308] feat(EASY): add _107_levelOrderBottom --- .../leetcode/_107_levelOrderBottom.java | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_107_levelOrderBottom.java diff --git a/src/pp/arithmetic/leetcode/_107_levelOrderBottom.java b/src/pp/arithmetic/leetcode/_107_levelOrderBottom.java new file mode 100644 index 0000000..5f080b4 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_107_levelOrderBottom.java @@ -0,0 +1,84 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; +import pp.arithmetic.model.TreeNode; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; + +/** + * Created by wangpeng on 2019-12-10. + * 107. 二叉树的层次遍历 II + * + * 给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历) + * + * 例如: + * 给定二叉树 [3,9,20,null,null,15,7], + * + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * 返回其自底向上的层次遍历为: + * + * [ + * [15,7], + * [9,20], + * [3] + * ] + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _107_levelOrderBottom { + + public static void main(String[] args) { + _107_levelOrderBottom levelOrderBottom = new _107_levelOrderBottom(); + TreeNode node = new TreeNode(3); + node.left = new TreeNode(9); + node.right = new TreeNode(20); + node.right.left = new TreeNode(15); + node.right.right = new TreeNode(7); + List> lists = levelOrderBottom.levelOrderBottom(node); + for (int i = 0; i < lists.size(); i++) { + Util.printList(lists.get(i)); + } + } + + /** + * 解题思路: + * 树的问题就是遍历,本题用树的广度遍历(BFS) + * BFS遍历依赖队列保存一层的节点 + * + * @param root + * @return + */ + public List> levelOrderBottom(TreeNode root) { + List> retList = new ArrayList<>(); + if (root == null) return retList; + Queue queue = new ArrayDeque<>(); + queue.add(root); + while (queue.peek() != null) { + List items = new ArrayList<>(); + List treeList = new ArrayList<>(); + TreeNode poll = queue.poll(); + while (poll != null) { + items.add(poll.val); + if (poll.left != null) treeList.add(poll.left); + if (poll.right != null) treeList.add(poll.right); + poll = queue.poll(); + } + if (!treeList.isEmpty()) { + queue.addAll(treeList); + } + if (!items.isEmpty()) { + retList.add(0, items); + } + } + return retList; + } +} From 2edf5fe6f845c3196db3e5578dbf8cb0d8b9cc9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 10 Dec 2019 17:43:00 +0800 Subject: [PATCH 231/308] docs: add _107_levelOrderBottom --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6f8fda8..7dd3f2c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成239道 +- leetcode练习,坚持每天一道,目前已完成240道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -14,7 +14,7 @@ - [x] [106. 从中序与后序遍历序列构造二叉树 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_106_buildTree.java) -- [ ] [107. 二叉树的层次遍历 II --Easy](https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/) +- [x] [107. 二叉树的层次遍历 II --Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_107_levelOrderBottom.java) - [ ] [109. 有序链表转换二叉搜索树 --Medium](https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成239) +### 题目列表(更新中—已完成240) -[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_106_buildTree.java) +[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_107_levelOrderBottom.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -171,6 +171,7 @@ | #104 | [二叉树的最大深度](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/) | [MaxDepth](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_104_maxDepth.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | | #105 | [从前序与中序遍历序列构造二叉树](https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) | [BuildTree](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_105_buildTree.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/)、[数组]() | Medium | | | #106 | [从中序与后序遍历序列构造二叉树](https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/) | [BuildTree](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_106_buildTree.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/)、[数组]() | Medium | | +| #107 | [二叉树的层次遍历 II](https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/) | [LevelOrderBottom](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_107_levelOrderBottom.java) | [树](https://leetcode-cn.com/tag/tree/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Easy | | | #108 | [将有序数组转换为二叉搜索树](https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/) | [SortedArrayToBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_108_sortedArrayToBST.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | | #113 | [路径总和 II](https://leetcode-cn.com/problems/path-sum-ii/) | [PathSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_113_pathSum.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #114 | [二叉树展开为链表](https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/) | [Flatten](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_114_flatten.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | From 1cd7dac0cfceff8043ffcbf213f09c8df472550f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 11 Dec 2019 11:15:26 +0800 Subject: [PATCH 232/308] feat(MEDIUM): add _109_sortedListToBST --- .../leetcode/_109_sortedListToBST.java | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_109_sortedListToBST.java diff --git a/src/pp/arithmetic/leetcode/_109_sortedListToBST.java b/src/pp/arithmetic/leetcode/_109_sortedListToBST.java new file mode 100644 index 0000000..5d8b5a2 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_109_sortedListToBST.java @@ -0,0 +1,89 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; +import pp.arithmetic.model.ListNode; +import pp.arithmetic.model.TreeNode; + +/** + * Created by wangpeng on 2019-12-11. + * 109. 有序链表转换二叉搜索树 + * + * 给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。 + * + * 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。 + * + * 示例: + * + * 给定的有序链表: [-10, -3, 0, 5, 9], + * + * 一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树: + * + * 0 + * / \ + * -3 9 + * / / + * -10 5 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _109_sortedListToBST { + + public static void main(String[] args) { + _109_sortedListToBST sortedListToBST = new _109_sortedListToBST(); + ListNode listNode = new ListNode(-10); + listNode.next = new ListNode(-3); + listNode.next.next = new ListNode(0); + listNode.next.next.next = new ListNode(5); + listNode.next.next.next.next = new ListNode(9); + TreeNode treeNode = sortedListToBST.sortedListToBST(listNode); + Util.printTree(treeNode); + } + + /** + * 解题思路: + * 去有序链表的中间位置作为根节点,将左部生成左子树,右部生成右子树 + * 难点: + * 1、如何找到链表的中间位置 ==> 两次遍历,第一次使用length记录总长度,第二次取length/2的位置为更觉得 + * 2、如何将一个链表分割成左右两部分独立链表 ==> 变量rightPreNode保存遍历过程中的前置节点,为断链做准备 + * + * 链表的解法多数是遍历,利用额外的节点保存中间状态 + * 树的解法多数是递归,同样的入参生成左右子树 + * + * 执行用时 :2 ms, 在所有 java 提交中击败了48.48%的用户 + * 内存消耗 :38.7 MB , 在所有 java 提交中击败了97.64%的用户 + * + * @param head + * @return + */ + public TreeNode sortedListToBST(ListNode head) { + if (head == null) return null; + ListNode next = head; + int length = 0; + while (next!=null){ + length++; + next = next.next; + } + if (length==1){ + return new TreeNode(head.val); + } + ListNode leftNode = head; + ListNode rightNode = head; + ListNode rightPreNode = head; + for (int i = 0; i < length / 2; i++) { + rightPreNode = rightNode; + rightNode = rightPreNode.next; + } + //生成根节点 + TreeNode root = new TreeNode(rightNode.val); + //断开左侧 + rightPreNode.next = null; + //断开右侧 + rightNode = rightNode.next; + //生成左右子树 + root.left = sortedListToBST(leftNode); + root.right = sortedListToBST(rightNode); + return root; + } +} From b5740ef72ac8988eccf3fa8f60dcfd2581659e1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 11 Dec 2019 11:22:21 +0800 Subject: [PATCH 233/308] docs: add _109_sortedListToBST --- README.md | 9 +++++---- src/pp/arithmetic/leetcode/_109_sortedListToBST.java | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7dd3f2c..f1a49ce 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成240道 +- leetcode练习,坚持每天一道,目前已完成241道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -16,7 +16,7 @@ - [x] [107. 二叉树的层次遍历 II --Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_107_levelOrderBottom.java) -- [ ] [109. 有序链表转换二叉搜索树 --Medium](https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree/) +- [x] [109. 有序链表转换二叉搜索树 --Medium]([_109_sortedListToBST.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_109_sortedListToBST.java)) - [ ] [112. 路径总和 --Easy](https://leetcode-cn.com/problems/path-sum/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成240) +### 题目列表(更新中—已完成241) -[Leetcode-Java(200+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_107_levelOrderBottom.java) +[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)]([_109_sortedListToBST.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_109_sortedListToBST.java)) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -173,6 +173,7 @@ | #106 | [从中序与后序遍历序列构造二叉树](https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/) | [BuildTree](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_106_buildTree.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/)、[数组]() | Medium | | | #107 | [二叉树的层次遍历 II](https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/) | [LevelOrderBottom](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_107_levelOrderBottom.java) | [树](https://leetcode-cn.com/tag/tree/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Easy | | | #108 | [将有序数组转换为二叉搜索树](https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/) | [SortedArrayToBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_108_sortedArrayToBST.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | +| #109 | [有序链表转换二叉搜索树](https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree/) | [SortedListToBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_109_sortedListToBST.java) | [DFS](https://leetcode-cn.com/tag/depth-first-search/)、[链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | | #113 | [路径总和 II](https://leetcode-cn.com/problems/path-sum-ii/) | [PathSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_113_pathSum.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #114 | [二叉树展开为链表](https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/) | [Flatten](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_114_flatten.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #120 | [三角形最小路径和](https://leetcode-cn.com/problems/triangle/) | [MinimumTotal](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_120_minimumTotal.java) | [数组]()、[动态规划]() | Medium | | diff --git a/src/pp/arithmetic/leetcode/_109_sortedListToBST.java b/src/pp/arithmetic/leetcode/_109_sortedListToBST.java index 5d8b5a2..73355f2 100644 --- a/src/pp/arithmetic/leetcode/_109_sortedListToBST.java +++ b/src/pp/arithmetic/leetcode/_109_sortedListToBST.java @@ -48,6 +48,8 @@ public static void main(String[] args) { * 1、如何找到链表的中间位置 ==> 两次遍历,第一次使用length记录总长度,第二次取length/2的位置为更觉得 * 2、如何将一个链表分割成左右两部分独立链表 ==> 变量rightPreNode保存遍历过程中的前置节点,为断链做准备 * + * 对于难点一:也可以用快慢指针定位中间位置 + * * 链表的解法多数是遍历,利用额外的节点保存中间状态 * 树的解法多数是递归,同样的入参生成左右子树 * From 17026d60a2e3876b90437580b6051fcef2c7bcc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 12 Dec 2019 11:20:05 +0800 Subject: [PATCH 234/308] feat(EASY): add _110_isBalanced --- README.md | 4 + src/pp/arithmetic/Util.java | 31 ++++++++ .../arithmetic/leetcode/_110_isBalanced.java | 73 +++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_110_isBalanced.java diff --git a/README.md b/README.md index f1a49ce..56f3561 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,10 @@ - [x] [109. 有序链表转换二叉搜索树 --Medium]([_109_sortedListToBST.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_109_sortedListToBST.java)) +- [ ] [110. 平衡二叉树](https://leetcode-cn.com/problems/balanced-binary-tree/) + +- [ ] [111. 二叉树的最小深度](https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/) + - [ ] [112. 路径总和 --Easy](https://leetcode-cn.com/problems/path-sum/) - [ ] [115. 不同的子序列 --Hard](https://leetcode-cn.com/problems/distinct-subsequences/) diff --git a/src/pp/arithmetic/Util.java b/src/pp/arithmetic/Util.java index 4db874e..c377a67 100644 --- a/src/pp/arithmetic/Util.java +++ b/src/pp/arithmetic/Util.java @@ -4,7 +4,9 @@ import pp.arithmetic.model.ListNode; import pp.arithmetic.model.TreeNode; +import java.util.ArrayDeque; import java.util.List; +import java.util.Queue; import java.util.Random; /** @@ -102,6 +104,35 @@ public static TreeNode generateTreeNode() { return root; } + public static TreeNode generateTreeNode(Integer[] nodes) { + if (nodes == null || nodes.length == 0 || nodes[0] == null) return null; + TreeNode root = new TreeNode(nodes[0]); + Queue stack = new ArrayDeque<>(); + stack.add(root); + int length = 1; + while (length < nodes.length) { + TreeNode poll = stack.poll(); + if (poll == null) break; + Integer node = nodes[length]; + if (node!=null) { + TreeNode left = new TreeNode(node); + poll.left = left; + stack.add(left); + } + length++; + if (length < nodes.length) { + node=nodes[length]; + if (node!=null) { + TreeNode right = new TreeNode(node); + poll.right = right; + stack.add(right); + } + length++; + } + } + return root; + } + public static void printArray(int[] nums) { for (int i = 0; i < nums.length; i++) { System.out.print(nums[i] + " "); diff --git a/src/pp/arithmetic/leetcode/_110_isBalanced.java b/src/pp/arithmetic/leetcode/_110_isBalanced.java new file mode 100644 index 0000000..ba22318 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_110_isBalanced.java @@ -0,0 +1,73 @@ +package pp.arithmetic.leetcode; + +import javafx.util.Pair; +import pp.arithmetic.Util; +import pp.arithmetic.model.TreeNode; + +/** + * Created by wangpeng on 2019-12-12. + * 110. 平衡二叉树 + * + * 给定一个二叉树,判断它是否是高度平衡的二叉树。 + * + * 本题中,一棵高度平衡二叉树定义为: + * + * 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 + * + * 示例 1: + * + * 给定二叉树 [3,9,20,null,null,15,7] + * + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * 返回 true 。 + * + * 示例 2: + * + * 给定二叉树 [1,2,2,3,3,null,null,4,4] + * + * 1 + * / \ + * 2 2 + * / \ + * 3 3 + * / \ + * 4 4 + * 返回 false 。 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/balanced-binary-tree + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _110_isBalanced { + + public static void main(String[] args) { + _110_isBalanced isBalanced = new _110_isBalanced(); + TreeNode treeNode = Util.generateTreeNode(new Integer[]{3, 9, 20, null, null, 15, 7}); + System.out.println(isBalanced.isBalanced(treeNode)); + TreeNode treeNode2 = Util.generateTreeNode(new Integer[]{1,2,2,3,3,null,null,4,4}); + System.out.println(isBalanced.isBalanced(treeNode2)); + } + + /** + * 解题思路: + * 1、递归计算左右子树的高度 + * 2、取左右子树的最大高度+1,即是该根节点的高度 + * 3、由于每个节点都需要满足高度平衡二叉树的条件,所以递归返回一个Pair + * @param root + * @return + */ + public boolean isBalanced(TreeNode root) { + return dfs(root).getKey(); + } + + private Pair dfs(TreeNode root) { + if (root == null) return new Pair<>(true, 0); + Pair left = dfs(root.left); + Pair right = dfs(root.right); + return new Pair<>(left.getKey() && right.getKey() && (Math.abs(left.getValue() - right.getValue()) <= 1), Math.max(left.getValue(), right.getValue()) + 1); + } +} From ebda09862aaf61427e40ebe57508f818cc985ece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 12 Dec 2019 11:36:37 +0800 Subject: [PATCH 235/308] feat(EASY): add _111_minDepth --- README.md | 4 +- src/pp/arithmetic/leetcode/_111_minDepth.java | 55 +++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 src/pp/arithmetic/leetcode/_111_minDepth.java diff --git a/README.md b/README.md index 56f3561..75b55cc 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ - [x] [109. 有序链表转换二叉搜索树 --Medium]([_109_sortedListToBST.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_109_sortedListToBST.java)) -- [ ] [110. 平衡二叉树](https://leetcode-cn.com/problems/balanced-binary-tree/) +- [x] [110. 平衡二叉树 --Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_110_isBalanced.java) - [ ] [111. 二叉树的最小深度](https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/) @@ -65,7 +65,7 @@ ### 题目列表(更新中—已完成241) -[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)]([_109_sortedListToBST.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_109_sortedListToBST.java)) +[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_110_isBalanced.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | diff --git a/src/pp/arithmetic/leetcode/_111_minDepth.java b/src/pp/arithmetic/leetcode/_111_minDepth.java new file mode 100644 index 0000000..b294a1e --- /dev/null +++ b/src/pp/arithmetic/leetcode/_111_minDepth.java @@ -0,0 +1,55 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; +import pp.arithmetic.model.TreeNode; + +/** + * Created by wangpeng on 2019-12-12. + * 111. 二叉树的最小深度 + * + * 给定一个二叉树,找出其最小深度。 + * + * 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 + * + * 说明: 叶子节点是指没有子节点的节点。 + * + * 示例: + * + * 给定二叉树 [3,9,20,null,null,15,7], + * + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * 返回它的最小深度  2. + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/minimum-depth-of-binary-tree + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _111_minDepth { + + public static void main(String[] args) { + _111_minDepth minDepth = new _111_minDepth(); + System.out.println(minDepth.minDepth(Util.generateTreeNode(new Integer[]{3, 9, 20, null, null, 15, 7}))); + } + + /** + * 解题思路:DFS求解 + * 1、求左子树的最小深度 + * 2、求右子树的最小深度 + * 3、求根节点的最小深度 = Math.min(left,right)+1 + * + * 需要注意一点:如左/右子树为空,得取有值得叶节点长度 + * + * @param root + * @return + */ + public int minDepth(TreeNode root) { + if (root == null) return 0; + int left = minDepth(root.left); + int right = minDepth(root.right); + return (left == 0 || right == 0) ? left + right + 1 : Math.min(left, right) + 1; + } +} From b15bb3400cca40d84d73d35baef9c80718a7d395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 12 Dec 2019 11:39:44 +0800 Subject: [PATCH 236/308] docs: add 110&111 --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 75b55cc..699b256 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ - [x] [110. 平衡二叉树 --Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_110_isBalanced.java) -- [ ] [111. 二叉树的最小深度](https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/) +- [x] [111. 二叉树的最小深度](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_111_minDepth.java) - [ ] [112. 路径总和 --Easy](https://leetcode-cn.com/problems/path-sum/) @@ -65,7 +65,7 @@ ### 题目列表(更新中—已完成241) -[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_110_isBalanced.java) +[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_111_minDepth.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -178,6 +178,8 @@ | #107 | [二叉树的层次遍历 II](https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/) | [LevelOrderBottom](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_107_levelOrderBottom.java) | [树](https://leetcode-cn.com/tag/tree/)、[BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Easy | | | #108 | [将有序数组转换为二叉搜索树](https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/) | [SortedArrayToBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_108_sortedArrayToBST.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | | #109 | [有序链表转换二叉搜索树](https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree/) | [SortedListToBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_109_sortedListToBST.java) | [DFS](https://leetcode-cn.com/tag/depth-first-search/)、[链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | +| #110 | [平衡二叉树](https://leetcode-cn.com/problems/balanced-binary-tree/) | [IsBalanced](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_110_isBalanced.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | +| #111 | [二叉树的最小深度](https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/) | [MinDepth](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_111_minDepth.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | | #113 | [路径总和 II](https://leetcode-cn.com/problems/path-sum-ii/) | [PathSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_113_pathSum.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #114 | [二叉树展开为链表](https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/) | [Flatten](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_114_flatten.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #120 | [三角形最小路径和](https://leetcode-cn.com/problems/triangle/) | [MinimumTotal](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_120_minimumTotal.java) | [数组]()、[动态规划]() | Medium | | From df0da65701ccd734bbf935d90ad5090181455d3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 12 Dec 2019 12:04:09 +0800 Subject: [PATCH 237/308] feat(EASY): add _112_hasPathSum --- .../arithmetic/leetcode/_112_hasPathSum.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_112_hasPathSum.java diff --git a/src/pp/arithmetic/leetcode/_112_hasPathSum.java b/src/pp/arithmetic/leetcode/_112_hasPathSum.java new file mode 100644 index 0000000..cc37d2e --- /dev/null +++ b/src/pp/arithmetic/leetcode/_112_hasPathSum.java @@ -0,0 +1,67 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; +import pp.arithmetic.model.TreeNode; + +/** + * Created by wangpeng on 2019-12-12. + * 112. 路径总和 + * + * 给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。 + * + * 说明: 叶子节点是指没有子节点的节点。 + * + * 示例:  + * 给定如下二叉树,以及目标和 sum = 22, + * + * 5 + * / \ + * 4 8 + * / / \ + * 11 13 4 + * / \ \ + * 7 2 1 + * 返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/path-sum + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _112_hasPathSum { + + public static void main(String[] args) { + _112_hasPathSum hasPathSum = new _112_hasPathSum(); + TreeNode treeNode = Util.generateTreeNode(new Integer[]{5, 4, 7, 11, null, 13, 4, 7, 2, null, null, null, 1}); + System.out.println(hasPathSum.hasPathSum(treeNode,22)); + System.out.println(hasPathSum.hasPathSum(Util.generateTreeNode(new Integer[]{1,2}),1)); + } + + /** + * 解题思路: + * 1、sum减去当前根节点的val,将新的sum传递给左右子树 + * 2、左右子树重复步骤1 + * 3、如最终的节点==null并且sum==0则找到目标路径 + * + * 注意:叶节点的定义 + * + * @param root + * @param sum + * @return + */ + public boolean hasPathSum(TreeNode root, int sum) { + if (root == null) return false; + return dfs(root, sum); + } + + private boolean dfs(TreeNode root, int sum) { + if (root == null) return sum == 0; + int newSum = sum - root.val; + if (root.left == null && root.right == null) return newSum == 0; + boolean left = dfs(root.left, newSum); + boolean right = dfs(root.right, newSum); + if (root.left != null && root.right != null) return left || right; + if (root.left != null) return left; + if (root.right != null) return right; + return false; + } +} From 2ab67438c70e1779b5eb649caa8907da576d181c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 12 Dec 2019 12:09:02 +0800 Subject: [PATCH 238/308] docs: add _112_hasPathSum --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 699b256..22515d7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成241道 +- leetcode练习,坚持每天一道,目前已完成242道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -20,9 +20,9 @@ - [x] [110. 平衡二叉树 --Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_110_isBalanced.java) -- [x] [111. 二叉树的最小深度](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_111_minDepth.java) +- [x] [111. 二叉树的最小深度 --Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_111_minDepth.java) -- [ ] [112. 路径总和 --Easy](https://leetcode-cn.com/problems/path-sum/) +- [x] [112. 路径总和 --Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_112_hasPathSum.java) - [ ] [115. 不同的子序列 --Hard](https://leetcode-cn.com/problems/distinct-subsequences/) @@ -63,9 +63,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成241) +### 题目列表(更新中—已完成242) -[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_111_minDepth.java) +[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_112_hasPathSum.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -180,6 +180,7 @@ | #109 | [有序链表转换二叉搜索树](https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree/) | [SortedListToBST](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_109_sortedListToBST.java) | [DFS](https://leetcode-cn.com/tag/depth-first-search/)、[链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | | #110 | [平衡二叉树](https://leetcode-cn.com/problems/balanced-binary-tree/) | [IsBalanced](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_110_isBalanced.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | | #111 | [二叉树的最小深度](https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/) | [MinDepth](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_111_minDepth.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | +| #112 | [路径总和](https://leetcode-cn.com/problems/path-sum/) | [HasPathSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_112_hasPathSum.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | | #113 | [路径总和 II](https://leetcode-cn.com/problems/path-sum-ii/) | [PathSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_113_pathSum.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #114 | [二叉树展开为链表](https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/) | [Flatten](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_114_flatten.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #120 | [三角形最小路径和](https://leetcode-cn.com/problems/triangle/) | [MinimumTotal](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_120_minimumTotal.java) | [数组]()、[动态规划]() | Medium | | From a423cd248874e1e7801f6bec86abc126c55cbf1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Sat, 14 Dec 2019 11:16:21 +0800 Subject: [PATCH 239/308] feat(HARD): add _115_numDistinct --- .../arithmetic/leetcode/_115_numDistinct.java | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_115_numDistinct.java diff --git a/src/pp/arithmetic/leetcode/_115_numDistinct.java b/src/pp/arithmetic/leetcode/_115_numDistinct.java new file mode 100644 index 0000000..d5af50a --- /dev/null +++ b/src/pp/arithmetic/leetcode/_115_numDistinct.java @@ -0,0 +1,139 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +/** + * Created by wangpeng on 2019-12-13. + * 115. 不同的子序列 + * + * 给定一个字符串 S 和一个字符串 T,计算在 S 的子序列中 T 出现的个数。 + * + * 一个字符串的一个子序列是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。(例如,"ACE" 是 "ABCDE" 的一个子序列,而 "AEC" 不是) + * + * 示例 1: + * + * 输入: S = "rabbbit", T = "rabbit" + * 输出: 3 + * 解释: + * + * 如下图所示, 有 3 种可以从 S 中得到 "rabbit" 的方案。 + * (上箭头符号 ^ 表示选取的字母) + * + * rabbbit + * ^^^^ ^^ + * rabbbit + * ^^ ^^^^ + * rabbbit + * ^^^ ^^^ + * 示例 2: + * + * 输入: S = "babgbag", T = "bag" + * 输出: 5 + * 解释: + * + * 如下图所示, 有 5 种可以从 S 中得到 "bag" 的方案。 + * (上箭头符号 ^ 表示选取的字母) + * + * babgbag + * ^^ ^ + * babgbag + * ^^ ^ + * babgbag + * ^ ^^ + * babgbag + * ^ ^^ + * babgbag + * ^^^ + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/distinct-subsequences + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _115_numDistinct { + + public static void main(String[] args) { + _115_numDistinct numDistinct = new _115_numDistinct(); + System.out.println(numDistinct.numDistinct("aaa", "aa")); + System.out.println(numDistinct.numDistinct("rabbbit", "rabbit")); + System.out.println(numDistinct.numDistinct("babgbag", "bag")); + System.out.println(numDistinct.numDistinct("adbdadeecadeadeccaeaabdabdbcdabddddabcaaadbabaaedeeddeaeebcdeabcaaaeeaeeabcddcebddebeebedaecccbdcbcedbdaeaedcdebeecdaaedaacadbdccabddaddacdddc", "bcddceeeebecbc")); + Util.printDivideLine(); + System.out.println(numDistinct.numDistinct2("babgbag", "bag")); + System.out.println(numDistinct.numDistinct2("aaa", "aa")); + System.out.println(numDistinct.numDistinct2("rabbbit", "rabbit")); + System.out.println(numDistinct.numDistinct2("adbdadeecadeadeccaeaabdabdbcdabddddabcaaadbabaaedeeddeaeebcdeabcaaaeeaeeabcddcebddebeebedaecccbdcbcedbdaeaedcdebeecdaaedaacadbdccabddaddacdddc", "bcddceeeebecbc")); + } + + /** + * 解题思路: + * 通过模拟题意中的过程,感知有点回溯的感觉: + * 1、优先匹配前面的 + * 2、匹配上了之后,再匹配后面的 + * 3、直到匹配到最后一个,向后搜索匹配的,直到末尾 + * 4、最后一位匹配到末尾之后,倒数第二位向后搜索匹配 + * 5、如此循环,直至第一位也匹配到末尾结束 + * + * 可解题,遇到复杂的提交超时: + * 比如这跟case: + * "adbdadeecadeadeccaeaabdabdbcdabddddabcaaadbabaaedeeddeaeebcdeabcaaaeeaeeabcddcebddebeebedaecccbdcbcedbdaeaedcdebeecdaaedaacadbdccabddaddacdddc" + * "bcddceeeebecbc" + * 本地跑出结果:700531452 + * + * 优化思考:是不是可以考虑将遍历过程中的一些结果保存起来,而不是每次凑重新计算==>动态规划 + * + * @param s + * @param t + * @return + */ + public int numDistinct(String s, String t) { + if (s.length() < t.length()) return 0; + int sum = 0; + int ti = 0; + int si = 0; + while (si < s.length() && ti < t.length()) { + if (s.charAt(si) == t.charAt(ti)) { + if (si + 1 < s.length() && ti + 1 < t.length()) { + sum += numDistinct(s.substring(si + 1), t.substring(ti + 1)); + } else { + if (ti == t.length() - 1) { + sum += 1; + } + } + } + si++; + } + + return sum; + } + + /** + * 优化求解:找递进规律(s:babgbag,t:bag) + * T/S "" b a b g b a g + * "" 1 1 1 1 1 1 1 1 + * b 0 1 1 2 2 3 3 3 + * a 0 0 1 1 1 1 4 4 + * g 0 0 0 0 1 1 1 5 + * + * dp[t.length() + 1][s.length() + 1] : dp[i][j]代表t[0-i]在s[0-j]中的出现的次数 + * 如果某一位t[i]==s[j],则此时的次数=dp[i-1][j-1]+dp[i][j-1] + * 如果某一位t[i]!=s[j],则此时的次数=dp[i][j-1] + * + * @param s + * @param t + * @return + */ + public int numDistinct2(String s, String t) { + int[][] dp = new int[t.length() + 1][s.length() + 1]; + for (int j = 0; j < s.length() + 1; j++) dp[0][j] = 1; + for (int i = 1; i < t.length() + 1; i++) { + for (int j = 1; j < s.length() + 1; j++) { + if (t.charAt(i - 1) == s.charAt(j - 1)) { + dp[i][j] = dp[i - 1][j - 1] + dp[i][j - 1]; + } else { + dp[i][j] = dp[i][j - 1]; + } + } + } + return dp[t.length()][s.length()]; + } +} From 47a28def53332b5f6f6213327d315e155b53b171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Sat, 14 Dec 2019 11:21:47 +0800 Subject: [PATCH 240/308] docs: add _115_numDistinct --- README.md | 9 +++++---- src/pp/arithmetic/leetcode/_115_numDistinct.java | 5 ++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 22515d7..3a88def 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成242道 +- leetcode练习,坚持每天一道,目前已完成243道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -24,7 +24,7 @@ - [x] [112. 路径总和 --Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_112_hasPathSum.java) -- [ ] [115. 不同的子序列 --Hard](https://leetcode-cn.com/problems/distinct-subsequences/) +- [x] [115. 不同的子序列 --Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_115_numDistinct.java) - [ ] [116. 填充每个节点的下一个右侧节点指针 --Medium](https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/) @@ -63,9 +63,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成242) +### 题目列表(更新中—已完成243) -[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_112_hasPathSum.java) +[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_115_numDistinct.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -183,6 +183,7 @@ | #112 | [路径总和](https://leetcode-cn.com/problems/path-sum/) | [HasPathSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_112_hasPathSum.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Easy | | | #113 | [路径总和 II](https://leetcode-cn.com/problems/path-sum-ii/) | [PathSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_113_pathSum.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #114 | [二叉树展开为链表](https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/) | [Flatten](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_114_flatten.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | +| #115 | [不同的子序列](https://leetcode-cn.com/problems/distinct-subsequences/) | [NumDistinct](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_115_numDistinct.java) | [字符串]()、[动态规划]() | Hard | | | #120 | [三角形最小路径和](https://leetcode-cn.com/problems/triangle/) | [MinimumTotal](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_120_minimumTotal.java) | [数组]()、[动态规划]() | Medium | | | #121 | [买卖股票的最佳时机](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/) | [MaxProfit](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_121_maxProfit.java) | [数组]()、[动态规划]() | Easy | | | #122 | [买卖股票的最佳时机 II](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/) | [MaxProfit](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_122_maxProfit.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Easy | | diff --git a/src/pp/arithmetic/leetcode/_115_numDistinct.java b/src/pp/arithmetic/leetcode/_115_numDistinct.java index d5af50a..1610c0b 100644 --- a/src/pp/arithmetic/leetcode/_115_numDistinct.java +++ b/src/pp/arithmetic/leetcode/_115_numDistinct.java @@ -79,7 +79,7 @@ public static void main(String[] args) { * "bcddceeeebecbc" * 本地跑出结果:700531452 * - * 优化思考:是不是可以考虑将遍历过程中的一些结果保存起来,而不是每次凑重新计算==>动态规划 + * 优化思考:是不是可以考虑将遍历过程中的一些结果保存起来,而不是每次凑重新计算==>动态规划{@link _115_numDistinct#numDistinct2(String, String)} * * @param s * @param t @@ -118,6 +118,9 @@ public int numDistinct(String s, String t) { * 如果某一位t[i]==s[j],则此时的次数=dp[i-1][j-1]+dp[i][j-1] * 如果某一位t[i]!=s[j],则此时的次数=dp[i][j-1] * + * 执行用时 :7 ms, 在所有 java 提交中击败了79.83%的用户 + * 内存消耗 :35.8 MB, 在所有 java 提交中击败了85.40%的用户 + * * @param s * @param t * @return From 986742580c5b30910ee1616794ed93f462ed1a27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Sat, 14 Dec 2019 15:21:29 +0800 Subject: [PATCH 241/308] feat(MEDIUM): add _116_connect --- src/pp/arithmetic/leetcode/_116_connect.java | 81 ++++++++++++++++++++ src/pp/arithmetic/model/Node.java | 24 ++++++ 2 files changed, 105 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_116_connect.java create mode 100644 src/pp/arithmetic/model/Node.java diff --git a/src/pp/arithmetic/leetcode/_116_connect.java b/src/pp/arithmetic/leetcode/_116_connect.java new file mode 100644 index 0000000..27b27dd --- /dev/null +++ b/src/pp/arithmetic/leetcode/_116_connect.java @@ -0,0 +1,81 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.model.Node; + +/** + * Created by wangpeng on 2019-12-14. + * 116. 填充每个节点的下一个右侧节点指针 + * + * 给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下: + * + * struct Node { + * int val; + * Node *left; + * Node *right; + * Node *next; + * } + * 填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。 + * + * 初始状态下,所有 next 指针都被设置为 NULL。 + * + *   + * + * 示例: + * + * https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2019/02/15/116_sample.png + * + * + * 输入:{"$id":"1","left":{"$id":"2","left":{"$id":"3","left":null,"next":null,"right":null,"val":4},"next":null,"right":{"$id":"4","left":null,"next":null,"right":null,"val":5},"val":2},"next":null,"right":{"$id":"5","left":{"$id":"6","left":null,"next":null,"right":null,"val":6},"next":null,"right":{"$id":"7","left":null,"next":null,"right":null,"val":7},"val":3},"val":1} + * + * 输出:{"$id":"1","left":{"$id":"2","left":{"$id":"3","left":null,"next":{"$id":"4","left":null,"next":{"$id":"5","left":null,"next":{"$id":"6","left":null,"next":null,"right":null,"val":7},"right":null,"val":6},"right":null,"val":5},"right":null,"val":4},"next":{"$id":"7","left":{"$ref":"5"},"next":null,"right":{"$ref":"6"},"val":3},"right":{"$ref":"4"},"val":2},"next":null,"right":{"$ref":"7"},"val":1} + * + * 解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。 + *   + * + * 提示: + * + * 你只能使用常量级额外空间。 + * 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _116_connect { + + public static void main(String[] args) { + _116_connect connect = new _116_connect(); + Node node = new Node(1); + node.left = new Node(2); + node.right = new Node(3); + node.left.left = new Node(4); + node.left.right = new Node(5); + node.right.left = new Node(6); + node.right.right = new Node(7); + connect.connect(node); + System.out.println(); + } + + /** + * 解题思路: + * 总结题意:BFS遍历的时候将每一层的节点用next指针关联起来,难点是只能使用常量级空间 + * 1、将左子树的最后侧,右子树的最左侧连接,同级向下一层层循环 + * 2、同理作用于根节点的左右子树 + * + * @param root + * @return + */ + public Node connect(Node root) { + if (root == null) return null; + Node left = root.left; + Node right = root.right; + while (left != null) { + left.next = right; + left = left.right; + right = right.left; + } + connect(root.left); + connect(root.right); + return root; + } +} diff --git a/src/pp/arithmetic/model/Node.java b/src/pp/arithmetic/model/Node.java new file mode 100644 index 0000000..15ac2de --- /dev/null +++ b/src/pp/arithmetic/model/Node.java @@ -0,0 +1,24 @@ +package pp.arithmetic.model; + +/** + * Created by wangpeng on 2019-12-14. + */ +public class Node { + public int val; + public Node left; + public Node right; + public Node next; + + public Node() {} + + public Node(int _val) { + val = _val; + } + + public Node(int _val, Node _left, Node _right, Node _next) { + val = _val; + left = _left; + right = _right; + next = _next; + } +} From fa3f26ad21df9b1e3e2d44e9fe243abf1cc4dc5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Sat, 14 Dec 2019 15:26:11 +0800 Subject: [PATCH 242/308] docs: add _116_connect --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3a88def..2a5a1be 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成243道 +- leetcode练习,坚持每天一道,目前已完成244道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -26,7 +26,7 @@ - [x] [115. 不同的子序列 --Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_115_numDistinct.java) -- [ ] [116. 填充每个节点的下一个右侧节点指针 --Medium](https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/) +- [x] [116. 填充每个节点的下一个右侧节点指针 --Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_116_connect.java) - [ ] [117. 填充每个节点的下一个右侧节点指针 II --Medium](https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii/) @@ -63,9 +63,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成243) +### 题目列表(更新中—已完成244) -[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_115_numDistinct.java) +[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_116_connect.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -184,6 +184,7 @@ | #113 | [路径总和 II](https://leetcode-cn.com/problems/path-sum-ii/) | [PathSum](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_113_pathSum.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #114 | [二叉树展开为链表](https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/) | [Flatten](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_114_flatten.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #115 | [不同的子序列](https://leetcode-cn.com/problems/distinct-subsequences/) | [NumDistinct](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_115_numDistinct.java) | [字符串]()、[动态规划]() | Hard | | +| #116 | [填充每个节点的下一个右侧节点指针](https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/) | [Connect](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_116_connect.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #120 | [三角形最小路径和](https://leetcode-cn.com/problems/triangle/) | [MinimumTotal](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_120_minimumTotal.java) | [数组]()、[动态规划]() | Medium | | | #121 | [买卖股票的最佳时机](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/) | [MaxProfit](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_121_maxProfit.java) | [数组]()、[动态规划]() | Easy | | | #122 | [买卖股票的最佳时机 II](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/) | [MaxProfit](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_122_maxProfit.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Easy | | From bef7cb6921d64759f98f5c6de576cfe001d9d02c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 17 Dec 2019 15:36:30 +0800 Subject: [PATCH 243/308] feat(MEDIUM): add _117_connect --- src/pp/arithmetic/leetcode/_117_connect.java | 97 ++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_117_connect.java diff --git a/src/pp/arithmetic/leetcode/_117_connect.java b/src/pp/arithmetic/leetcode/_117_connect.java new file mode 100644 index 0000000..8db4604 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_117_connect.java @@ -0,0 +1,97 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.model.Node; + +/** + * Created by wangpeng on 2019-12-16. + * 117. 填充每个节点的下一个右侧节点指针 II + * + * 给定一个二叉树 + * + * struct Node { + * int val; + * Node *left; + * Node *right; + * Node *next; + * } + * 填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。 + * + * 初始状态下,所有 next 指针都被设置为 NULL。 + * + *   + * + * 进阶: + * + * 你只能使用常量级额外空间。 + * 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。 + *   + * + * 示例: + * + * https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2019/02/15/117_sample.png + * + * 输入:root = [1,2,3,4,5,null,7] + * 输出:[1,#,2,3,#,4,5,7,#] + * 解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。 + *   + * + * 提示: + * + * 树中的节点数小于 6000 + * -100 <= node.val <= 100 + *   + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _117_connect { + + public static void main(String[] args) { + //[1,2,3,4,5,null,6,7,null,null,null,null,8] + //[1,#,2,3,#,4,5,6,#,7,#] + //[1,#,2,3,#,4,5,6,#,7,8,#] + _117_connect connect = new _117_connect(); + Node node = new Node(1); + node.left = new Node(2); + node.right = new Node(3); + node.left.left = new Node(4); + node.left.right = new Node(5); + node.right.right = new Node(6); + node.left.left.left = new Node(7); + node.right.right.right = new Node(8); + connect.connect(node); + System.out.println(); + } + + /** + * 解题思路:题目和{@link _116_connect}类似,唯一区别是此题不是完美二叉树,可能存在子树为空,所以不能使用116的解法, + * 得求解每一层需要连接的左右子树 + * + * @param root + * @return + */ + public Node connect(Node root) { + Node cur = root; + while (cur != null) { + Node dummy = new Node(); + Node tail = dummy; + //遍历 cur 的当前层 + while (cur != null) { + if (cur.left != null) { + tail.next = cur.left; + tail = tail.next; + } + if (cur.right != null) { + tail.next = cur.right; + tail = tail.next; + } + cur = cur.next; + } + //更新 cur 到下一层 + cur = dummy.next; + } + return root; + } + +} From 9cf5f192c80d04b9d42c3babe5074f1d51ac9d62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 17 Dec 2019 15:40:38 +0800 Subject: [PATCH 244/308] docs: add _117_connect --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2a5a1be..6721fe7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成244道 +- leetcode练习,坚持每天一道,目前已完成245道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -28,7 +28,7 @@ - [x] [116. 填充每个节点的下一个右侧节点指针 --Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_116_connect.java) -- [ ] [117. 填充每个节点的下一个右侧节点指针 II --Medium](https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii/) +- [x] [117. 填充每个节点的下一个右侧节点指针 II --Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_117_connect.java) ## 已解题目 @@ -63,9 +63,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成244) +### 题目列表(更新中—已完成245) -[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_116_connect.java) +[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_117_connect.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -185,6 +185,7 @@ | #114 | [二叉树展开为链表](https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/) | [Flatten](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_114_flatten.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #115 | [不同的子序列](https://leetcode-cn.com/problems/distinct-subsequences/) | [NumDistinct](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_115_numDistinct.java) | [字符串]()、[动态规划]() | Hard | | | #116 | [填充每个节点的下一个右侧节点指针](https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/) | [Connect](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_116_connect.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | +| #117 | [填充每个节点的下一个右侧节点指针 II](https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii/) | [Connect](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_117_connect.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #120 | [三角形最小路径和](https://leetcode-cn.com/problems/triangle/) | [MinimumTotal](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_120_minimumTotal.java) | [数组]()、[动态规划]() | Medium | | | #121 | [买卖股票的最佳时机](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/) | [MaxProfit](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_121_maxProfit.java) | [数组]()、[动态规划]() | Easy | | | #122 | [买卖股票的最佳时机 II](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/) | [MaxProfit](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_122_maxProfit.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Easy | | From 65342a8766e3f9ec44ef7fa3e33ecce372601aa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 18 Dec 2019 09:40:09 +0800 Subject: [PATCH 245/308] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E9=A2=98?= =?UTF-8?q?=E7=9B=AE=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 6721fe7..5a83f68 100644 --- a/README.md +++ b/README.md @@ -12,23 +12,19 @@ 扫题:顺序 -- [x] [106. 从中序与后序遍历序列构造二叉树 -Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_106_buildTree.java) +- [ ] [118. 杨辉三角](https://leetcode-cn.com/problems/pascals-triangle/) -- [x] [107. 二叉树的层次遍历 II --Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_107_levelOrderBottom.java) +- [ ] [119. 杨辉三角 II](https://leetcode-cn.com/problems/pascals-triangle-ii/) -- [x] [109. 有序链表转换二叉搜索树 --Medium]([_109_sortedListToBST.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_109_sortedListToBST.java)) +- [ ] [129. 求根到叶子节点数字之和](https://leetcode-cn.com/problems/sum-root-to-leaf-numbers/) -- [x] [110. 平衡二叉树 --Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_110_isBalanced.java) +- [ ] [130. 被围绕的区域](https://leetcode-cn.com/problems/surrounded-regions/) -- [x] [111. 二叉树的最小深度 --Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_111_minDepth.java) +- [ ] [131. 分割回文串](https://leetcode-cn.com/problems/palindrome-partitioning/) -- [x] [112. 路径总和 --Easy](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_112_hasPathSum.java) +- [ ] [132. 分割回文串 II](https://leetcode-cn.com/problems/palindrome-partitioning-ii/) -- [x] [115. 不同的子序列 --Hard](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_115_numDistinct.java) - -- [x] [116. 填充每个节点的下一个右侧节点指针 --Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_116_connect.java) - -- [x] [117. 填充每个节点的下一个右侧节点指针 II --Medium](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_117_connect.java) +- [ ] [133. 克隆图](https://leetcode-cn.com/problems/clone-graph/) ## 已解题目 From 8e8063c79b4d0a3a710f5178d1f1a1e2b9596dfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 18 Dec 2019 09:56:03 +0800 Subject: [PATCH 246/308] feat(EASY): add _118_generate --- src/pp/arithmetic/leetcode/_118_generate.java | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_118_generate.java diff --git a/src/pp/arithmetic/leetcode/_118_generate.java b/src/pp/arithmetic/leetcode/_118_generate.java new file mode 100644 index 0000000..02952cb --- /dev/null +++ b/src/pp/arithmetic/leetcode/_118_generate.java @@ -0,0 +1,74 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wangpeng on 2019-12-18. + * 118. 杨辉三角 + * + * + * 给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。 + * + * https://upload.wikimedia.org/wikipedia/commons/0/0d/PascalTriangleAnimated2.gif + * + * 在杨辉三角中,每个数是它左上方和右上方的数的和。 + * + * 示例: + * + * 输入: 5 + * 输出: + * [ + * [1], + * [1,1], + * [1,2,1], + * [1,3,3,1], + * [1,4,6,4,1] + * ] + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/pascals-triangle + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _118_generate { + + + public static void main(String[] args) { + _118_generate generate = new _118_generate(); + List> list = generate.generate(5); + for (int i = 0; i < list.size(); i++) { + Util.printList(list.get(i)); + } + } + + /** + * 解题思路: + * 0、用一个list数组保存上一行的遍历结果 + * 1、当下一行是头和尾,直接赋值1 + * 2、当下一行在中间位置j,结果=preItem.get(j - 1) + preItem.get(j) + * + * 执行用时 :1 ms, 在所有 java 提交中击败了98.18%的用户 + * 内存消耗 :34.5 MB, 在所有 java 提交中击败了25.70%的用户 + * @param numRows + * @return + */ + public List> generate(int numRows) { + List> retList = new ArrayList<>(); + List preItem = null; + for (int i = 0; i < numRows; i++) { + List item = new ArrayList<>(); + for (int j = 0; j <= i; j++) { + if (j == 0 || j == i) { + item.add(1); + } else { + item.add(preItem.get(j - 1) + preItem.get(j)); + } + } + preItem = item; + retList.add(item); + } + return retList; + } +} From 50e04c27f57ac3f123b85aa71ca4da6393ff94b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 18 Dec 2019 09:58:20 +0800 Subject: [PATCH 247/308] docs: add _118_generate --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5a83f68..145c3ce 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成245道 +- leetcode练习,坚持每天一道,目前已完成246道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -12,7 +12,7 @@ 扫题:顺序 -- [ ] [118. 杨辉三角](https://leetcode-cn.com/problems/pascals-triangle/) +- [x] [118. 杨辉三角](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_118_generate.java) - [ ] [119. 杨辉三角 II](https://leetcode-cn.com/problems/pascals-triangle-ii/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成245) +### 题目列表(更新中—已完成246) -[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_117_connect.java) +[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_118_generate.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -182,6 +182,7 @@ | #115 | [不同的子序列](https://leetcode-cn.com/problems/distinct-subsequences/) | [NumDistinct](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_115_numDistinct.java) | [字符串]()、[动态规划]() | Hard | | | #116 | [填充每个节点的下一个右侧节点指针](https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/) | [Connect](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_116_connect.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #117 | [填充每个节点的下一个右侧节点指针 II](https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii/) | [Connect](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_117_connect.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | +| #118 | [杨辉三角](https://leetcode-cn.com/problems/pascals-triangle/) | [Generate](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_118_generate.java) | [数组]() | Easy | | | #120 | [三角形最小路径和](https://leetcode-cn.com/problems/triangle/) | [MinimumTotal](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_120_minimumTotal.java) | [数组]()、[动态规划]() | Medium | | | #121 | [买卖股票的最佳时机](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/) | [MaxProfit](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_121_maxProfit.java) | [数组]()、[动态规划]() | Easy | | | #122 | [买卖股票的最佳时机 II](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/) | [MaxProfit](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_122_maxProfit.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Easy | | From 338e617276db3b28b15b55a241266a3070a72733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 18 Dec 2019 10:50:02 +0800 Subject: [PATCH 248/308] feat(EASY): add _119_getRow --- src/pp/arithmetic/leetcode/_119_getRow.java | 61 +++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_119_getRow.java diff --git a/src/pp/arithmetic/leetcode/_119_getRow.java b/src/pp/arithmetic/leetcode/_119_getRow.java new file mode 100644 index 0000000..4ab63d3 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_119_getRow.java @@ -0,0 +1,61 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wangpeng on 2019-12-18. + * 119. 杨辉三角 II + * + * 给定一个非负索引 k,其中 k ≤ 33,返回杨辉三角的第 k 行。 + * + * https://upload.wikimedia.org/wikipedia/commons/0/0d/PascalTriangleAnimated2.gif + * + * 在杨辉三角中,每个数是它左上方和右上方的数的和。 + * + * 示例: + * + * 输入: 3 + * 输出: [1,3,3,1] + * 进阶: + * + * 你可以优化你的算法到 O(k) 空间复杂度吗? + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/pascals-triangle-ii + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _119_getRow { + + public static void main(String[] args) { + _119_getRow getRow = new _119_getRow(); + Util.printList(getRow.getRow(6)); + } + + /** + * 解题思路: + * 最简单的就是像 {@link _118_generate} 中解题方式,求出第row行的结果,可是期望 O(k) 空间复杂度,这是难点 + * 考虑能不能通过规律找出直接计算第row行的结果? + * 通过杨辉三角规律可知,第i行第j个得数字结果是(i,j)的组合数 + * + * 执行用时 :1 ms, 在所有 java 提交中击败了93.68%的用户 + * 内存消耗 :33.6 MB, 在所有 java 提交中击败了23.63%的用户 + * + * @param rowIndex + * @return + */ + public List getRow(int rowIndex) { + List retList = new ArrayList<>(); + int N = rowIndex; + long pre = 1; + retList.add(1); + for (int k = 1; k <= N; k++) { + long cur = pre * (N - k + 1) / k; + retList.add((int) cur); + pre = cur; + } + return retList; + } +} From e1ad7ea0447b575f4c5d7e6befa71243624e536d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 18 Dec 2019 10:57:04 +0800 Subject: [PATCH 249/308] docs: add _119_getRow --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 145c3ce..20e94c9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成246道 +- leetcode练习,坚持每天一道,目前已完成247道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -14,7 +14,7 @@ - [x] [118. 杨辉三角](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_118_generate.java) -- [ ] [119. 杨辉三角 II](https://leetcode-cn.com/problems/pascals-triangle-ii/) +- [x] [119. 杨辉三角 II](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_119_getRow.java) - [ ] [129. 求根到叶子节点数字之和](https://leetcode-cn.com/problems/sum-root-to-leaf-numbers/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成246) +### 题目列表(更新中—已完成247) -[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_118_generate.java) +[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_119_getRow.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -183,6 +183,7 @@ | #116 | [填充每个节点的下一个右侧节点指针](https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/) | [Connect](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_116_connect.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #117 | [填充每个节点的下一个右侧节点指针 II](https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii/) | [Connect](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_117_connect.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #118 | [杨辉三角](https://leetcode-cn.com/problems/pascals-triangle/) | [Generate](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_118_generate.java) | [数组]() | Easy | | +| #119 | [杨辉三角 II](https://leetcode-cn.com/problems/pascals-triangle-ii/) | [GetRow](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_119_getRow.java) | [数组]() | Easy | | | #120 | [三角形最小路径和](https://leetcode-cn.com/problems/triangle/) | [MinimumTotal](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_120_minimumTotal.java) | [数组]()、[动态规划]() | Medium | | | #121 | [买卖股票的最佳时机](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/) | [MaxProfit](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_121_maxProfit.java) | [数组]()、[动态规划]() | Easy | | | #122 | [买卖股票的最佳时机 II](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/) | [MaxProfit](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_122_maxProfit.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Easy | | From 25d3ab7f76ff07420fae271a7ba96dee4e48fbca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 23 Dec 2019 11:47:18 +0800 Subject: [PATCH 250/308] feat(MEDIUM): add _129_sumNumbers --- .../arithmetic/leetcode/_129_sumNumbers.java | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_129_sumNumbers.java diff --git a/src/pp/arithmetic/leetcode/_129_sumNumbers.java b/src/pp/arithmetic/leetcode/_129_sumNumbers.java new file mode 100644 index 0000000..d9a28e5 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_129_sumNumbers.java @@ -0,0 +1,84 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; +import pp.arithmetic.model.TreeNode; + +/** + * Created by wangpeng on 2019-12-21. + * 129. 求根到叶子节点数字之和 + * + * 给定一个二叉树,它的每个结点都存放一个 0-9 的数字,每条从根到叶子节点的路径都代表一个数字。 + * + * 例如,从根到叶子节点路径 1->2->3 代表数字 123。 + * + * 计算从根到叶子节点生成的所有数字之和。 + * + * 说明: 叶子节点是指没有子节点的节点。 + * + * 示例 1: + * + * 输入: [1,2,3] + * 1 + * / \ + * 2 3 + * 输出: 25 + * 解释: + * 从根到叶子节点路径 1->2 代表数字 12. + * 从根到叶子节点路径 1->3 代表数字 13. + * 因此,数字总和 = 12 + 13 = 25. + * 示例 2: + * + * 输入: [4,9,0,5,1] + * 4 + * / \ + * 9 0 + *  / \ + * 5 1 + * 输出: 1026 + * 解释: + * 从根到叶子节点路径 4->9->5 代表数字 495. + * 从根到叶子节点路径 4->9->1 代表数字 491. + * 从根到叶子节点路径 4->0 代表数字 40. + * 因此,数字总和 = 495 + 491 + 40 = 1026. + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/sum-root-to-leaf-numbers + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _129_sumNumbers { + + public static void main(String[] args) { + _129_sumNumbers sumNumbers = new _129_sumNumbers(); + TreeNode treeNode = Util.generateTreeNode(new Integer[]{4, 9, 0, 5, 1}); + System.out.println(sumNumbers.sumNumbers(treeNode)); + } + + private int sum = 0; + + /** + * 解题思路: + * DFS遍历将之前的拼接节点代入,当到达叶节点后累加结果 + * + * @param root + * @return + */ + public int sumNumbers(TreeNode root) { + if (root == null) return 0; + dfs("",root); + return sum; + } + + private void dfs(String preVal, TreeNode root) { + if (root.left == null && root.right == null) { + sum += Integer.parseInt(preVal + root.val); + return; + } + if (root.left != null) { + dfs(preVal + root.val, root.left); + } + if (root.right != null) { + dfs(preVal + root.val, root.right); + } + } + +} From ed9006d08e530d300add908e71ddeed70726b2ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 23 Dec 2019 11:50:48 +0800 Subject: [PATCH 251/308] docs: add _129_sumNumbers --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 20e94c9..e760dc6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成247道 +- leetcode练习,坚持每天一道,目前已完成248道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -16,7 +16,7 @@ - [x] [119. 杨辉三角 II](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_119_getRow.java) -- [ ] [129. 求根到叶子节点数字之和](https://leetcode-cn.com/problems/sum-root-to-leaf-numbers/) +- [x] [129. 求根到叶子节点数字之和](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_129_sumNumbers.java) - [ ] [130. 被围绕的区域](https://leetcode-cn.com/problems/surrounded-regions/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成247) +### 题目列表(更新中—已完成248) -[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_119_getRow.java) +[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_129_sumNumbers.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -193,6 +193,7 @@ | #126 | [单词接龙 II](https://leetcode-cn.com/problems/word-ladder-ii/) | [FindLadders](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_126_findLadders.java) | [BFS](https://leetcode-cn.com/tag/breadth-first-search/)、[数组]()、[字符串]()、[回溯算法]() | Hard | | | #127 | [单词接龙](https://leetcode-cn.com/problems/word-ladder/) | [LadderLength](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_127_ladderLength_2.java) | [BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Medium | [自己原始解法](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_127_ladderLength.java) | | #128 | [最长连续序列](https://leetcode-cn.com/problems/longest-consecutive-sequence/) | [LongestConsecutive](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_128_longestConsecutive.java) | [并查集](https://leetcode-cn.com/tag/union-find/)、[数组]() | Hard | | +| #129 | [求根到叶子节点数字之和](https://leetcode-cn.com/problems/sum-root-to-leaf-numbers/) | [SumNumbers](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_129_sumNumbers.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #136 | [只出现一次的数字](https://leetcode-cn.com/problems/single-number/) | [SingleNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_136_singleNumber.java) | [哈希表]()、[位运算](https://leetcode-cn.com/tag/bit-manipulation/) | Easy | 位运算了解下 | | #138 | [复制带随机指针的链表](https://leetcode-cn.com/problems/copy-list-with-random-pointer/) | [CopyRandomList](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_138_CopyRandomList.java) | [哈希表]()、[链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | | #139 | [单词拆分](https://leetcode-cn.com/problems/word-break/) | [WordBreak](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_139_wordBreak.java) | [动态规划]() | Medium | 回溯实现耗时 | From af25dac177d46fa609684c1efdea1cea8d6f91c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 23 Dec 2019 19:53:56 +0800 Subject: [PATCH 252/308] feat(MEDIUM): add _130_solve --- src/pp/arithmetic/leetcode/_130_solve.java | 88 ++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_130_solve.java diff --git a/src/pp/arithmetic/leetcode/_130_solve.java b/src/pp/arithmetic/leetcode/_130_solve.java new file mode 100644 index 0000000..cbb37cd --- /dev/null +++ b/src/pp/arithmetic/leetcode/_130_solve.java @@ -0,0 +1,88 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-12-23. + * 130. 被围绕的区域 + * + * 给定一个二维的矩阵,包含 'X' 和 'O'(字母 O)。 + * + * 找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充。 + * + * 示例: + * + * X X X X + * X O O X + * X X O X + * X O X X + * 运行你的函数后,矩阵变为: + * + * X X X X + * X X X X + * X X X X + * X O X X + * 解释: + * + * 被围绕的区间不会存在于边界上,换句话说,任何边界上的 'O' 都不会被填充为 'X'。 任何不在边界上,或不与边界上的 'O' 相连的 'O' 最终都会被填充为 'X'。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/surrounded-regions + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _130_solve { + + public static void main(String[] args) { + _130_solve solve = new _130_solve(); + char[][] chars = { + {'X', 'X', 'X', 'X'}, + {'X', 'O', 'X', 'X'}, + {'X', 'X', 'O', 'X'}, + {'X', 'O', 'X', 'X'} + }; + solve.solve(chars); + } + + /** + * 解题思路: + * 难点:如何确定一个O是否被X全部给围住 + * char[][] board构建的其实是一张图,可以考虑使用图的DFS遍历 + * + * @param board + */ + public void solve(char[][] board) { + if (board == null || board.length == 0) return; + int m = board.length; + int n = board[0].length; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + // 从边缘O开始搜索 + boolean isEdge = i == 0 || j == 0 || i == m - 1 || j == n - 1; + if (isEdge && board[i][j] == 'O') { + dfs(board, i, j); + } + } + } + + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (board[i][j] == 'O') { + board[i][j] = 'X'; + } + if (board[i][j] == '#') { + board[i][j] = 'O'; + } + } + } + } + + public void dfs(char[][] board, int i, int j) { + if (i < 0 || j < 0 || i >= board.length || j >= board[0].length || board[i][j] == 'X' || board[i][j] == '#') { + // board[i][j] == '#' 说明已经搜索过了. + return; + } + board[i][j] = '#'; + dfs(board, i - 1, j); // 上 + dfs(board, i + 1, j); // 下 + dfs(board, i, j - 1); // 左 + dfs(board, i, j + 1); // 右 + } +} From 4df519d972d1e5a1495723163d94791d9f6154a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 23 Dec 2019 19:57:07 +0800 Subject: [PATCH 253/308] docs: add _130_solve --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e760dc6..f9a610e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成248道 +- leetcode练习,坚持每天一道,目前已完成249道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -18,7 +18,7 @@ - [x] [129. 求根到叶子节点数字之和](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_129_sumNumbers.java) -- [ ] [130. 被围绕的区域](https://leetcode-cn.com/problems/surrounded-regions/) +- [x] [130. 被围绕的区域](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_130_solve.java) - [ ] [131. 分割回文串](https://leetcode-cn.com/problems/palindrome-partitioning/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成248) +### 题目列表(更新中—已完成249) -[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_129_sumNumbers.java) +[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_130_solve.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -194,6 +194,7 @@ | #127 | [单词接龙](https://leetcode-cn.com/problems/word-ladder/) | [LadderLength](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_127_ladderLength_2.java) | [BFS](https://leetcode-cn.com/tag/breadth-first-search/) | Medium | [自己原始解法](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_127_ladderLength.java) | | #128 | [最长连续序列](https://leetcode-cn.com/problems/longest-consecutive-sequence/) | [LongestConsecutive](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_128_longestConsecutive.java) | [并查集](https://leetcode-cn.com/tag/union-find/)、[数组]() | Hard | | | #129 | [求根到叶子节点数字之和](https://leetcode-cn.com/problems/sum-root-to-leaf-numbers/) | [SumNumbers](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_129_sumNumbers.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | +| #130 | [被围绕的区域](https://leetcode-cn.com/problems/surrounded-regions/) | [Solve](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_130_solve.java) | [BFS](https://leetcode-cn.com/tag/breadth-first-search/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/)、[并查集](https://leetcode-cn.com/tag/union-find/) | Medium | | | #136 | [只出现一次的数字](https://leetcode-cn.com/problems/single-number/) | [SingleNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_136_singleNumber.java) | [哈希表]()、[位运算](https://leetcode-cn.com/tag/bit-manipulation/) | Easy | 位运算了解下 | | #138 | [复制带随机指针的链表](https://leetcode-cn.com/problems/copy-list-with-random-pointer/) | [CopyRandomList](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_138_CopyRandomList.java) | [哈希表]()、[链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | | #139 | [单词拆分](https://leetcode-cn.com/problems/word-break/) | [WordBreak](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_139_wordBreak.java) | [动态规划]() | Medium | 回溯实现耗时 | From a6682ecb38baa4e0513c7c609c215890c4206ee4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 26 Dec 2019 11:36:20 +0800 Subject: [PATCH 254/308] feat(MEDIUM): add _131_partition --- src/pp/arithmetic/Util.java | 11 +++ .../arithmetic/leetcode/_131_partition.java | 85 +++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_131_partition.java diff --git a/src/pp/arithmetic/Util.java b/src/pp/arithmetic/Util.java index c377a67..7e38661 100644 --- a/src/pp/arithmetic/Util.java +++ b/src/pp/arithmetic/Util.java @@ -147,6 +147,17 @@ public static void printList(List nums) { System.out.println(); } + public static void printLists(List> lists) { + for (int i = 0; i < lists.size(); i++) { + System.out.print("[ "); + for (int j = 0; j < lists.get(i).size(); j++) { + System.out.print(lists.get(i).get(j) + " "); + } + System.out.print("]"); + System.out.println(); + } + } + public static void printStringList(List nums) { if (nums == null){ System.out.println("list is null"); diff --git a/src/pp/arithmetic/leetcode/_131_partition.java b/src/pp/arithmetic/leetcode/_131_partition.java new file mode 100644 index 0000000..1d17ee4 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_131_partition.java @@ -0,0 +1,85 @@ +package pp.arithmetic.leetcode; + +import pp.arithmetic.Util; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wangpeng on 2019-12-24. + * 131. 分割回文串 + * + * 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。 + * + * 返回 s 所有可能的分割方案。 + * + * 示例: + * + * 输入: "aab" + * 输出: + * [ + * ["aa","b"], + * ["a","a","b"] + * ] + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/palindrome-partitioning + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _131_partition { + + public static void main(String[] args) { + _131_partition partition = new _131_partition(); + Util.printLists(partition.partition("aab")); + Util.printLists(partition.partition("abbaa")); + Util.printLists(partition.partition("")); + } + + /** + * 解题思路:DFS遍历+回溯 + * 1、DFS遍历,从s的第一位开始,逐步判断至最后一位 + * 2、定义一个skip=1,从1开始,代表从当前位加上skip的结果是否是回文 + * 3、定义一个循环,位置从0开始,得到所有的结果 + * + * 执行用时 :8 ms, 在所有 java 提交中击败了20.05%的用户 + * 内存消耗 :38.1 MB, 在所有 java 提交中击败了97.34%的用户 + * + * @param s + * @return + */ + public List> partition(String s) { + List> retList = new ArrayList<>(); + dfs(retList,new ArrayList<>(),s,0); + return retList; + } + + private void dfs(List> retList, List itemList, String s, int index) { + if (index > s.length()-1){ + retList.add(new ArrayList<>(itemList)); + return; + } + int skip = 1; + while (skip + index <= s.length()) { + String sub = s.substring(index, index + skip); + if (isPlalindrome(sub)) { + itemList.add(sub); + dfs(retList, itemList, s, index + skip); + if (itemList.size() > 0) { + itemList.remove(itemList.size() - 1); + } + } + skip++; + } + } + + //是否是回文 + private boolean isPlalindrome(String s) { + int si = 0, ei = s.length() - 1; + while (si < ei) { + if (s.charAt(si) != s.charAt(ei)) return false; + si++; + ei--; + } + return true; + } +} From 36e62306f221c339bc519bedd502afaac9328bc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 26 Dec 2019 11:43:23 +0800 Subject: [PATCH 255/308] docs: add _131_partition --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f9a610e..0d9d052 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成249道 +- leetcode练习,坚持每天一道,目前已完成250道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -20,7 +20,7 @@ - [x] [130. 被围绕的区域](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_130_solve.java) -- [ ] [131. 分割回文串](https://leetcode-cn.com/problems/palindrome-partitioning/) +- [x] [131. 分割回文串](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_131_partition.java) - [ ] [132. 分割回文串 II](https://leetcode-cn.com/problems/palindrome-partitioning-ii/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成249) +### 题目列表(更新中—已完成250) -[Leetcode-Java(240+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_130_solve.java) +[Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_131_partition.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -195,6 +195,7 @@ | #128 | [最长连续序列](https://leetcode-cn.com/problems/longest-consecutive-sequence/) | [LongestConsecutive](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_128_longestConsecutive.java) | [并查集](https://leetcode-cn.com/tag/union-find/)、[数组]() | Hard | | | #129 | [求根到叶子节点数字之和](https://leetcode-cn.com/problems/sum-root-to-leaf-numbers/) | [SumNumbers](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_129_sumNumbers.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #130 | [被围绕的区域](https://leetcode-cn.com/problems/surrounded-regions/) | [Solve](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_130_solve.java) | [BFS](https://leetcode-cn.com/tag/breadth-first-search/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/)、[并查集](https://leetcode-cn.com/tag/union-find/) | Medium | | +| #131 | [分割回文串](https://leetcode-cn.com/problems/palindrome-partitioning/) | [Partition](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_131_partition.java) | [回溯算法]() | Medium | | | #136 | [只出现一次的数字](https://leetcode-cn.com/problems/single-number/) | [SingleNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_136_singleNumber.java) | [哈希表]()、[位运算](https://leetcode-cn.com/tag/bit-manipulation/) | Easy | 位运算了解下 | | #138 | [复制带随机指针的链表](https://leetcode-cn.com/problems/copy-list-with-random-pointer/) | [CopyRandomList](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_138_CopyRandomList.java) | [哈希表]()、[链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | | #139 | [单词拆分](https://leetcode-cn.com/problems/word-break/) | [WordBreak](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_139_wordBreak.java) | [动态规划]() | Medium | 回溯实现耗时 | From 73f0aaec3d706fef0e07971817133106ac78e4f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 31 Dec 2019 11:14:19 +0800 Subject: [PATCH 256/308] feat(HARD): add _132_minCut --- src/pp/arithmetic/leetcode/_132_minCut.java | 57 +++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_132_minCut.java diff --git a/src/pp/arithmetic/leetcode/_132_minCut.java b/src/pp/arithmetic/leetcode/_132_minCut.java new file mode 100644 index 0000000..f1d3944 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_132_minCut.java @@ -0,0 +1,57 @@ +package pp.arithmetic.leetcode; + +/** + * Created by wangpeng on 2019-12-27. + * 132. 分割回文串 II + * + * 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。 + * + * 返回符合要求的最少分割次数。 + * + * 示例: + * + * 输入: "aab" + * 输出: 1 + * 解释: 进行一次分割就可将 s 分割成 ["aa","b"] 这样两个回文子串。 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/palindrome-partitioning-ii + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _132_minCut { + + public static void main(String[] args) { + _132_minCut minCut = new _132_minCut(); + System.out.println(minCut.minCut("aab")); + } + + /** + * 解题思路: + * 要求最少分割次数,所以在一次分割中尽可能的形成较长的回文子串,当然你也可以将所有的可能性都列出来,取其中最少的(耗时) + * + * @param s + * @return + */ + public int minCut(String s) { + boolean[][] dp = new boolean[s.length()][s.length()]; + int[] min = new int[s.length()]; + min[0] = 0; + for (int i = 1; i < s.length(); i++) { + int temp = Integer.MAX_VALUE; + for (int j = 0; j <= i; j++) { + if (s.charAt(j) == s.charAt(i) && (j + 1 > i - 1 || dp[j + 1][i - 1])) { + dp[j][i] = true; + if (j == 0) { + temp = 0; + } else { + temp = Math.min(temp, min[j - 1] + 1); + } + } + } + min[i] = temp; + + } + return min[s.length() - 1]; + + } +} From 7e48309b0e9f14f9532f79310af1b2be7fd4a616 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 31 Dec 2019 11:15:59 +0800 Subject: [PATCH 257/308] docs: add _132_minCut --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0d9d052..14ee630 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成250道 +- leetcode练习,坚持每天一道,目前已完成251道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -22,7 +22,7 @@ - [x] [131. 分割回文串](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_131_partition.java) -- [ ] [132. 分割回文串 II](https://leetcode-cn.com/problems/palindrome-partitioning-ii/) +- [x] [132. 分割回文串 II](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_132_minCut.java) - [ ] [133. 克隆图](https://leetcode-cn.com/problems/clone-graph/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成250) +### 题目列表(更新中—已完成251) -[Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_131_partition.java) +[Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_132_minCut.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -196,6 +196,7 @@ | #129 | [求根到叶子节点数字之和](https://leetcode-cn.com/problems/sum-root-to-leaf-numbers/) | [SumNumbers](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_129_sumNumbers.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | #130 | [被围绕的区域](https://leetcode-cn.com/problems/surrounded-regions/) | [Solve](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_130_solve.java) | [BFS](https://leetcode-cn.com/tag/breadth-first-search/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/)、[并查集](https://leetcode-cn.com/tag/union-find/) | Medium | | | #131 | [分割回文串](https://leetcode-cn.com/problems/palindrome-partitioning/) | [Partition](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_131_partition.java) | [回溯算法]() | Medium | | +| #132 | [分割回文串 II](https://leetcode-cn.com/problems/palindrome-partitioning-ii/) | [MinCut](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_132_minCut.java) | [动态规划]() | Hard | | | #136 | [只出现一次的数字](https://leetcode-cn.com/problems/single-number/) | [SingleNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_136_singleNumber.java) | [哈希表]()、[位运算](https://leetcode-cn.com/tag/bit-manipulation/) | Easy | 位运算了解下 | | #138 | [复制带随机指针的链表](https://leetcode-cn.com/problems/copy-list-with-random-pointer/) | [CopyRandomList](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_138_CopyRandomList.java) | [哈希表]()、[链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | | #139 | [单词拆分](https://leetcode-cn.com/problems/word-break/) | [WordBreak](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_139_wordBreak.java) | [动态规划]() | Medium | 回溯实现耗时 | From 50bc0944629f74618038b47f9dfb6e58bb7859e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 20 Jan 2020 17:22:29 +0800 Subject: [PATCH 258/308] feat(MEDIUM): add _133_cloneGraph --- .../arithmetic/leetcode/_133_cloneGraph.java | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_133_cloneGraph.java diff --git a/src/pp/arithmetic/leetcode/_133_cloneGraph.java b/src/pp/arithmetic/leetcode/_133_cloneGraph.java new file mode 100644 index 0000000..80b8945 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_133_cloneGraph.java @@ -0,0 +1,138 @@ +package pp.arithmetic.leetcode; + + +import java.util.*; + +/** + * Created by wangpeng on 2020-01-20. + * 133. 克隆图 + *

+ * 给你无向 连通 图中一个节点的引用,请你返回该图的 深拷贝(克隆)。 + *

+ * 图中的每个节点都包含它的值 val(int) 和其邻居的列表(list[Node])。 + *

+ * class Node { + * public int val; + * public List neighbors; + * } + *   + *

+ * 测试用例格式: + *

+ * 简单起见,每个节点的值都和它的索引相同。例如,第一个节点值为 1,第二个节点值为 2,以此类推。该图在测试用例中使用邻接列表表示。 + *

+ * 邻接列表是用于表示有限图的无序列表的集合。每个列表都描述了图中节点的邻居集。 + *

+ * 给定节点将始终是图中的第一个节点(值为 1)。你必须将 给定节点的拷贝 作为对克隆图的引用返回。 + *

+ *   + *

+ * 示例 1: + *

+ *

+ *

+ * 输入:adjList = [[2,4],[1,3],[2,4],[1,3]] + * 输出:[[2,4],[1,3],[2,4],[1,3]] + * 解释: + * 图中有 4 个节点。 + * 节点 1 的值是 1,它有两个邻居:节点 2 和 4 。 + * 节点 2 的值是 2,它有两个邻居:节点 1 和 3 。 + * 节点 3 的值是 3,它有两个邻居:节点 2 和 4 。 + * 节点 4 的值是 4,它有两个邻居:节点 1 和 3 。 + * 示例 2: + *

+ *

+ *

+ * 输入:adjList = [[]] + * 输出:[[]] + * 解释:输入包含一个空列表。该图仅仅只有一个值为 1 的节点,它没有任何邻居。 + * 示例 3: + *

+ * 输入:adjList = [] + * 输出:[] + * 解释:这个图是空的,它不含任何节点。 + * 示例 4: + *

+ *

+ *

+ * 输入:adjList = [[2],[1]] + * 输出:[[2],[1]] + *   + *

+ * 提示: + *

+ * 节点数介于 1 到 100 之间。 + * 每个节点值都是唯一的。 + * 无向图是一个简单图,这意味着图中没有重复的边,也没有自环。 + * 由于图是无向的,如果节点 p 是节点 q 的邻居,那么节点 q 也必须是节点 p 的邻居。 + * 图是连通图,你可以从给定节点访问到所有节点。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/clone-graph + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _133_cloneGraph { + + public static void main(String[] args) { + _133_cloneGraph cloneGraph = new _133_cloneGraph(); + Node node1 = new Node(); + node1.val = 1; + Node node2 = new Node(); + node2.val = 2; + Node node3 = new Node(); + node3.val = 3; + Node node4 = new Node(); + node4.val = 4; + //[[2,4],[1,3],[2,4],[1,3]] + node1.neighbors = new ArrayList<>(); + node1.neighbors.add(node2); + node1.neighbors.add(node4); + node2.neighbors = new ArrayList<>(); + node2.neighbors.add(node1); + node2.neighbors.add(node3); + node3.neighbors = new ArrayList<>(); + node3.neighbors.add(node2); + node3.neighbors.add(node4); + node4.neighbors = new ArrayList<>(); + node4.neighbors.add(node1); + node4.neighbors.add(node3); + Node clone = cloneGraph.cloneGraph(node1); + System.out.println(); + } + + /** + * 解题思路: + * 先花了很大的力气读题目,最后发现就是图的深度遍历,由于每个节点值都是唯一的,用一个HashMap保存遍历过的节点,防止无限循环 + * @param node + * @return + */ + public Node cloneGraph(Node node) { + if (node == null){ + return null; + } + HashMap map = new HashMap<>(); + Node cloneNode = dfs(node, map); + return cloneNode; + } + + private Node dfs(Node node, HashMap map) { + if (map.get(node.val) != null) { + return map.get(node.val); + } + Node cloneNode = new Node(); + cloneNode.val = node.val; + map.put(node.val, cloneNode); + if (node.neighbors != null) { + cloneNode.neighbors = new ArrayList<>(); + for (int i = 0; i < node.neighbors.size(); i++) { + cloneNode.neighbors.add(dfs(node.neighbors.get(i), map)); + } + } + return cloneNode; + } + + private static class Node { + public int val; + public List neighbors; + } +} From 9ed132feb9dcb7da183999b72a3369b70d47cba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 20 Jan 2020 17:26:00 +0800 Subject: [PATCH 259/308] docs: add _133_cloneGraph --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 14ee630..501762a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成251道 +- leetcode练习,坚持每天一道,目前已完成252道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -10,7 +10,7 @@ - 网址:https://leetcode-cn.com/ ## 待解题目列表 -扫题:顺序 +2020春节放假停更,祝大家越码越溜~ - [x] [118. 杨辉三角](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_118_generate.java) @@ -24,7 +24,7 @@ - [x] [132. 分割回文串 II](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_132_minCut.java) -- [ ] [133. 克隆图](https://leetcode-cn.com/problems/clone-graph/) +- [x] [133. 克隆图](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_133_cloneGraph.java) ## 已解题目 @@ -61,7 +61,7 @@ ### 题目列表(更新中—已完成251) -[Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_132_minCut.java) +[Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_133_cloneGraph.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -197,6 +197,7 @@ | #130 | [被围绕的区域](https://leetcode-cn.com/problems/surrounded-regions/) | [Solve](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_130_solve.java) | [BFS](https://leetcode-cn.com/tag/breadth-first-search/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/)、[并查集](https://leetcode-cn.com/tag/union-find/) | Medium | | | #131 | [分割回文串](https://leetcode-cn.com/problems/palindrome-partitioning/) | [Partition](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_131_partition.java) | [回溯算法]() | Medium | | | #132 | [分割回文串 II](https://leetcode-cn.com/problems/palindrome-partitioning-ii/) | [MinCut](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_132_minCut.java) | [动态规划]() | Hard | | +| #133 | [克隆图](https://leetcode-cn.com/problems/clone-graph/) | [CloneGraph](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_133_cloneGraph.java) | [BFS](https://leetcode-cn.com/tag/breadth-first-search/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/)、[图](https://leetcode-cn.com/tag/graph/) | Medium | | | #136 | [只出现一次的数字](https://leetcode-cn.com/problems/single-number/) | [SingleNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_136_singleNumber.java) | [哈希表]()、[位运算](https://leetcode-cn.com/tag/bit-manipulation/) | Easy | 位运算了解下 | | #138 | [复制带随机指针的链表](https://leetcode-cn.com/problems/copy-list-with-random-pointer/) | [CopyRandomList](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_138_CopyRandomList.java) | [哈希表]()、[链表](https://leetcode-cn.com/tag/linked-list/) | Medium | | | #139 | [单词拆分](https://leetcode-cn.com/problems/word-break/) | [WordBreak](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_139_wordBreak.java) | [动态规划]() | Medium | 回溯实现耗时 | From b5e02f301fdfcfcb8f63c26910e11a8755e745bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 9 Mar 2020 11:48:28 +0800 Subject: [PATCH 260/308] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E5=A4=9A?= =?UTF-8?q?=E7=BA=BF=E7=A8=8B=E9=A2=98=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 501762a..3af0e13 100644 --- a/README.md +++ b/README.md @@ -10,21 +10,19 @@ - 网址:https://leetcode-cn.com/ ## 待解题目列表 -2020春节放假停更,祝大家越码越溜~ +2020疫情,安全复工~ ~多线程专题 -- [x] [118. 杨辉三角](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_118_generate.java) +- [ ] [1114. 按序打印](https://leetcode-cn.com/problems/print-in-order/) -- [x] [119. 杨辉三角 II](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_119_getRow.java) +- [ ] [1115. 交替打印FooBar](https://leetcode-cn.com/problems/print-foobar-alternately/) -- [x] [129. 求根到叶子节点数字之和](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_129_sumNumbers.java) +- [ ] [1116. 打印零与奇偶数](https://leetcode-cn.com/problems/print-zero-even-odd/) -- [x] [130. 被围绕的区域](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_130_solve.java) +- [ ] [1117. H2O 生成](https://leetcode-cn.com/problems/building-h2o/) -- [x] [131. 分割回文串](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_131_partition.java) +- [ ] [1195. 交替打印字符串](https://leetcode-cn.com/problems/fizz-buzz-multithreaded/) -- [x] [132. 分割回文串 II](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_132_minCut.java) - -- [x] [133. 克隆图](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_133_cloneGraph.java) +- [ ] [1226. 哲学家进餐](https://leetcode-cn.com/problems/the-dining-philosophers/) ## 已解题目 From 11e2d056eb9f067d831ea8cb3d4b709487a5ac66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 13 Mar 2020 11:46:32 +0800 Subject: [PATCH 261/308] feat(EASY): add _1114_Foo --- src/pp/arithmetic/leetcode/_1114_Foo.java | 116 ++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_1114_Foo.java diff --git a/src/pp/arithmetic/leetcode/_1114_Foo.java b/src/pp/arithmetic/leetcode/_1114_Foo.java new file mode 100644 index 0000000..8fe9439 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_1114_Foo.java @@ -0,0 +1,116 @@ +package pp.arithmetic.leetcode; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Created by wangpeng on 2020-03-09. + * 1114. 按序打印 + *

+ * 我们提供了一个类: + *

+ * public class Foo { + *   public void one() { print("one"); } + *   public void two() { print("two"); } + *   public void three() { print("three"); } + * } + * 三个不同的线程将会共用一个 Foo 实例。 + *

+ * 线程 A 将会调用 one() 方法 + * 线程 B 将会调用 two() 方法 + * 线程 C 将会调用 three() 方法 + * 请设计修改程序,以确保 two() 方法在 one() 方法之后被执行,three() 方法在 two() 方法之后被执行。 + *

+ *   + *

+ * 示例 1: + *

+ * 输入: [1,2,3] + * 输出: "onetwothree" + * 解释: + * 有三个线程会被异步启动。 + * 输入 [1,2,3] 表示线程 A 将会调用 one() 方法,线程 B 将会调用 two() 方法,线程 C 将会调用 three() 方法。 + * 正确的输出是 "onetwothree"。 + * 示例 2: + *

+ * 输入: [1,3,2] + * 输出: "onetwothree" + * 解释: + * 输入 [1,3,2] 表示线程 A 将会调用 one() 方法,线程 B 将会调用 three() 方法,线程 C 将会调用 two() 方法。 + * 正确的输出是 "onetwothree"。 + *   + *

+ * 注意: + *

+ * 尽管输入中的数字似乎暗示了顺序,但是我们并不保证线程在操作系统中的调度顺序。 + *

+ * 你看到的输入格式主要是为了确保测试的全面性。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/print-in-order + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _1114_Foo { + + public static void main(String[] args) { + Foo foo = new Foo(); + Runnable runnable1 = new Runnable() { + @Override + public void run() { + System.out.println("printFirst"); + } + }; + Runnable runnable2 = new Runnable() { + @Override + public void run() { + System.out.println("printSecond"); + } + }; + Runnable runnable3 = new Runnable() { + @Override + public void run() { + System.out.println("printThird"); + } + }; + try { + foo.first(runnable1); + foo.third(runnable3); + foo.second(runnable2); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } + + static class Foo { + + private AtomicInteger firstJobDone = new AtomicInteger(0); + private AtomicInteger secondJobDone = new AtomicInteger(0); + + public Foo() {} + + public void first(Runnable printFirst) throws InterruptedException { + // printFirst.run() outputs "first". + printFirst.run(); + // mark the first job as done, by increasing its count. + firstJobDone.incrementAndGet(); + } + + public void second(Runnable printSecond) throws InterruptedException { + while (firstJobDone.get() != 1) { + // waiting for the first job to be done. + } + // printSecond.run() outputs "second". + printSecond.run(); + // mark the second as done, by increasing its count. + secondJobDone.incrementAndGet(); + } + + public void third(Runnable printThird) throws InterruptedException { + while (secondJobDone.get() != 1) { + // waiting for the second job to be done. + } + // printThird.run() outputs "third". + printThird.run(); + } + } +} From d0fc32cc1305a1b31a99380413586754d9429dde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 13 Mar 2020 11:49:33 +0800 Subject: [PATCH 262/308] docs: add _1114_Foo --- README.md | 9 +++++---- src/pp/arithmetic/leetcode/_1114_Foo.java | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3af0e13..8b8732f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成252道 +- leetcode练习,坚持每天一道,目前已完成253道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -12,7 +12,7 @@ 2020疫情,安全复工~ ~多线程专题 -- [ ] [1114. 按序打印](https://leetcode-cn.com/problems/print-in-order/) +- [x] [1114. 按序打印](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1114_Foo.java) - [ ] [1115. 交替打印FooBar](https://leetcode-cn.com/problems/print-foobar-alternately/) @@ -57,9 +57,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成251) +### 题目列表(更新中—已完成253) -[Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_133_cloneGraph.java) +[Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1114_Foo.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -306,6 +306,7 @@ | #1052 | [爱生气的书店老板](https://leetcode-cn.com/problems/grumpy-bookstore-owner/) | [MaxSatisfied](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1052_maxSatisfied.java) | [数组]()、[sliding window]() | Medium | | | #1053 | [交换一次的先前排列](https://leetcode-cn.com/problems/previous-permutation-with-one-swap/) | [PrevPermOpt](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1053_prevPermOpt1.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Medium | | | #1054 | [距离相等的条形码](https://leetcode-cn.com/problems/distant-barcodes/) | [RearrangeBarcodes](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1054_rearrangeBarcodes.java) | [堆](https://leetcode-cn.com/tag/heap/)、[排序](https://leetcode-cn.com/tag/sort/) | Medium | | +| #1114 | [按序打印](https://leetcode-cn.com/problems/print-in-order/) | [Foo](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1114_Foo.java) | | Easy | | LCP diff --git a/src/pp/arithmetic/leetcode/_1114_Foo.java b/src/pp/arithmetic/leetcode/_1114_Foo.java index 8fe9439..c78916a 100644 --- a/src/pp/arithmetic/leetcode/_1114_Foo.java +++ b/src/pp/arithmetic/leetcode/_1114_Foo.java @@ -81,6 +81,7 @@ public void run() { } + //一道题自己没有跑成功,不知道测试用例如何输出的 static class Foo { private AtomicInteger firstJobDone = new AtomicInteger(0); From 635a3424a14180048f7600bb81ec907b77301d3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 8 Jul 2020 16:07:04 +0800 Subject: [PATCH 263/308] feat(MEDIUM): add _1115_FooBar --- src/pp/arithmetic/leetcode/_1115_FooBar.java | 111 +++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_1115_FooBar.java diff --git a/src/pp/arithmetic/leetcode/_1115_FooBar.java b/src/pp/arithmetic/leetcode/_1115_FooBar.java new file mode 100644 index 0000000..b981d43 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_1115_FooBar.java @@ -0,0 +1,111 @@ +package pp.arithmetic.leetcode; + +import java.util.concurrent.Semaphore; + +/** + * Created by wangpeng on 2020-07-08. + * 1115. 交替打印FooBar + *

+ * 我们提供一个类: + *

+ * class FooBar { + * public void foo() { + *     for (int i = 0; i < n; i++) { + *       print("foo"); + *   } + * } + *

+ * public void bar() { + *     for (int i = 0; i < n; i++) { + *       print("bar"); + *     } + * } + * } + * 两个不同的线程将会共用一个 FooBar 实例。其中一个线程将会调用 foo() 方法,另一个线程将会调用 bar() 方法。 + *

+ * 请设计修改程序,以确保 "foobar" 被输出 n 次。 + *

+ *   + *

+ * 示例 1: + *

+ * 输入: n = 1 + * 输出: "foobar" + * 解释: 这里有两个线程被异步启动。其中一个调用 foo() 方法, 另一个调用 bar() 方法,"foobar" 将被输出一次。 + * 示例 2: + *

+ * 输入: n = 2 + * 输出: "foobarfoobar" + * 解释: "foobar" 将被输出两次。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/print-foobar-alternately + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _1115_FooBar { + + public static void main(String[] args) { + + FooBar fooBar = new FooBar(5); + new Thread() { + @Override + public void run() { + try { + fooBar.foo(new Runnable() { + @Override + public void run() { + System.out.println("foo"); + } + }); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }.start(); + new Thread() { + @Override + public void run() { + try { + fooBar.bar(new Runnable() { + @Override + public void run() { + System.out.println("bar"); + } + }); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }.start(); + + } + + static class FooBar { + private Semaphore fooSe = new Semaphore(0); + private Semaphore barSe = new Semaphore(1); + + private int n; + + public FooBar(int n) { + this.n = n; + } + + public void foo(Runnable printFoo) throws InterruptedException { + + for (int i = 0; i < n; i++) { + barSe.acquire(); + printFoo.run(); + fooSe.release(); + } + } + + public void bar(Runnable printBar) throws InterruptedException { + + for (int i = 0; i < n; i++) { + fooSe.acquire(); + printBar.run(); + barSe.release(); + } + } + } +} From bc10ce68a6fa05d002e19a5ebe771d027530f1d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 8 Jul 2020 16:10:12 +0800 Subject: [PATCH 264/308] docs: add _1115_FooBar --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8b8732f..c3b5a84 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ - [x] [1114. 按序打印](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1114_Foo.java) -- [ ] [1115. 交替打印FooBar](https://leetcode-cn.com/problems/print-foobar-alternately/) +- [x] [1115. 交替打印FooBar](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1115_FooBar.java) - [ ] [1116. 打印零与奇偶数](https://leetcode-cn.com/problems/print-zero-even-odd/) @@ -57,9 +57,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成253) +### 题目列表(更新中—已完成254) -[Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1114_Foo.java) +[Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1115_FooBar.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -307,6 +307,7 @@ | #1053 | [交换一次的先前排列](https://leetcode-cn.com/problems/previous-permutation-with-one-swap/) | [PrevPermOpt](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1053_prevPermOpt1.java) | [贪心算法](https://leetcode-cn.com/tag/greedy/)、[数组]() | Medium | | | #1054 | [距离相等的条形码](https://leetcode-cn.com/problems/distant-barcodes/) | [RearrangeBarcodes](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1054_rearrangeBarcodes.java) | [堆](https://leetcode-cn.com/tag/heap/)、[排序](https://leetcode-cn.com/tag/sort/) | Medium | | | #1114 | [按序打印](https://leetcode-cn.com/problems/print-in-order/) | [Foo](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1114_Foo.java) | | Easy | | +| #1115 | [交替打印FooBar](https://leetcode-cn.com/problems/print-foobar-alternately/) | [FooBar]([Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1115_FooBar.java)) | | Medium | | LCP From be8cdefc1ac4d3f2e871f8845d456a7a889c0f52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 14 Jul 2020 11:14:08 +0800 Subject: [PATCH 265/308] feat(MEDIUM): add _1116_ZeroEvenOdd --- .../leetcode/_1116_ZeroEvenOdd.java | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_1116_ZeroEvenOdd.java diff --git a/src/pp/arithmetic/leetcode/_1116_ZeroEvenOdd.java b/src/pp/arithmetic/leetcode/_1116_ZeroEvenOdd.java new file mode 100644 index 0000000..5aeac21 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_1116_ZeroEvenOdd.java @@ -0,0 +1,125 @@ +package pp.arithmetic.leetcode; + +import java.util.concurrent.Semaphore; +import java.util.function.IntConsumer; + +/** + * Created by wangpeng on 2020-07-09. + * 1116. 打印零与奇偶数 + *

+ * 假设有这么一个类: + *

+ * class ZeroEvenOdd { + *   public ZeroEvenOdd(int n) { ... }  // 构造函数 + * public void zero(printNumber) { ... } // 仅打印出 0 + * public void even(printNumber) { ... } // 仅打印出 偶数 + * public void odd(printNumber) { ... } // 仅打印出 奇数 + * } + * 相同的一个 ZeroEvenOdd 类实例将会传递给三个不同的线程: + *

+ * 线程 A 将调用 zero(),它只输出 0 。 + * 线程 B 将调用 even(),它只输出偶数。 + * 线程 C 将调用 odd(),它只输出奇数。 + * 每个线程都有一个 printNumber 方法来输出一个整数。请修改给出的代码以输出整数序列 010203040506... ,其中序列的长度必须为 2n。 + *

+ *   + *

+ * 示例 1: + *

+ * 输入:n = 2 + * 输出:"0102" + * 说明:三条线程异步执行,其中一个调用 zero(),另一个线程调用 even(),最后一个线程调用odd()。正确的输出为 "0102"。 + * 示例 2: + *

+ * 输入:n = 5 + * 输出:"0102030405" + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/print-zero-even-odd + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _1116_ZeroEvenOdd { + + public static void main(String[] args) { + ZeroEvenOdd zeroEvenOdd = new ZeroEvenOdd(5); + IntConsumer printNumber = new IntConsumer() { + @Override + public void accept(int value) { + System.out.println(value); + } + }; + new Thread(){ + @Override + public void run() { + super.run(); + try { + zeroEvenOdd.zero(printNumber); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }.start(); + new Thread(){ + @Override + public void run() { + super.run(); + try { + zeroEvenOdd.even(printNumber); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }.start(); + new Thread(){ + @Override + public void run() { + super.run(); + try { + zeroEvenOdd.odd(printNumber); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }.start(); + } + + static class ZeroEvenOdd { + private int n; + private Semaphore zeroSe = new Semaphore(1); + private Semaphore evenSe = new Semaphore(0); + private Semaphore oddSe = new Semaphore(0); + + public ZeroEvenOdd(int n) { + this.n = n; + } + + // printNumber.accept(x) outputs "x", where x is an integer. + public void zero(IntConsumer printNumber) throws InterruptedException { + for (int i = 0; i < n; i++) { + zeroSe.acquire(); + printNumber.accept(0); + if (i % 2 == 0) { + evenSe.release(); + } else { + oddSe.release(); + } + } + } + + public void even(IntConsumer printNumber) throws InterruptedException { + for (int i = 1; i <= n; i+=2) { + evenSe.acquire(); + printNumber.accept(i); + zeroSe.release(); + } + } + + public void odd(IntConsumer printNumber) throws InterruptedException { + for (int i = 2; i <= n; i+=2) { + oddSe.acquire(); + printNumber.accept(i); + zeroSe.release(); + } + } + } +} From 033706c2854c68e504e05c32735fa0cca5ff0a01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 14 Jul 2020 11:33:13 +0800 Subject: [PATCH 266/308] docs: add _1116_ZeroEvenOdd --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c3b5a84..6399072 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ - [x] [1115. 交替打印FooBar](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1115_FooBar.java) -- [ ] [1116. 打印零与奇偶数](https://leetcode-cn.com/problems/print-zero-even-odd/) +- [x] [1116. 打印零与奇偶数](https://leetcode-cn.com/problems/print-zero-even-odd/) - [ ] [1117. H2O 生成](https://leetcode-cn.com/problems/building-h2o/) @@ -57,9 +57,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成254) +### 题目列表(更新中—已完成255) -[Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1115_FooBar.java) +[Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1116_ZeroEvenOdd.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -308,6 +308,7 @@ | #1054 | [距离相等的条形码](https://leetcode-cn.com/problems/distant-barcodes/) | [RearrangeBarcodes](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1054_rearrangeBarcodes.java) | [堆](https://leetcode-cn.com/tag/heap/)、[排序](https://leetcode-cn.com/tag/sort/) | Medium | | | #1114 | [按序打印](https://leetcode-cn.com/problems/print-in-order/) | [Foo](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1114_Foo.java) | | Easy | | | #1115 | [交替打印FooBar](https://leetcode-cn.com/problems/print-foobar-alternately/) | [FooBar]([Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1115_FooBar.java)) | | Medium | | +| #1116 | [打印零与奇偶数](https://leetcode-cn.com/problems/print-zero-even-odd/) | [ZeroEvenOdd](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1116_ZeroEvenOdd.java) | | Medium | | LCP From 22c6c1c595905f8841fb09e632c8a45e5aee226f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 15 Jul 2020 14:26:22 +0800 Subject: [PATCH 267/308] feat(MEDIUM): add _1117_H2O --- src/pp/arithmetic/leetcode/_1117_H2O.java | 196 ++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_1117_H2O.java diff --git a/src/pp/arithmetic/leetcode/_1117_H2O.java b/src/pp/arithmetic/leetcode/_1117_H2O.java new file mode 100644 index 0000000..3d9661f --- /dev/null +++ b/src/pp/arithmetic/leetcode/_1117_H2O.java @@ -0,0 +1,196 @@ +package pp.arithmetic.leetcode; + +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.Semaphore; + +/** + * Created by wangpeng on 2020-07-15. + * 1117. H2O 生成 + *

+ * 现在有两种线程,氧 oxygen 和氢 hydrogen,你的目标是组织这两种线程来产生水分子。 + *

+ * 存在一个屏障(barrier)使得每个线程必须等候直到一个完整水分子能够被产生出来。 + *

+ * 氢和氧线程会被分别给予 releaseHydrogen 和 releaseOxygen 方法来允许它们突破屏障。 + *

+ * 这些线程应该三三成组突破屏障并能立即组合产生一个水分子。 + *

+ * 你必须保证产生一个水分子所需线程的结合必须发生在下一个水分子产生之前。 + *

+ * 换句话说: + *

+ * 如果一个氧线程到达屏障时没有氢线程到达,它必须等候直到两个氢线程到达。 + * 如果一个氢线程到达屏障时没有其它线程到达,它必须等候直到一个氧线程和另一个氢线程到达。 + * 书写满足这些限制条件的氢、氧线程同步代码。 + *

+ *   + *

+ * 示例 1: + *

+ * 输入: "HOH" + * 输出: "HHO" + * 解释: "HOH" 和 "OHH" 依然都是有效解。 + * 示例 2: + *

+ * 输入: "OOHHHH" + * 输出: "HHOHHO" + * 解释: "HOHHHO", "OHHHHO", "HHOHOH", "HOHHOH", "OHHHOH", "HHOOHH", "HOHOHH" 和 "OHHOHH" 依然都是有效解。 + *   + *

+ * 提示: + *

+ * 输入字符串的总长将会是 3n, 1 ≤ n ≤ 50; + * 输入字符串中的 “H” 总数将会是 2n 。 + * 输入字符串中的 “O” 总数将会是 n 。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/building-h2o + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _1117_H2O { + + + public static void main(String[] args) { + + int n = 6; + H2O h2O = new H2O(); + for (int i = 0; i < n * 2; i++) { + //H + new Thread() { + @Override + public void run() { + super.run(); + try { + h2O.hydrogen(new Runnable() { + @Override + public void run() { + System.out.println("H"); + } + }); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }.start(); + } + for (int i = 0; i < n; i++) { + //O + new Thread() { + @Override + public void run() { + super.run(); + try { + h2O.oxygen(new Runnable() { + @Override + public void run() { + System.out.println("O"); + } + }); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }.start(); + } + } + + class H2O2 { + + private Semaphore hs; + private Semaphore os; + private CyclicBarrier totalBarrier; + + public H2O2() { + hs = new Semaphore(2); + os = new Semaphore(1); + //await用于标识等待所有的线程都达到barrier才继续执行 + totalBarrier = new CyclicBarrier(3); + } + + public void hydrogen(Runnable releaseHydrogen) throws InterruptedException { + hs.acquire(); + // releaseHydrogen.run() outputs "H". Do not change or remove this line. + releaseHydrogen.run(); + try { + totalBarrier.await(); + } catch (BrokenBarrierException e) { + e.printStackTrace(); + } + hs.release(); + } + + public void oxygen(Runnable releaseOxygen) throws InterruptedException { + os.acquire(); + // releaseOxygen.run() outputs "O". Do not change or remove this line. + releaseOxygen.run(); + try { + totalBarrier.await(); + } catch (BrokenBarrierException e) { + e.printStackTrace(); + } + os.release(); + } + } + + + static class H2O { + + private final Object lock = new Object(); + private int hc = 2; + private int oc = 1; + + public H2O() { + + } + + public void hydrogen(Runnable releaseHydrogen) throws InterruptedException { + + boolean flag = false; + synchronized (lock) { + while (hc == 0) { + lock.wait(); + synchronized (lock) { + if (hc > 0) { + hc--; + flag = true; + break; + } + } + } + if (!flag) hc--; + // releaseHydrogen.run() outputs "H". Do not change or remove this line. + releaseHydrogen.run(); + reset(); + } + } + + public void oxygen(Runnable releaseOxygen) throws InterruptedException { + boolean flag = false; + synchronized (lock) { + while (oc == 0) { + lock.wait(); + synchronized (lock) { + if (oc > 0) { + oc--; + flag = true; + break; + } + } + } + if (!flag) oc--; + // releaseOxygen.run() outputs "O". Do not change or remove this line. + releaseOxygen.run(); + reset(); + } + } + + private void reset() { + if (hc == 0 && oc == 0) { + hc = 2; + oc = 1; + lock.notifyAll(); + } + } + } +} From 4bb02b0a4cebb0b63715ec998258a4335de7e82f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 15 Jul 2020 14:31:58 +0800 Subject: [PATCH 268/308] docs: add _1117_H2O --- README.md | 5 +++-- src/pp/arithmetic/leetcode/_1117_H2O.java | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6399072..e9dc433 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ - [x] [1116. 打印零与奇偶数](https://leetcode-cn.com/problems/print-zero-even-odd/) -- [ ] [1117. H2O 生成](https://leetcode-cn.com/problems/building-h2o/) +- [x] [1117. H2O 生成](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1116_ZeroEvenOdd.java) - [ ] [1195. 交替打印字符串](https://leetcode-cn.com/problems/fizz-buzz-multithreaded/) @@ -57,7 +57,7 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成255) +### 题目列表(更新中—已完成256) [Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1116_ZeroEvenOdd.java) @@ -309,6 +309,7 @@ | #1114 | [按序打印](https://leetcode-cn.com/problems/print-in-order/) | [Foo](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1114_Foo.java) | | Easy | | | #1115 | [交替打印FooBar](https://leetcode-cn.com/problems/print-foobar-alternately/) | [FooBar]([Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1115_FooBar.java)) | | Medium | | | #1116 | [打印零与奇偶数](https://leetcode-cn.com/problems/print-zero-even-odd/) | [ZeroEvenOdd](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1116_ZeroEvenOdd.java) | | Medium | | +| #1117 | [H2O 生成](https://leetcode-cn.com/problems/building-h2o/) | [H2O](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1117_H2O.java) | | Medium | | LCP diff --git a/src/pp/arithmetic/leetcode/_1117_H2O.java b/src/pp/arithmetic/leetcode/_1117_H2O.java index 3d9661f..79a195e 100644 --- a/src/pp/arithmetic/leetcode/_1117_H2O.java +++ b/src/pp/arithmetic/leetcode/_1117_H2O.java @@ -95,6 +95,7 @@ public void run() { } } + //使用系统类进行优化 class H2O2 { private Semaphore hs; From 0e86375c901b214485edf10e0fb1a8cab2c79afd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 16 Jul 2020 14:24:04 +0800 Subject: [PATCH 269/308] feat(MEDIUM): add _1195_FizzBuzz --- .../arithmetic/leetcode/_1195_FizzBuzz.java | 187 ++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_1195_FizzBuzz.java diff --git a/src/pp/arithmetic/leetcode/_1195_FizzBuzz.java b/src/pp/arithmetic/leetcode/_1195_FizzBuzz.java new file mode 100644 index 0000000..1c000d7 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_1195_FizzBuzz.java @@ -0,0 +1,187 @@ +package pp.arithmetic.leetcode; + +import java.util.concurrent.Semaphore; +import java.util.function.IntConsumer; + +/** + * Created by wangpeng on 2020-07-16. + * 1195. 交替打印字符串 + *

+ * 编写一个可以从 1 到 n 输出代表这个数字的字符串的程序,但是: + *

+ * 如果这个数字可以被 3 整除,输出 "fizz"。 + * 如果这个数字可以被 5 整除,输出 "buzz"。 + * 如果这个数字可以同时被 3 和 5 整除,输出 "fizzbuzz"。 + * 例如,当 n = 15,输出: 1, 2, fizz, 4, buzz, fizz, 7, 8, fizz, buzz, 11, fizz, 13, 14, fizzbuzz。 + *

+ * 假设有这么一个类: + *

+ * class FizzBuzz { + *   public FizzBuzz(int n) { ... }  // constructor + * public void fizz(printFizz) { ... } // only output "fizz" + * public void buzz(printBuzz) { ... } // only output "buzz" + * public void fizzbuzz(printFizzBuzz) { ... } // only output "fizzbuzz" + * public void number(printNumber) { ... } // only output the numbers + * } + * 请你实现一个有四个线程的多线程版  FizzBuzz, 同一个 FizzBuzz 实例会被如下四个线程使用: + *

+ * 线程A将调用 fizz() 来判断是否能被 3 整除,如果可以,则输出 fizz。 + * 线程B将调用 buzz() 来判断是否能被 5 整除,如果可以,则输出 buzz。 + * 线程C将调用 fizzbuzz() 来判断是否同时能被 3 和 5 整除,如果可以,则输出 fizzbuzz。 + * 线程D将调用 number() 来实现输出既不能被 3 整除也不能被 5 整除的数字。 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/fizz-buzz-multithreaded + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _1195_FizzBuzz { + + public static void main(String[] args) { + FizzBuzz fizzBuzz = new FizzBuzz(16); + new Thread() { + @Override + public void run() { + super.run(); + try { + fizzBuzz.fizz(new Runnable() { + @Override + public void run() { + System.out.println("fizz"); + } + }); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }.start(); + new Thread() { + @Override + public void run() { + super.run(); + try { + fizzBuzz.buzz(new Runnable() { + @Override + public void run() { + System.out.println("buzz"); + } + }); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }.start(); + new Thread() { + @Override + public void run() { + super.run(); + try { + fizzBuzz.fizzbuzz(new Runnable() { + @Override + public void run() { + System.out.println("fizzbuzz"); + } + }); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }.start(); + new Thread() { + @Override + public void run() { + super.run(); + try { + fizzBuzz.number(new IntConsumer() { + @Override + public void accept(int value) { + System.out.println(value); + } + }); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }.start(); + } + + /** + * 解题思路:对于多线程的问题,无非是加锁、等待、解锁、通知, + */ + static class FizzBuzz { + private int n; + private int pn = 1; + private Semaphore fs = new Semaphore(0); + private Semaphore bs = new Semaphore(0); + private Semaphore fbs = new Semaphore(0); + private Semaphore ns = new Semaphore(1); + + public FizzBuzz(int n) { + this.n = n; + } + + // printFizz.run() outputs "fizz". + public void fizz(Runnable printFizz) throws InterruptedException { + while (pn <= n) { + fs.acquire(); + if (pn > n) break; + printFizz.run(); + pn++; + notifyPrint(); + } + } + + // printBuzz.run() outputs "buzz". + public void buzz(Runnable printBuzz) throws InterruptedException { + while (pn <= n) { + bs.acquire(); + if (pn > n) break; + printBuzz.run(); + pn++; + notifyPrint(); + } + } + + // printFizzBuzz.run() outputs "fizzbuzz". + public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException { + while (pn <= n) { + fbs.acquire(); + if (pn > n) break; + printFizzBuzz.run(); + pn++; + notifyPrint(); + } + } + + // printNumber.accept(x) outputs "x", where x is an integer. + public void number(IntConsumer printNumber) throws InterruptedException { + while (pn <= n) { + ns.acquire(); + if (pn > n) break; + printNumber.accept(pn); + pn++; + notifyPrint(); + } + } + + private void notifyPrint() { + if (pn > n) { + fs.release(); + bs.release(); + fbs.release(); + ns.release(); + return; + } + boolean m3 = pn % 3 == 0; + boolean m5 = pn % 5 == 0; + if (m3 && m5) { + fbs.release(); + } else if (m3) { + fs.release(); + } else if (m5) { + bs.release(); + } else { + ns.release(); + } + } + } +} From f3930af7e6e1bac9d158fbe0401f3fd389a4f916 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 16 Jul 2020 14:34:12 +0800 Subject: [PATCH 270/308] docs: add _1195_FizzBuzz --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e9dc433..7ba3d7d 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ - [x] [1117. H2O 生成](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1116_ZeroEvenOdd.java) -- [ ] [1195. 交替打印字符串](https://leetcode-cn.com/problems/fizz-buzz-multithreaded/) +- [x] [1195. 交替打印字符串](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1195_FizzBuzz.java) - [ ] [1226. 哲学家进餐](https://leetcode-cn.com/problems/the-dining-philosophers/) @@ -57,9 +57,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成256) +### 题目列表(更新中—已完成257) -[Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1116_ZeroEvenOdd.java) +[Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1195_FizzBuzz.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -310,6 +310,7 @@ | #1115 | [交替打印FooBar](https://leetcode-cn.com/problems/print-foobar-alternately/) | [FooBar]([Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1115_FooBar.java)) | | Medium | | | #1116 | [打印零与奇偶数](https://leetcode-cn.com/problems/print-zero-even-odd/) | [ZeroEvenOdd](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1116_ZeroEvenOdd.java) | | Medium | | | #1117 | [H2O 生成](https://leetcode-cn.com/problems/building-h2o/) | [H2O](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1117_H2O.java) | | Medium | | +| #1195 | [交替打印字符串](https://leetcode-cn.com/problems/fizz-buzz-multithreaded/) | [FizzBuzz](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1195_FizzBuzz.java) | | Medium | | LCP From a21f888a999bfb29975d5e3b254bb0426e09ca2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 22 Jul 2020 12:00:00 +0800 Subject: [PATCH 271/308] feat(MEDIUM): add _1226_DiningPhilosophers --- .../leetcode/_1226_DiningPhilosophers.java | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 src/pp/arithmetic/leetcode/_1226_DiningPhilosophers.java diff --git a/src/pp/arithmetic/leetcode/_1226_DiningPhilosophers.java b/src/pp/arithmetic/leetcode/_1226_DiningPhilosophers.java new file mode 100644 index 0000000..291cf68 --- /dev/null +++ b/src/pp/arithmetic/leetcode/_1226_DiningPhilosophers.java @@ -0,0 +1,155 @@ +package pp.arithmetic.leetcode; + +import java.util.concurrent.Semaphore; + +/** + * Created by wangpeng on 2020-07-17. + * 1226. 哲学家进餐 + * + * 5 个沉默寡言的哲学家围坐在圆桌前,每人面前一盘意面。叉子放在哲学家之间的桌面上。(5 个哲学家,5 根叉子) + * + * 所有的哲学家都只会在思考和进餐两种行为间交替。哲学家只有同时拿到左边和右边的叉子才能吃到面,而同一根叉子在同一时间只能被一个哲学家使用。每个哲学家吃完面后都需要把叉子放回桌面以供其他哲学家吃面。只要条件允许,哲学家可以拿起左边或者右边的叉子,但在没有同时拿到左右叉子时不能进食。 + * + * 假设面的数量没有限制,哲学家也能随便吃,不需要考虑吃不吃得下。 + * + * 设计一个进餐规则(并行算法)使得每个哲学家都不会挨饿;也就是说,在没有人知道别人什么时候想吃东西或思考的情况下,每个哲学家都可以在吃饭和思考之间一直交替下去。 + * + * + * 问题描述和图片来自维基百科 wikipedia.org + * 图片地址:https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2019/10/23/an_illustration_of_the_dining_philosophers_problem.png + * + * + * 哲学家从 0 到 4 按 顺时针 编号。请实现函数 void wantsToEat(philosopher, pickLeftFork, pickRightFork, eat, putLeftFork, putRightFork): + * + * philosopher 哲学家的编号。 + * pickLeftFork 和 pickRightFork 表示拿起左边或右边的叉子。 + * eat 表示吃面。 + * putLeftFork 和 putRightFork 表示放下左边或右边的叉子。 + * 由于哲学家不是在吃面就是在想着啥时候吃面,所以思考这个方法没有对应的回调。 + * 给你 5 个线程,每个都代表一个哲学家,请你使用类的同一个对象来模拟这个过程。在最后一次调用结束之前,可能会为同一个哲学家多次调用该函数。 + * + *   + * + * 示例: + * + * 输入:n = 1 + * 输出:[[4,2,1],[4,1,1],[0,1,1],[2,2,1],[2,1,1],[2,0,3],[2,1,2],[2,2,2],[4,0,3],[4,1,2],[0,2,1],[4,2,2],[3,2,1],[3,1,1],[0,0,3],[0,1,2],[0,2,2],[1,2,1],[1,1,1],[3,0,3],[3,1,2],[3,2,2],[1,0,3],[1,1,2],[1,2,2]] + * 解释: + * n 表示每个哲学家需要进餐的次数。 + * 输出数组描述了叉子的控制和进餐的调用,它的格式如下: + * output[i] = [a, b, c] (3个整数) + * - a 哲学家编号。 + * - b 指定叉子:{1 : 左边, 2 : 右边}. + * - c 指定行为:{1 : 拿起, 2 : 放下, 3 : 吃面}。 + * 如 [4,2,1] 表示 4 号哲学家拿起了右边的叉子。 + *   + * + * 提示: + * + * 1 <= n <= 60 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/the-dining-philosophers + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _1226_DiningPhilosophers { + + public static void main(String[] args) { + DiningPhilosophers diningPhilosophers = new DiningPhilosophers(); + for (int i = 0; i < 5; i++) { + int finalI = i; + new Thread(){ + @Override + public void run() { + super.run(); + try { + diningPhilosophers.wantsToEat(finalI, new Runnable() { + @Override + public void run() { + System.out.println("["+finalI+",1,1]"); + } + }, new Runnable() { + @Override + public void run() { + System.out.println("["+finalI+",2,1]"); + } + }, new Runnable() { + @Override + public void run() { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("["+finalI+",0,3]"); + } + }, new Runnable() { + @Override + public void run() { + System.out.println("["+finalI+",1,2]"); + } + }, new Runnable() { + @Override + public void run() { + System.out.println("["+finalI+",2,2]"); + } + }); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }.start(); + } + } + + /** + * 解题思路: + * 资源:5个叉子(5个信号量),同时拿到两个叉子(1个互斥信号量,防止死锁),此题解并不是最优解,最优解应该能满足多个同时进餐 + */ + static class DiningPhilosophers { + //一个互斥信号量用于临界资源的互斥访问 + private Semaphore mutex; + //5个同步信号量用于哲学家之间的同步访问 + private Semaphore[] sema; + public DiningPhilosophers() { + mutex = new Semaphore(1); + sema = new Semaphore[] { + new Semaphore(1), + new Semaphore(1), + new Semaphore(1), + new Semaphore(1), + new Semaphore(1) + }; + } + + // call the run() method of any runnable to execute its code + public void wantsToEat(int philosopher, + Runnable pickLeftFork, + Runnable pickRightFork, + Runnable eat, + Runnable putLeftFork, + Runnable putRightFork) throws InterruptedException { + //一个哲学家如果要拿起叉子就同时拿两个,因此这里是一个原子操作,需要用mutex信号量包起来,表示互斥 + mutex.acquire(); + //尝试获取左手边的叉子 + sema[philosopher].acquire(); + //尝试获取右手边的叉子 + sema[(philosopher+1) % 5].acquire(); + + pickLeftFork.run(); + pickRightFork.run(); + //我认为这句话应该放在这里。 + // mutex.release(); + + //拿到叉子开始吃饭 + eat.run(); + + //吃完饭放下叉子 + putLeftFork.run(); + sema[philosopher].release(); + putRightFork.run(); + sema[(philosopher+1) % 5].release(); + mutex.release(); + } + } +} From ed1465a92ebe0237ee23d11f3cbd917ddafb8955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 22 Jul 2020 12:02:13 +0800 Subject: [PATCH 272/308] docs: add _1226_DiningPhilosophers --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7ba3d7d..a90c97e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成253道 +- leetcode练习,坚持每天一道,目前已完成258道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -22,7 +22,7 @@ - [x] [1195. 交替打印字符串](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1195_FizzBuzz.java) -- [ ] [1226. 哲学家进餐](https://leetcode-cn.com/problems/the-dining-philosophers/) +- [x] [1226. 哲学家进餐](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1226_DiningPhilosophers.java/) ## 已解题目 @@ -57,9 +57,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成257) +### 题目列表(更新中—已完成258) -[Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1195_FizzBuzz.java) +[Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1226_DiningPhilosophers.java) | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | @@ -311,6 +311,7 @@ | #1116 | [打印零与奇偶数](https://leetcode-cn.com/problems/print-zero-even-odd/) | [ZeroEvenOdd](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1116_ZeroEvenOdd.java) | | Medium | | | #1117 | [H2O 生成](https://leetcode-cn.com/problems/building-h2o/) | [H2O](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1117_H2O.java) | | Medium | | | #1195 | [交替打印字符串](https://leetcode-cn.com/problems/fizz-buzz-multithreaded/) | [FizzBuzz](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1195_FizzBuzz.java) | | Medium | | +| #1226 | [哲学家进餐](https://leetcode-cn.com/problems/the-dining-philosophers/) | [DiningPhilosophers](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1226_DiningPhilosophers.java) | | Medium | | LCP From f1d86f2a5bbc4a4d80497c7b8fa478d07ea80283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 28 Jul 2020 10:30:33 +0800 Subject: [PATCH 273/308] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E5=89=91?= =?UTF-8?q?=E6=8C=87offer=E4=B8=93=E9=A2=98=E7=B3=BB=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index a90c97e..032ada9 100644 --- a/README.md +++ b/README.md @@ -10,19 +10,15 @@ - 网址:https://leetcode-cn.com/ ## 待解题目列表 -2020疫情,安全复工~ ~多线程专题 +剑指offer系列-持续多月,每周7题 -- [x] [1114. 按序打印](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1114_Foo.java) - -- [x] [1115. 交替打印FooBar](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1115_FooBar.java) - -- [x] [1116. 打印零与奇偶数](https://leetcode-cn.com/problems/print-zero-even-odd/) - -- [x] [1117. H2O 生成](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1116_ZeroEvenOdd.java) - -- [x] [1195. 交替打印字符串](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1195_FizzBuzz.java) - -- [x] [1226. 哲学家进餐](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1226_DiningPhilosophers.java/) +- [ ] [数组中重复的数字](https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof) +- [ ] [二维数组中的查找](https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof) +- [ ] [替换空格](https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof) +- [ ] [从尾到头打印链表](https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof) +- [ ] [重建二叉树](https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof) +- [ ] [用两个栈实现队列](https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof) +- [ ] [斐波那契数列](https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof) ## 已解题目 From 000960f50ff0cc7cdc24059d571836b5965c5720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 28 Jul 2020 11:18:12 +0800 Subject: [PATCH 274/308] feat(offer-easy): add _03_findRepeatNumber --- .../offer/_03_findRepeatNumber.java | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 src/pp/arithmetic/offer/_03_findRepeatNumber.java diff --git a/src/pp/arithmetic/offer/_03_findRepeatNumber.java b/src/pp/arithmetic/offer/_03_findRepeatNumber.java new file mode 100644 index 0000000..8fbedfa --- /dev/null +++ b/src/pp/arithmetic/offer/_03_findRepeatNumber.java @@ -0,0 +1,124 @@ +package pp.arithmetic.offer; + +import java.util.HashMap; + +/** + * Created by wangpeng on 2020-07-28. + * 剑指 Offer 03. 数组中重复的数字 + *

+ * 找出数组中重复的数字。 + *

+ *

+ * 在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。 + *

+ * 示例 1: + *

+ * 输入: + * [2, 3, 1, 0, 2, 5, 3] + * 输出:2 或 3 + *   + *

+ * 限制: + *

+ * 2 <= n <= 100000 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _03_findRepeatNumber { + + public static void main(String[] args) { + _03_findRepeatNumber findRepeatNumber = new _03_findRepeatNumber(); + int repeatNumber = findRepeatNumber.findRepeatNumber(new int[]{2, 3, 0, 1, 2, 3, 4, 5, 3}); + System.out.println(repeatNumber); + int repeatNumber2 = findRepeatNumber.findRepeatNumber2(new int[]{2, 3, 0, 1, 2, 3, 4, 5, 3}); + System.out.println(repeatNumber2); + int repeatNumber3 = findRepeatNumber.findRepeatNumber3(new int[]{2, 3, 0, 1, 2, 3, 4, 5, 3}); + System.out.println(repeatNumber3); + } + + /** + * 解题思路: + * 方案一:最直接的方式,使用一个HashMap进行存储遍历过的数字,性能肯定不会差,内存占用会高 + *

+ * 执行用时:13 ms, 在所有 Java 提交中击败了8.98%的用户 + * 内存消耗:48.7 MB, 在所有 Java 提交中击败了100.00%的用户 + *

+ * 执行结果有点出人意料,用时偏高 + *

+ * 优化方案二:{@link _03_findRepeatNumber#findRepeatNumber2(int[])} + * + * @param nums + * @return + */ + public int findRepeatNumber(int[] nums) { + HashMap map = new HashMap<>(); + for (int i = 0; i < nums.length; i++) { + int num = nums[i]; + if (map.getOrDefault(num, false)) { + return num; + } + map.put(num, true); + } + + return 0; + } + + /** + * 针对方案一的提交结果,看看哪些地方可以优化 + * 分析可能是HashMao扩容导致的耗时,用同等大小的数组,保存出现次数 + * + * 执行用时:2 ms, 在所有 Java 提交中击败了70.22%的用户 + * 内存消耗:46.9 MB, 在所有 Java 提交中击败了100.00%的用户 + * + * 结果满足要求,印证了HashMap扩容存在耗时 + * + * 最后参考一个最优方案,不需要额外储存空间:{@link _03_findRepeatNumber#findRepeatNumber3(int[])} + * + * @param nums + * @return + */ + public int findRepeatNumber2(int[] nums) { + int[] numCounts = new int[nums.length]; + for (int i = 0; i < nums.length; i++) { + int num = nums[i]; + if (numCounts[num] != 0) { + return num; + } + numCounts[num]++; + } + + return 0; + } + + /** + * 方案三: + * 利用数组本身去存储遍历过程的结果,数组第i位就是i,如果后面的有相应的i,则存在重复元素 + * 此方案前提条件:" 在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内 ",不然数组可能会越界 + * 此方案还有个劣势:修改了原数组 + * + * 执行用时:1 ms, 在所有 Java 提交中击败了91.54%的用户 + * 内存消耗:47.9 MB, 在所有 Java 提交中击败了100.00%的用户 + * @param nums + * @return + */ + public int findRepeatNumber3(int[] nums) { + int i = 0; + while(i < nums.length){ + if(i != nums[i]){ + int tmp = nums[nums[i]]; + if(tmp == nums[i]){ + return tmp; + } + nums[nums[i]] = nums[i]; + nums[i] = tmp; + }else{ + i++; + } + } + + return -1; + + } +} From 2ad0b63990243c84137b0ba38aa3ac91122362a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 28 Jul 2020 11:21:25 +0800 Subject: [PATCH 275/308] docs: add _03_findRepeatNumber --- README.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 032ada9..026b456 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成258道 +- leetcode练习,坚持每天一道,目前已完成259道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -12,7 +12,7 @@ 剑指offer系列-持续多月,每周7题 -- [ ] [数组中重复的数字](https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof) +- [x] [数组中重复的数字](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_03_findRepeatNumber.java) - [ ] [二维数组中的查找](https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof) - [ ] [替换空格](https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof) - [ ] [从尾到头打印链表](https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof) @@ -53,9 +53,19 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成258) +### 题目列表(更新中—已完成259) -[Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1226_DiningPhilosophers.java) +[Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_03_findRepeatNumber.java) + +剑指offer系列 + +| 题目 | 解决方案 | 相关话题 | 难度 | +| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | +| [剑指 Offer 03. 数组中重复的数字](https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/) | [FindRepeatNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_03_findRepeatNumber.java) | [数组]()、[哈希表]() | Easy | +| | | | | +| | | | | + +经典题解 | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | From 6b1ce49210fc9afb469d2974fb3e981f22a5023b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 30 Jul 2020 10:34:26 +0800 Subject: [PATCH 276/308] feat(EASY): add _04_findNumberIn2DArray --- .../offer/_04_findNumberIn2DArray.java | 135 ++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 src/pp/arithmetic/offer/_04_findNumberIn2DArray.java diff --git a/src/pp/arithmetic/offer/_04_findNumberIn2DArray.java b/src/pp/arithmetic/offer/_04_findNumberIn2DArray.java new file mode 100644 index 0000000..d33ab90 --- /dev/null +++ b/src/pp/arithmetic/offer/_04_findNumberIn2DArray.java @@ -0,0 +1,135 @@ +package pp.arithmetic.offer; + +/** + * Created by wangpeng on 2020-07-29. + * 剑指 Offer 04. 二维数组中的查找 + * + * 在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 + * + *   + * + * 示例: + * + * 现有矩阵 matrix 如下: + * + * [ + * [1, 4, 7, 11, 15], + * [2, 5, 8, 12, 19], + * [3, 6, 9, 16, 22], + * [10, 13, 14, 17, 24], + * [18, 21, 23, 26, 30] + * ] + * 给定 target = 5,返回 true。 + * + * 给定 target = 20,返回 false。 + * + *   + * + * 限制: + * + * 0 <= n <= 1000 + * + * 0 <= m <= 1000 + * + *   + * + * 注意:本题与主站 240 题相同:https://leetcode-cn.com/problems/search-a-2d-matrix-ii/ + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _04_findNumberIn2DArray { + + public static void main(String[] args) { + _04_findNumberIn2DArray findNumberIn2DArray = new _04_findNumberIn2DArray(); + int[][] matrix = { + {1,2,3,4,5}, + {6,7,8,9,10}, + {11,12,13,14,15}, + {16,17,18,19,20}, + {21,22,23,24,25} + }; + System.out.println(findNumberIn2DArray.findNumberIn2DArray(matrix,5)); + System.out.println(findNumberIn2DArray.findNumberIn2DArray(matrix,20)); + } + + /** + * 解题思路:一眼看过去,在一个有序的规则里找一个数,第一时间想到的是二分查找,看看能不能找到二分查找的规律,从实例中看 + * + * 1.n*m的数组中,[0,0]=1肯定最小,[n-1,m-1]=30肯定最大,如果target<[0,0] || target>[n-1,m-1]肯定不存在,返回false + * 2.如果target=[0,0] || target=[n-1,m-1],直接返回true + * 3.如果数组大小2*2,则直接返回结果 + * 4.找到数组的中位数[n/2,m/2] = 9 + * 5.target=[n/2,m/2],则直接找到结果,返回true + * 6.target<[n/2,m/2],则可能存在的区域是[0,0]-[n-1,m/2-1]或者[0,m/2]-[n/2-1,m-1]之间(也就是说除了右下角的两块区域),递归 + * 7.target>[n/2,m/2],则可能存在的区域是[n/2+1,0]-[n-1,m-1]或者[0,m/2+1]-[n/2,m-1](也就是说除了左上角的两块区域),递归 + * + * 方法二:利用自身数组的规律求解,详见:{@link _04_findNumberIn2DArray#findNumberIn2DArray2(int[][], int)} + * + * @param matrix + * @param target + * @return + */ + public boolean findNumberIn2DArray(int[][] matrix, int target) { + if (matrix.length == 0) return false; + int n = matrix.length; + int m = matrix[0].length; + return dfs(matrix, target, 0, 0, n - 1, m - 1); + } + + private boolean dfs(int[][] matrix, int target, int sx, int sy, int ex, int ey) { + if (!checkXY(matrix, sx, sy,ex,ey)) return false; + int start = matrix[sx][sy]; + int end = matrix[ex][ey]; + if (target < start || target > end) return false; + int mx = (ex + sx) / 2; + int my = (ey + sy) / 2; + int mid = matrix[mx][my]; + if (target < mid) { + return dfs(matrix, target, sx, sy, ex, my-1) || dfs(matrix, target, sx, my, mx-1, ey) ; + } + if (target > mid) { + return dfs(matrix, target, mx + 1, sy, ex, ey) || dfs(matrix, target, sx, my + 1, mx, ey); + } + return true; + } + + //检查输入参数是否有效 + private boolean checkXY(int[][] matrix, int sx, int sy, int ex, int ey) { + if (sx < 0 || sx > matrix.length - 1) return false; + if (sy < 0 || sy > matrix[0].length - 1) return false; + if (ex < 0 || ex > matrix.length - 1) return false; + if (ey < 0 || ey > matrix[0].length - 1) return false; + if (sx > ex || sy > ey) return false; + return true; + } + + /** + * 方法二:找到数组的右上角,此位置正下方都比他大,正左方都比他小,左下角区域可大可小,以此为起始锚点 + * 1.target>锚点,锚点位置向下移动一行 + * 2.target<锚点,锚点位置向左移动一列 + * 3.target=锚点,返回结果true + * 4.锚点移除列表边线,返回结果false + * @param matrix + * @param target + * @return + */ + public boolean findNumberIn2DArray2(int[][] matrix, int target) { + if (matrix == null || matrix.length == 0) return false; + //选取右上角 + int row = 0; + int col = matrix[0].length - 1; + while (row < matrix.length && col >= 0) { + if (matrix[row][col] == target) { + return true; + } else if (matrix[row][col] > target) { + col--; + } else if (matrix[row][col] < target) { + row++; + } + } + return false; + } + +} From 0be19a8268a492c16a9ebc76fd1961b2597a3fb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 30 Jul 2020 10:37:14 +0800 Subject: [PATCH 277/308] docs: add _04_findNumberIn2DArray --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 026b456..a4d8faa 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成259道 +- leetcode练习,坚持每天一道,目前已完成260道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -13,7 +13,7 @@ 剑指offer系列-持续多月,每周7题 - [x] [数组中重复的数字](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_03_findRepeatNumber.java) -- [ ] [二维数组中的查找](https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof) +- [x] [二维数组中的查找](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_04_findNumberIn2DArray.java) - [ ] [替换空格](https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof) - [ ] [从尾到头打印链表](https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof) - [ ] [重建二叉树](https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof) @@ -53,19 +53,19 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成259) +### 题目列表(更新中—已完成260) -[Leetcode-Java(250+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_03_findRepeatNumber.java) +[Leetcode-Java(260+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_04_findNumberIn2DArray.java) -剑指offer系列 +#### 剑指offer系列 -| 题目 | 解决方案 | 相关话题 | 难度 | -| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | -| [剑指 Offer 03. 数组中重复的数字](https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/) | [FindRepeatNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_03_findRepeatNumber.java) | [数组]()、[哈希表]() | Easy | -| | | | | -| | | | | +| 题目 | 解决方案 | 相关话题 | 难度 | 备注 | +| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | ---- | +| [剑指 Offer 03. 数组中重复的数字](https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/) | [FindRepeatNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_03_findRepeatNumber.java) | [数组]()、[哈希表]() | Easy | | +| [剑指 Offer 04. 二维数组中的查找](https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/) | [FindNumberIn2DArray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_04_findNumberIn2DArray.java) | [数组]()、[双指针]() | Easy | | +| | | | | | -经典题解 +#### 经典题解 | No | 题目 | 解决方案 | 相关话题 | 难度 | 备注 | | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | From 961e224b2bc74619aa2735b66d2b92129a446c6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 30 Jul 2020 11:13:05 +0800 Subject: [PATCH 278/308] feat(EASY): add _05_replaceSpace --- src/pp/arithmetic/offer/_05_replaceSpace.java | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/pp/arithmetic/offer/_05_replaceSpace.java diff --git a/src/pp/arithmetic/offer/_05_replaceSpace.java b/src/pp/arithmetic/offer/_05_replaceSpace.java new file mode 100644 index 0000000..8acd6d5 --- /dev/null +++ b/src/pp/arithmetic/offer/_05_replaceSpace.java @@ -0,0 +1,53 @@ +package pp.arithmetic.offer; + +/** + * Created by wangpeng on 2020-07-30. + * 剑指 Offer 05. 替换空格 + * + * 请实现一个函数,把字符串 s 中的每个空格替换成"%20"。 + * + *   + * + * 示例 1: + * + * 输入:s = "We are happy." + * 输出:"We%20are%20happy." + *   + * + * 限制: + * + * 0 <= s 的长度 <= 10000 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _05_replaceSpace { + + public static void main(String[] args) { + _05_replaceSpace replaceSpace = new _05_replaceSpace(); + System.out.println(replaceSpace.replaceSpace("We are happy.")); + } + + /** + * 解题思路: + * 看到题目最直接的想法就是遍历异常,遇到空格就替换 + * 没有清楚这道题到底想考什么? + * @param s + * @return + */ + public String replaceSpace(String s) { + char[] chars = s.toCharArray(); + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < chars.length; i++) { + char aChar = chars[i]; + if (aChar == ' '){ + builder.append("%20"); + }else{ + builder.append(aChar); + } + } + + return builder.toString(); + } +} From 977a604469b51dc46ee98a8c04d0a2054443c14b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 30 Jul 2020 11:15:51 +0800 Subject: [PATCH 279/308] docs: add _05_replaceSpace --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a4d8faa..e264aca 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成260道 +- leetcode练习,坚持每天一道,目前已完成261道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -14,7 +14,7 @@ - [x] [数组中重复的数字](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_03_findRepeatNumber.java) - [x] [二维数组中的查找](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_04_findNumberIn2DArray.java) -- [ ] [替换空格](https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof) +- [x] [替换空格](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_05_replaceSpace.java) - [ ] [从尾到头打印链表](https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof) - [ ] [重建二叉树](https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof) - [ ] [用两个栈实现队列](https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof) @@ -53,9 +53,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成260) +### 题目列表(更新中—已完成261) -[Leetcode-Java(260+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_04_findNumberIn2DArray.java) +[Leetcode-Java(260+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_05_replaceSpace.java) #### 剑指offer系列 @@ -63,7 +63,7 @@ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | ---- | | [剑指 Offer 03. 数组中重复的数字](https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/) | [FindRepeatNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_03_findRepeatNumber.java) | [数组]()、[哈希表]() | Easy | | | [剑指 Offer 04. 二维数组中的查找](https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/) | [FindNumberIn2DArray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_04_findNumberIn2DArray.java) | [数组]()、[双指针]() | Easy | | -| | | | | | +| [剑指 Offer 05. 替换空格](https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/) | [ReplaceSpace](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_05_replaceSpace.java) | | Easy | | #### 经典题解 @@ -319,7 +319,7 @@ | #1195 | [交替打印字符串](https://leetcode-cn.com/problems/fizz-buzz-multithreaded/) | [FizzBuzz](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1195_FizzBuzz.java) | | Medium | | | #1226 | [哲学家进餐](https://leetcode-cn.com/problems/the-dining-philosophers/) | [DiningPhilosophers](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/leetcode/_1226_DiningPhilosophers.java) | | Medium | | -LCP +#### LCP | No | 题目 | 解决方案 | 难度 | | ---- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | From a06f19ec96c0886980558f706178b23a6b3bb0f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 30 Jul 2020 11:28:44 +0800 Subject: [PATCH 280/308] feat(EASY): add _06_reversePrint --- src/pp/arithmetic/offer/_06_reversePrint.java | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/pp/arithmetic/offer/_06_reversePrint.java diff --git a/src/pp/arithmetic/offer/_06_reversePrint.java b/src/pp/arithmetic/offer/_06_reversePrint.java new file mode 100644 index 0000000..50ea158 --- /dev/null +++ b/src/pp/arithmetic/offer/_06_reversePrint.java @@ -0,0 +1,64 @@ +package pp.arithmetic.offer; + +import pp.arithmetic.Util; +import pp.arithmetic.model.ListNode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wangpeng on 2020-07-30. + * 剑指 Offer 06. 从尾到头打印链表 + * + * 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。 + * + *   + * + * 示例 1: + * + * 输入:head = [1,3,2] + * 输出:[2,3,1] + *   + * + * 限制: + * + * 0 <= 链表长度 <= 10000 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _06_reversePrint { + + public static void main(String[] args) { + ListNode listNode = Util.generateListNodeBySize(10); + Util.printListNode(listNode); + _06_reversePrint reversePrint = new _06_reversePrint(); + int[] arr = reversePrint.reversePrint(listNode); + Util.printArray(arr); + } + + /** + * 解题思路: + * 链表的问题,最直接也只能是遍历+递归,可以借助多指针一起,此题只需要遍历就可以了 + * @param head + * @return + */ + public int[] reversePrint(ListNode head) { + List list = new ArrayList<>(); + dfs(head,list); + int[] retArr = new int[list.size()]; + for (int i = 0; i < list.size(); i++) { + retArr[i] = list.get(i); + } + return retArr; + } + + private void dfs(ListNode node,List list){ + if (node == null){ + return; + } + dfs(node.next,list); + list.add(node.val); + } +} From 589eb8fadbb4216d2058937e193a148bb047a342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 30 Jul 2020 11:35:50 +0800 Subject: [PATCH 281/308] docs: add _06_reversePrint --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e264aca..4b53ec0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成261道 +- leetcode练习,坚持每天一道,目前已完成262道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -15,7 +15,7 @@ - [x] [数组中重复的数字](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_03_findRepeatNumber.java) - [x] [二维数组中的查找](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_04_findNumberIn2DArray.java) - [x] [替换空格](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_05_replaceSpace.java) -- [ ] [从尾到头打印链表](https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof) +- [x] [从尾到头打印链表]([_06_reversePrint.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_06_reversePrint.java)) - [ ] [重建二叉树](https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof) - [ ] [用两个栈实现队列](https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof) - [ ] [斐波那契数列](https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof) @@ -53,9 +53,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成261) +### 题目列表(更新中—已完成262) -[Leetcode-Java(260+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_05_replaceSpace.java) +[Leetcode-Java(260+题解,持续更新、欢迎star&留言&交流)]([_06_reversePrint.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_06_reversePrint.java)) #### 剑指offer系列 @@ -64,6 +64,7 @@ | [剑指 Offer 03. 数组中重复的数字](https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/) | [FindRepeatNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_03_findRepeatNumber.java) | [数组]()、[哈希表]() | Easy | | | [剑指 Offer 04. 二维数组中的查找](https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/) | [FindNumberIn2DArray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_04_findNumberIn2DArray.java) | [数组]()、[双指针]() | Easy | | | [剑指 Offer 05. 替换空格](https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/) | [ReplaceSpace](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_05_replaceSpace.java) | | Easy | | +| [剑指 Offer 06. 从尾到头打印链表](https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/) | [ReversePrint](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_06_reversePrint.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Easy | | #### 经典题解 From 73c680b19c3d2e5c5cc8d3001389021bf42b2caf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 4 Aug 2020 10:57:28 +0800 Subject: [PATCH 282/308] feat(MEDIUM): add _07_buildTree --- src/pp/arithmetic/offer/_07_buildTree.java | 103 +++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 src/pp/arithmetic/offer/_07_buildTree.java diff --git a/src/pp/arithmetic/offer/_07_buildTree.java b/src/pp/arithmetic/offer/_07_buildTree.java new file mode 100644 index 0000000..6c03b4c --- /dev/null +++ b/src/pp/arithmetic/offer/_07_buildTree.java @@ -0,0 +1,103 @@ +package pp.arithmetic.offer; + +import pp.arithmetic.Util; +import pp.arithmetic.model.TreeNode; + +/** + * Created by wangpeng on 2020-08-04. + * + * 剑指 Offer 07. 重建二叉树 + * + * 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 + * + *   + * + * 例如,给出 + * + * 前序遍历 preorder = [3,9,20,15,7] + * 中序遍历 inorder = [9,3,15,20,7] + * 返回如下的二叉树: + * + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + *   + * + * 限制: + * + * 0 <= 节点个数 <= 5000 + * + *   + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _07_buildTree { + + public static void main(String[] args) { + _07_buildTree buildTree = new _07_buildTree(); + int[] preorder = {3, 9, 20, 15, 7}; + int[] inorder = {9,3,15,20,7}; + TreeNode treeNode = buildTree.buildTree(preorder, inorder); + Util.printTree(treeNode); + } + + /** + * 解题思路: + * 1、知道前序遍历,首位就是根节点 + * 2、由于不存在重复数字,根据根节点找到中序遍历的位置I,I前就是左子树的中序,I后就是右子树的中序 + * 3、在前序数组中,根据左右子树中序的长度,能找到左右子树对应的前序遍历数组 + * 4、循环1-3,得到左右子树的对应的前序&中序数组,最终得到构建的树 + * + * 优化建议:得到左右子树对应的数组的时候,有两种方案: + * 一、拷贝新数组 + * 二、原数组上理由index指针获取结果(性能和效率都更高) + * + * 本题解基于方案二 + * + * @param preorder + * @param inorder + * @return + */ + public TreeNode buildTree(int[] preorder, int[] inorder) { + if (preorder.length == 0) return null; + return dfs(preorder.length,preorder,0,inorder,0); + } + + // 从前序和中序构造二叉树,前序和中序是大数组中的一段[start, start + count) + private TreeNode dfs(int count, int[] preOrder, int preStart, int[] inOrder, int inStart) { + if (count <= 0) return null; + + int rootValue = preOrder[preStart]; + TreeNode root = new TreeNode(rootValue); + + // 从inorder中找到root值,(inorder)左边就是左子树,(inorder)右边就是右子树 + // 然后在preorder中,数出与inorder中相同的个数即可 + int pos = inStart + count - 1; + for (; pos >= inStart; --pos) { + if (inOrder[pos] == rootValue) { + break; + } + } + int leftCount = pos - inStart; + int rightCount = inStart + count - pos - 1; + + if (leftCount > 0) { + int leftInStart = inStart; + int leftPreStart = preStart + 1; + root.left = dfs(leftCount, preOrder, leftPreStart, inOrder, leftInStart); + } + + if (rightCount > 0) { + int rightInStart = pos + 1; + int rightPreStart = preStart + 1 + leftCount; + root.right = dfs(rightCount, preOrder, rightPreStart, inOrder, rightInStart); + } + + return root; + } + +} From 0ca0a528e55cb7fc252378c60462fc2a7455eaf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 4 Aug 2020 10:59:30 +0800 Subject: [PATCH 283/308] docs: add _07_buildTree --- README.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 4b53ec0..3bcf95f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成262道 +- leetcode练习,坚持每天一道,目前已完成263道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -15,8 +15,8 @@ - [x] [数组中重复的数字](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_03_findRepeatNumber.java) - [x] [二维数组中的查找](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_04_findNumberIn2DArray.java) - [x] [替换空格](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_05_replaceSpace.java) -- [x] [从尾到头打印链表]([_06_reversePrint.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_06_reversePrint.java)) -- [ ] [重建二叉树](https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof) +- [x] [从尾到头打印链表](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_06_reversePrint.java) +- [x] [重建二叉树](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_07_buildTree.java) - [ ] [用两个栈实现队列](https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof) - [ ] [斐波那契数列](https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof) @@ -53,18 +53,19 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成262) +### 题目列表(更新中—已完成263) -[Leetcode-Java(260+题解,持续更新、欢迎star&留言&交流)]([_06_reversePrint.java](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_06_reversePrint.java)) +[Leetcode-Java(260+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_07_buildTree.java) #### 剑指offer系列 -| 题目 | 解决方案 | 相关话题 | 难度 | 备注 | -| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | ---- | -| [剑指 Offer 03. 数组中重复的数字](https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/) | [FindRepeatNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_03_findRepeatNumber.java) | [数组]()、[哈希表]() | Easy | | -| [剑指 Offer 04. 二维数组中的查找](https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/) | [FindNumberIn2DArray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_04_findNumberIn2DArray.java) | [数组]()、[双指针]() | Easy | | -| [剑指 Offer 05. 替换空格](https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/) | [ReplaceSpace](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_05_replaceSpace.java) | | Easy | | -| [剑指 Offer 06. 从尾到头打印链表](https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/) | [ReversePrint](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_06_reversePrint.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Easy | | +| 题目 | 解决方案 | 相关话题 | 难度 | 备注 | +| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ---- | +| [剑指 Offer 03. 数组中重复的数字](https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/) | [FindRepeatNumber](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_03_findRepeatNumber.java) | [数组]()、[哈希表]() | Easy | | +| [剑指 Offer 04. 二维数组中的查找](https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/) | [FindNumberIn2DArray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_04_findNumberIn2DArray.java) | [数组]()、[双指针]() | Easy | | +| [剑指 Offer 05. 替换空格](https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/) | [ReplaceSpace](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_05_replaceSpace.java) | | Easy | | +| [剑指 Offer 06. 从尾到头打印链表](https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/) | [ReversePrint](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_06_reversePrint.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Easy | | +| [剑指 Offer 07. 重建二叉树](https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/) | [BuildTree](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_07_buildTree.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | #### 经典题解 From ab5b84be2f0d257742b1d8541aa3ee3e47014c0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 4 Aug 2020 17:08:14 +0800 Subject: [PATCH 284/308] feat(EASY): add _09_CQueue --- src/pp/arithmetic/offer/_09_CQueue.java | 118 ++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 src/pp/arithmetic/offer/_09_CQueue.java diff --git a/src/pp/arithmetic/offer/_09_CQueue.java b/src/pp/arithmetic/offer/_09_CQueue.java new file mode 100644 index 0000000..b8406a3 --- /dev/null +++ b/src/pp/arithmetic/offer/_09_CQueue.java @@ -0,0 +1,118 @@ +package pp.arithmetic.offer; + +import java.util.Stack; + +/** + * Created by wangpeng on 2020-08-04. + * + * 剑指 Offer 09. 用两个栈实现队列 + * + * 用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 ) + * + *   + * + * 示例 1: + * + * 输入: + * ["CQueue","appendTail","deleteHead","deleteHead"] + * [[],[3],[],[]] + * 输出:[null,null,3,-1] + * 示例 2: + * + * 输入: + * ["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"] + * [[],[],[5],[2],[],[]] + * 输出:[null,-1,null,null,5,2] + * 提示: + * + * 1 <= values <= 10000 + * 最多会对 appendTail、deleteHead 进行 10000 次调用 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _09_CQueue { + + public static void main(String[] args) { + CQueue cQueue = new CQueue(); + System.out.println(cQueue.deleteHead()); + cQueue.appendTail(5); + cQueue.appendTail(2); + System.out.println(cQueue.deleteHead()); + System.out.println(cQueue.deleteHead()); + } + + /** + * 解题思路: + * 一个栈用于储存,另一个用于删除时候暂存数据 + * + * 提交结果: + * 执行用时:416 ms, 在所有 Java 提交中击败了5.06%的用户 + * 内存消耗:48.5 MB, 在所有 Java 提交中击败了32.71%的用户 + * + * delete操作存在十分频繁的数据移动操作,待优化{@link CQueue2} + */ + static class CQueue { + + Stack add; + Stack stash; + + public CQueue() { + add = new Stack(); + stash = new Stack(); + } + + public void appendTail(int value) { + add.push(value); + } + + public int deleteHead() { + int retVal = -1; + while (!add.isEmpty()){ + retVal = add.pop(); + stash.push(retVal); + } + //将删除的val剔除掉 + if (!stash.isEmpty()) { + stash.pop(); + } + while (!stash.isEmpty()){ + add.push(stash.pop()); + } + + return retVal; + } + } + + /** + * 优化思路: + * 1.stash用来delete操作,当stash为空的时候,才将add中的数据同步过去 + */ + static class CQueue2 { + + Stack add; + Stack stash; + + public CQueue2() { + add = new Stack(); + stash = new Stack(); + } + + public void appendTail(int value) { + add.push(value); + } + + public int deleteHead() { + if (stash.isEmpty()){ + if (add.isEmpty()) return -1; + while (!add.isEmpty()){ + stash.push(add.pop()); + } + return stash.pop(); + }else{ + return stash.pop(); + } + } + } +} From ed6c643217344f411ff5d909a744b09af8be9838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 4 Aug 2020 17:10:23 +0800 Subject: [PATCH 285/308] docs: add _09_CQueue --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3bcf95f..30bb0e2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成263道 +- leetcode练习,坚持每天一道,目前已完成264道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -17,7 +17,7 @@ - [x] [替换空格](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_05_replaceSpace.java) - [x] [从尾到头打印链表](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_06_reversePrint.java) - [x] [重建二叉树](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_07_buildTree.java) -- [ ] [用两个栈实现队列](https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof) +- [x] [用两个栈实现队列](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_09_CQueue.java) - [ ] [斐波那契数列](https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof) ## 已解题目 @@ -53,9 +53,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成263) +### 题目列表(更新中—已完成264) -[Leetcode-Java(260+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_07_buildTree.java) +[Leetcode-Java(260+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_09_CQueue.java) #### 剑指offer系列 @@ -66,6 +66,7 @@ | [剑指 Offer 05. 替换空格](https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/) | [ReplaceSpace](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_05_replaceSpace.java) | | Easy | | | [剑指 Offer 06. 从尾到头打印链表](https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/) | [ReversePrint](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_06_reversePrint.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Easy | | | [剑指 Offer 07. 重建二叉树](https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/) | [BuildTree](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_07_buildTree.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | +| [剑指 Offer 09. 用两个栈实现队列](https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/) | [CQueue](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_09_CQueue.java) | [栈](https://leetcode-cn.com/tag/stack/)、[设计](https://leetcode-cn.com/tag/design/) | Easy | | #### 经典题解 From 6b99872a0a4cea66699ea0cf0a91220715c7accd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 4 Aug 2020 17:34:04 +0800 Subject: [PATCH 286/308] feat(EASY): add _10_fib --- src/pp/arithmetic/offer/_10_fib.java | 65 ++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/pp/arithmetic/offer/_10_fib.java diff --git a/src/pp/arithmetic/offer/_10_fib.java b/src/pp/arithmetic/offer/_10_fib.java new file mode 100644 index 0000000..406f9b0 --- /dev/null +++ b/src/pp/arithmetic/offer/_10_fib.java @@ -0,0 +1,65 @@ +package pp.arithmetic.offer; + +/** + * Created by wangpeng on 2020-08-04. + * + * 剑指 Offer 10- I. 斐波那契数列 + * + * 写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项。斐波那契数列的定义如下: + * + * F(0) = 0,   F(1) = 1 + * F(N) = F(N - 1) + F(N - 2), 其中 N > 1. + * 斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。 + * + * 答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。 + * + *   + * + * 示例 1: + * + * 输入:n = 2 + * 输出:1 + * 示例 2: + * + * 输入:n = 5 + * 输出:5 + *   + * + * 提示: + * + * 0 <= n <= 100 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _10_fib { + + public static void main(String[] args) { + _10_fib fib = new _10_fib(); + System.out.println(fib.fib(2)); + System.out.println(fib.fib(5)); + System.out.println(fib.fib(100)); + } + + /** + * 解题思路: + * 有两个方案: + * 一、是从n开始递归求解f(n)=f(n-1)+f(n-2),这种递归效率较低,当n比较大时候存在大量重复的计算 + * 二、从0开始计算,存储下每次计算的结果,逐步计算到n,借助动态规划 + * + * @param n + * @return + */ + public int fib(int n) { + if (n == 0) return 0; + if (n == 1) return 1; + int[] dp = new int[n+1]; + dp[0] = 0; + dp[1] = 1; + for (int i = 2; i <= n; i++) { + dp[i] = (dp[i-1]+dp[i-2])%1000000007; + } + return dp[n]; + } +} From 3895fb77bb141fb0fc72dc1df9d99e9560045861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 4 Aug 2020 17:44:38 +0800 Subject: [PATCH 287/308] docs: add _10_fib --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 30bb0e2..3b52e59 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成264道 +- leetcode练习,坚持每天一道,目前已完成265道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -18,7 +18,7 @@ - [x] [从尾到头打印链表](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_06_reversePrint.java) - [x] [重建二叉树](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_07_buildTree.java) - [x] [用两个栈实现队列](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_09_CQueue.java) -- [ ] [斐波那契数列](https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof) +- [x] [斐波那契数列](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_10_fib.java) ## 已解题目 @@ -53,9 +53,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成264) +### 题目列表(更新中—已完成265) -[Leetcode-Java(260+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_09_CQueue.java) +[Leetcode-Java(260+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_10_fib.java) #### 剑指offer系列 @@ -67,6 +67,7 @@ | [剑指 Offer 06. 从尾到头打印链表](https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/) | [ReversePrint](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_06_reversePrint.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Easy | | | [剑指 Offer 07. 重建二叉树](https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/) | [BuildTree](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_07_buildTree.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | [剑指 Offer 09. 用两个栈实现队列](https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/) | [CQueue](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_09_CQueue.java) | [栈](https://leetcode-cn.com/tag/stack/)、[设计](https://leetcode-cn.com/tag/design/) | Easy | | +| [剑指 Offer 10- I. 斐波那契数列](https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof/) | [Fib](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_10_fib.java) | | Easy | | #### 经典题解 From a393cd0cee5a707c28f300af6815cea5e2726843 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 5 Aug 2020 11:05:48 +0800 Subject: [PATCH 288/308] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E9=A2=98?= =?UTF-8?q?=E7=9B=AE=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 3b52e59..adba758 100644 --- a/README.md +++ b/README.md @@ -10,15 +10,21 @@ - 网址:https://leetcode-cn.com/ ## 待解题目列表 -剑指offer系列-持续多月,每周7题 +剑指offer系列-持续多周,每周7题 -- [x] [数组中重复的数字](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_03_findRepeatNumber.java) -- [x] [二维数组中的查找](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_04_findNumberIn2DArray.java) -- [x] [替换空格](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_05_replaceSpace.java) -- [x] [从尾到头打印链表](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_06_reversePrint.java) -- [x] [重建二叉树](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_07_buildTree.java) -- [x] [用两个栈实现队列](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_09_CQueue.java) -- [x] [斐波那契数列](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_10_fib.java) +- [ ] [剑指 Offer 10- II. 青蛙跳台阶问题](https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof/) + +- [ ] [剑指 Offer 11. 旋转数组的最小数字](https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/) + +- [ ] [剑指 Offer 12. 矩阵中的路径](https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/) + +- [ ] [剑指 Offer 13. 机器人的运动范围](https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/) + +- [ ] [剑指 Offer 14- I. 剪绳子](https://leetcode-cn.com/problems/jian-sheng-zi-lcof/) + +- [ ] [剑指 Offer 14- II. ](https://leetcode-cn.com/problems/jian-sheng-zi-ii-lcof/) + +- [ ] [剑指 Offer 15. 二进制中1的个数](https://leetcode-cn.com/problems/er-jin-zhi-zhong-1de-ge-shu-lcof/) ## 已解题目 From 7f0fc475823ec1d5756dbab6d85c8735c1db0628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 5 Aug 2020 11:57:39 +0800 Subject: [PATCH 289/308] feat(EASY): add _10_2_numWays --- src/pp/arithmetic/offer/_10_2_numWays.java | 65 ++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/pp/arithmetic/offer/_10_2_numWays.java diff --git a/src/pp/arithmetic/offer/_10_2_numWays.java b/src/pp/arithmetic/offer/_10_2_numWays.java new file mode 100644 index 0000000..f3cf657 --- /dev/null +++ b/src/pp/arithmetic/offer/_10_2_numWays.java @@ -0,0 +1,65 @@ +package pp.arithmetic.offer; + +/** + * Created by wangpeng on 2020-08-05. + * + * 剑指 Offer 10- II. 青蛙跳台阶问题 + * + * + * 一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。 + * + * 答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。 + * + * 示例 1: + * + * 输入:n = 2 + * 输出:2 + * 示例 2: + * + * 输入:n = 7 + * 输出:21 + * 示例 3: + * + * 输入:n = 0 + * 输出:1 + * 提示: + * + * 0 <= n <= 100 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _10_2_numWays { + + public static void main(String[] args) { + _10_2_numWays numWays = new _10_2_numWays(); + System.out.println(numWays.numWays(2)); + System.out.println(numWays.numWays(3)); + System.out.println(numWays.numWays(4)); + System.out.println(numWays.numWays(5)); + System.out.println(numWays.numWays(6)); + System.out.println(numWays.numWays(40)); + } + + /** + * 解题思路:借鉴动态规划思路 + * 1.dp[0]=1,dp[1]=1,d[2]=dp[0]+d[1] + * 2.dp[n]=dp[n-1]+dp[n-2] + * + * @param n + * @return + */ + public int numWays(int n) { + if (n == 0) return 1; + if (n == 1) return 1; + int[] dp = new int[n+1]; + dp[0] = 1; + dp[1] = 1; + for (int i = 2; i <= n; i++) { + dp[i] = (dp[i-1]+dp[i-2])%1000000007; + } + + return dp[n]; + } +} From ceb914a859ad91dcd347958e42f08b185328c4c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 5 Aug 2020 11:59:32 +0800 Subject: [PATCH 290/308] docs: add _10_2_numWays --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index adba758..d18e73b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成265道 +- leetcode练习,坚持每天一道,目前已完成266道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -12,7 +12,7 @@ 剑指offer系列-持续多周,每周7题 -- [ ] [剑指 Offer 10- II. 青蛙跳台阶问题](https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof/) +- [x] [剑指 Offer 10- II. 青蛙跳台阶问题](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_10_2_numWays.java) - [ ] [剑指 Offer 11. 旋转数组的最小数字](https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成265) +### 题目列表(更新中—已完成266) -[Leetcode-Java(260+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_10_fib.java) +[Leetcode-Java(260+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_10_2_numWays.java) #### 剑指offer系列 @@ -74,6 +74,7 @@ | [剑指 Offer 07. 重建二叉树](https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/) | [BuildTree](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_07_buildTree.java) | [树](https://leetcode-cn.com/tag/tree/)、[DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | [剑指 Offer 09. 用两个栈实现队列](https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/) | [CQueue](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_09_CQueue.java) | [栈](https://leetcode-cn.com/tag/stack/)、[设计](https://leetcode-cn.com/tag/design/) | Easy | | | [剑指 Offer 10- I. 斐波那契数列](https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof/) | [Fib](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_10_fib.java) | | Easy | | +| [剑指 Offer 10- II. 青蛙跳台阶问题](https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof/) | [NumWays](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_10_2_numWays.java) | | Easy | | #### 经典题解 From f8e0843ceb81a5b1475a669363eea3b4f676c85a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 5 Aug 2020 14:57:06 +0800 Subject: [PATCH 291/308] feat(EASY): add _11_minArray --- src/pp/arithmetic/offer/_11_minArray.java | 52 +++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/pp/arithmetic/offer/_11_minArray.java diff --git a/src/pp/arithmetic/offer/_11_minArray.java b/src/pp/arithmetic/offer/_11_minArray.java new file mode 100644 index 0000000..b0795f6 --- /dev/null +++ b/src/pp/arithmetic/offer/_11_minArray.java @@ -0,0 +1,52 @@ +package pp.arithmetic.offer; + +/** + * Created by wangpeng on 2020-08-05. + * + * + * 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。   + * + * 示例 1: + * + * 输入:[3,4,5,1,2] + * 输出:1 + * 示例 2: + * + * 输入:[2,2,2,0,1] + * 输出:0 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _11_minArray { + + public static void main(String[] args) { + _11_minArray minArray = new _11_minArray(); + System.out.println(minArray.minArray(new int[]{3,4,5,1,2})); + System.out.println(minArray.minArray(new int[]{2,2,2,0,1})); + } + + /** + * 解题思路: + * 递增数组经过一次旋转,从递增到递减的转折点,则是最小的 + * @param numbers + * @return + */ + public int minArray(int[] numbers) { + if (numbers == null || numbers.length == 0) return 0; + int retVal = numbers[0]; + int preVal = numbers[0]; + for (int i = 1; i < numbers.length; i++) { + int number = numbers[i]; + if (number >= preVal){ + preVal = number; + }else{ + retVal = number; + break; + } + } + + return retVal; + } +} From a11a20cc20430e2ecea6e451cb4a941e457d2373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 5 Aug 2020 14:59:24 +0800 Subject: [PATCH 292/308] docs: add _11_minArray --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d18e73b..cb52d10 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成266道 +- leetcode练习,坚持每天一道,目前已完成267道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -14,7 +14,7 @@ - [x] [剑指 Offer 10- II. 青蛙跳台阶问题](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_10_2_numWays.java) -- [ ] [剑指 Offer 11. 旋转数组的最小数字](https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/) +- [x] [剑指 Offer 11. 旋转数组的最小数字](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_11_minArray.java) - [ ] [剑指 Offer 12. 矩阵中的路径](https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成266) +### 题目列表(更新中—已完成267) -[Leetcode-Java(260+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_10_2_numWays.java) +[Leetcode-Java(260+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_11_minArray.java) #### 剑指offer系列 @@ -75,6 +75,7 @@ | [剑指 Offer 09. 用两个栈实现队列](https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/) | [CQueue](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_09_CQueue.java) | [栈](https://leetcode-cn.com/tag/stack/)、[设计](https://leetcode-cn.com/tag/design/) | Easy | | | [剑指 Offer 10- I. 斐波那契数列](https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof/) | [Fib](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_10_fib.java) | | Easy | | | [剑指 Offer 10- II. 青蛙跳台阶问题](https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof/) | [NumWays](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_10_2_numWays.java) | | Easy | | +| [剑指 Offer 11. 旋转数组的最小数字](https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/) | [MinArray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_11_minArray.java) | [二分查找]() | Easy | | #### 经典题解 From 5e8af9e3888e0e44212f51ca0e318e896ff5d405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 6 Aug 2020 19:15:38 +0800 Subject: [PATCH 293/308] feat(MEDIUM): add _12_exist --- src/pp/arithmetic/offer/_12_exist.java | 105 +++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 src/pp/arithmetic/offer/_12_exist.java diff --git a/src/pp/arithmetic/offer/_12_exist.java b/src/pp/arithmetic/offer/_12_exist.java new file mode 100644 index 0000000..503e369 --- /dev/null +++ b/src/pp/arithmetic/offer/_12_exist.java @@ -0,0 +1,105 @@ +package pp.arithmetic.offer; + +/** + * Created by wangpeng on 2020-08-05. + *

+ * 剑指 Offer 12. 矩阵中的路径 + *

+ * 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。 + * 如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用加粗标出)。 + *

+ * [["a","b","c","e"], + * ["s","f","c","s"], + * ["a","d","e","e"]] + *

+ * 但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。 + *

+ *   + *

+ * 示例 1: + *

+ * 输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED" + * 输出:true + * 示例 2: + *

+ * 输入:board = [["a","b"],["c","d"]], word = "abcd" + * 输出:false + * 提示: + *

+ * 1 <= board.length <= 200 + * 1 <= board[i].length <= 200 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _12_exist { + + public static void main(String[] args) { + _12_exist exist = new _12_exist(); +// char[][] board = new char[][]{ +// {'A', 'B', 'C', 'E'}, +// {'S', 'F', 'C', 'S'}, +// {'A', 'D', 'E', 'E'} +// }; +// System.out.println(exist.exist(board,"ABFACED")); +// System.out.println(exist.exist(new char[][]{ +// {'a','b'}, +// {'c','d'} +// },"abcd")); + System.out.println(exist.exist(new char[][]{ + {'C','A','A'}, + {'A','A','A'}, + {'B','C','D'} + },"AAB")); + } + + /** + * 解题思路: + * 从board的[0,0]开始向上、左、下、右进行深度遍历,逐步去匹配word中的字符,新建个history保存遍历路径,防止死循环 + * + * @param board + * @param word + * @return + */ + public boolean exist(char[][] board, String word) { + if (board == null || board.length == 0) return false; + int[][] history = new int[board.length][board[0].length]; + return dfs(board, word, history, 0, 0, 0); + } + + private boolean dfs(char[][] board, String word, int[][] history, int wi, int nx, int ny) { + if (wi >= word.length()) { + //word遍历结束才返回true + return true; + } + //遍历越界 + if (nx < 0 || nx >= board.length || ny < 0 || ny >= board[nx].length) return false; + //之前走过这个位置 + if (history[nx][ny] == 1) return false; + if (board[nx][ny] == word.charAt(wi)) { + history[nx][ny] = 1; + if (dfs(board, word, history, wi + 1, nx, ny + 1) + || dfs(board, word, history, wi + 1, nx + 1, ny) + || dfs(board, word, history, wi + 1, nx, ny - 1) + || dfs(board, word, history, wi + 1, nx - 1, ny)) { + return true; + } + history[nx][ny] = 0; + } + if (wi == 0) { + //定位首个字符的标识位 + if (nx < board.length - 1) { + if (dfs(board, word, history, wi, nx + 1, ny)) { + return true; + } + } else if (ny < board[0].length - 1) { + if (dfs(board, word, history, wi, 0, ny + 1)) { + return true; + } + } + } + return false; + } + +} From a1231403e5fdd981085c34b11cdf4230ef957ba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 6 Aug 2020 19:18:10 +0800 Subject: [PATCH 294/308] docs: add _12_exist --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cb52d10..5835612 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成267道 +- leetcode练习,坚持每天一道,目前已完成268道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -16,7 +16,7 @@ - [x] [剑指 Offer 11. 旋转数组的最小数字](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_11_minArray.java) -- [ ] [剑指 Offer 12. 矩阵中的路径](https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/) +- [x] [剑指 Offer 12. 矩阵中的路径](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_12_exist.java) - [ ] [剑指 Offer 13. 机器人的运动范围](https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成267) +### 题目列表(更新中—已完成268) -[Leetcode-Java(260+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_11_minArray.java) +[Leetcode-Java(260+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_12_exist.java) #### 剑指offer系列 @@ -76,6 +76,7 @@ | [剑指 Offer 10- I. 斐波那契数列](https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof/) | [Fib](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_10_fib.java) | | Easy | | | [剑指 Offer 10- II. 青蛙跳台阶问题](https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof/) | [NumWays](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_10_2_numWays.java) | | Easy | | | [剑指 Offer 11. 旋转数组的最小数字](https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/) | [MinArray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_11_minArray.java) | [二分查找]() | Easy | | +| [剑指 Offer 12. 矩阵中的路径](https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/) | [Exist](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_12_exist.java) | [DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | #### 经典题解 From 03a5663615bcb270e8d19ce90fb2cb21df72a2af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 7 Aug 2020 11:03:55 +0800 Subject: [PATCH 295/308] feat(MEDIUM): add _13_movingCount --- src/pp/arithmetic/offer/_13_movingCount.java | 83 ++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/pp/arithmetic/offer/_13_movingCount.java diff --git a/src/pp/arithmetic/offer/_13_movingCount.java b/src/pp/arithmetic/offer/_13_movingCount.java new file mode 100644 index 0000000..e89db86 --- /dev/null +++ b/src/pp/arithmetic/offer/_13_movingCount.java @@ -0,0 +1,83 @@ +package pp.arithmetic.offer; + +/** + * Created by wangpeng on 2020-08-06. + *

+ * 剑指 Offer 13. 机器人的运动范围 + *

+ * 地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外), + * 也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子? + *

+ *   + *

+ * 示例 1: + *

+ * 输入:m = 2, n = 3, k = 1 + * 输出:3 + * 示例 2: + *

+ * 输入:m = 3, n = 1, k = 0 + * 输出:1 + * 提示: + *

+ * 1 <= n,m <= 100 + * 0 <= k <= 20 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _13_movingCount { + + public static void main(String[] args) { + _13_movingCount movingCount = new _13_movingCount(); + System.out.println(movingCount.movingCount(2,3,1)); + System.out.println(movingCount.movingCount(3,1,0)); + System.out.println(movingCount.movingCount(1,2,1)); + System.out.println(movingCount.movingCount(10,10,2)); + System.out.println(movingCount.movingCount(16,8,4)); + } + + private int retVal = 0; + + /** + * 解题思路: + * 使用int[m][n]大小的数组保存行进记录,上下左右进行DFS,不满足条件的跳过 + * 需要注意的可能中间某些行和列相加也满足条件,所以需要整个行和列都需要遍历完(不需要考虑,题中是从0,0开始的) + * + * @param m + * @param n + * @param k + * @return + */ + public int movingCount(int m, int n, int k) { + if (k < 0 || m <=0 || n<=0) return 0; + retVal = 0; + int[][] history = new int[m][n]; + dfs(0,0,m,n,k,history); + return retVal; + } + + private void dfs(int cx, int cy, int m, int n, int k, int[][] history) { + if (cx < 0 || cx >= m || cy < 0 || cy >= n) return; + if (add(cx, cy) > k) return; + if (history[cx][cy] == 1) return; + history[cx][cy] = 1; + retVal++; + dfs(cx, cy + 1, m, n, k, history); + dfs(cx + 1, cy, m, n, k, history); + dfs(cx, cy - 1, m, n, k, history); + dfs(cx - 1, cy, m, n, k, history); + } + + private int add(int x, int y) { + int retVal = 0; + retVal += x / 100; + retVal += (x - x / 100 * 100) / 10; + retVal += x - x / 100 * 100 - (x - x / 100 * 100) / 10 * 10; + retVal += y / 100; + retVal += (y - y / 100 * 100) / 10; + retVal += y - y / 100 * 100 - (y - y / 100 * 100) / 10 * 10; + return retVal; + } +} From c37b9e4d135c57a0d4add08b2c951516d3261712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 7 Aug 2020 11:06:26 +0800 Subject: [PATCH 296/308] docs: add _13_movingCount --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5835612..84df919 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成268道 +- leetcode练习,坚持每天一道,目前已完成269道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -18,7 +18,7 @@ - [x] [剑指 Offer 12. 矩阵中的路径](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_12_exist.java) -- [ ] [剑指 Offer 13. 机器人的运动范围](https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/) +- [x] [剑指 Offer 13. 机器人的运动范围](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_13_movingCount.java) - [ ] [剑指 Offer 14- I. 剪绳子](https://leetcode-cn.com/problems/jian-sheng-zi-lcof/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成268) +### 题目列表(更新中—已完成269) -[Leetcode-Java(260+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_12_exist.java) +[Leetcode-Java(260+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_13_movingCount.java) #### 剑指offer系列 @@ -77,6 +77,7 @@ | [剑指 Offer 10- II. 青蛙跳台阶问题](https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof/) | [NumWays](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_10_2_numWays.java) | | Easy | | | [剑指 Offer 11. 旋转数组的最小数字](https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/) | [MinArray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_11_minArray.java) | [二分查找]() | Easy | | | [剑指 Offer 12. 矩阵中的路径](https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/) | [Exist](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_12_exist.java) | [DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | +| [剑指 Offer 13. 机器人的运动范围](https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/) | [MovingCount](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_13_movingCount.java) | | | | #### 经典题解 From df58bba21a29dfca650cf89b205c6183d94a7cc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 7 Aug 2020 11:28:06 +0800 Subject: [PATCH 297/308] feat(MEDIUM): add _14_1_cuttingRope --- .../arithmetic/offer/_14_1_cuttingRope.java | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/pp/arithmetic/offer/_14_1_cuttingRope.java diff --git a/src/pp/arithmetic/offer/_14_1_cuttingRope.java b/src/pp/arithmetic/offer/_14_1_cuttingRope.java new file mode 100644 index 0000000..939abcc --- /dev/null +++ b/src/pp/arithmetic/offer/_14_1_cuttingRope.java @@ -0,0 +1,68 @@ +package pp.arithmetic.offer; + +/** + * Created by wangpeng on 2020-08-07. + * + * 剑指 Offer 14- I. 剪绳子 + * + * 给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]...k[m-1] 。请问 k[0]*k[1]*...*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。 + * + * 示例 1: + * + * 输入: 2 + * 输出: 1 + * 解释: 2 = 1 + 1, 1 × 1 = 1 + * 示例 2: + * + * 输入: 10 + * 输出: 36 + * 解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36 + * 提示: + * + * 2 <= n <= 58 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/jian-sheng-zi-lcof + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _14_1_cuttingRope { + + public static void main(String[] args) { + _14_1_cuttingRope cuttingRope = new _14_1_cuttingRope(); + System.out.println(cuttingRope.cuttingRope(8)); + System.out.println(cuttingRope.cuttingRope(10)); + System.out.println(cuttingRope.cuttingRope(14)); + System.out.println(cuttingRope.cuttingRope(58)); + } + + /** + * 解题思路: + * 手动模拟了从2-10的最大乘积数字拆解,发现了一个现象: + * 对于数字n,n一直除以2到1为止,得到的数字就是最大的乘积,举例如下: + * 数字n 2 3 4 5 6 7 8 9 10 + * 乘积 1,1 1,2 2,2 2,3 3,3 3,4(2,2) 4(2,2),4(2,2) 4,5(2,3) 5(2,3),5(2,3) + * 发现到了后面的最大乘积可以利用之前的计算好的结果,从而得出动态规划转移方程 + * dp[i]=dp[i/2]*dp[i-i/2](i>3) + * 上面有问题,例如8的最大值不是除以2得到4*4=16,而是3*2*3=18,所以得双重循环取所有情况的最大值 + * for (int j = 1; j <= i / 2; j++) { + * dp[i] = Math.max(dp[i], dp[j] * dp[i - j]); + * } + * + * @param n + * @return + */ + public int cuttingRope(int n) { + if (n <= 3) return n - 1; + int[] dp = new int[n + 1]; + //初始化,1,2,3特殊处理 + dp[1] = 1; + dp[2] = 2; + dp[3] = 3; + for (int i = 4; i <= n; i++) { + for (int j = 1; j <= i / 2; j++) { + dp[i] = Math.max(dp[i], dp[j] * dp[i - j]); + } + } + return dp[n]; + } +} From 34cc44486f8d414a329041a5f4bbe138ec1025ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Fri, 7 Aug 2020 11:33:06 +0800 Subject: [PATCH 298/308] docs: add _14_1_cuttingRope --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 84df919..e9434e3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成269道 +- leetcode练习,坚持每天一道,目前已完成270道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -20,7 +20,7 @@ - [x] [剑指 Offer 13. 机器人的运动范围](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_13_movingCount.java) -- [ ] [剑指 Offer 14- I. 剪绳子](https://leetcode-cn.com/problems/jian-sheng-zi-lcof/) +- [x] [剑指 Offer 14- I. 剪绳子](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_14_1_cuttingRope.java) - [ ] [剑指 Offer 14- II. ](https://leetcode-cn.com/problems/jian-sheng-zi-ii-lcof/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成269) +### 题目列表(更新中—已完成270) -[Leetcode-Java(260+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_13_movingCount.java) +[Leetcode-Java(270+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_14_1_cuttingRope.java) #### 剑指offer系列 @@ -77,7 +77,8 @@ | [剑指 Offer 10- II. 青蛙跳台阶问题](https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof/) | [NumWays](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_10_2_numWays.java) | | Easy | | | [剑指 Offer 11. 旋转数组的最小数字](https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/) | [MinArray](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_11_minArray.java) | [二分查找]() | Easy | | | [剑指 Offer 12. 矩阵中的路径](https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/) | [Exist](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_12_exist.java) | [DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | -| [剑指 Offer 13. 机器人的运动范围](https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/) | [MovingCount](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_13_movingCount.java) | | | | +| [剑指 Offer 13. 机器人的运动范围](https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/) | [MovingCount](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_13_movingCount.java) | | Medium | | +| [剑指 Offer 14- I. 剪绳子](https://leetcode-cn.com/problems/jian-sheng-zi-lcof/) | [CuttingRope](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_14_1_cuttingRope.java) | [数学]()、[动态规划]() | Medium | | #### 经典题解 From 7db6639a8c87cbebe19520fba8425b2eb3522090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 10 Aug 2020 15:30:27 +0800 Subject: [PATCH 299/308] feat(EASY): add _15_hammingWeight --- .../arithmetic/offer/_15_hammingWeight.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/pp/arithmetic/offer/_15_hammingWeight.java diff --git a/src/pp/arithmetic/offer/_15_hammingWeight.java b/src/pp/arithmetic/offer/_15_hammingWeight.java new file mode 100644 index 0000000..bfae0b4 --- /dev/null +++ b/src/pp/arithmetic/offer/_15_hammingWeight.java @@ -0,0 +1,57 @@ +package pp.arithmetic.offer; + +/** + * Created by wangpeng on 2020-08-10. + * 剑指 Offer 15. 二进制中1的个数 + * + * 请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。 + * + * 示例 1: + * + * 输入:00000000000000000000000000001011 + * 输出:3 + * 解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。 + * 示例 2: + * + * 输入:00000000000000000000000010000000 + * 输出:1 + * 解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。 + * 示例 3: + * + * 输入:11111111111111111111111111111101 + * 输出:31 + * 解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/er-jin-zhi-zhong-1de-ge-shu-lcof + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _15_hammingWeight { + + public static void main(String[] args) { + _15_hammingWeight hammingWeight = new _15_hammingWeight(); + System.out.println(hammingWeight.hammingWeight(11)); + System.out.println(hammingWeight.hammingWeight(128)); +// System.out.println(hammingWeight.hammingWeight(4294967293)); + } + + + /** + * 解题思路: + * 如果n%2!=0,则1的个数+1,直到n=1 + * + * 注意无符号的,对应int会超 右移动使用>>>(无符号右移) + * @param n + * @return + */ + // you need to treat n as an unsigned value + public int hammingWeight(int n) { + int retVal = 0; + while (n != 0) { + retVal += n & 1; + n = n >>> 1; + } + + return retVal; + } +} From c11e04639757b2b64b3ad7b94d6cfcd3cbb0fbde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Mon, 10 Aug 2020 15:32:30 +0800 Subject: [PATCH 300/308] docs: add _15_hammingWeight --- README.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index e9434e3..64740bd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成270道 +- leetcode练习,坚持每天一道,目前已完成271道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -22,9 +22,7 @@ - [x] [剑指 Offer 14- I. 剪绳子](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_14_1_cuttingRope.java) -- [ ] [剑指 Offer 14- II. ](https://leetcode-cn.com/problems/jian-sheng-zi-ii-lcof/) - -- [ ] [剑指 Offer 15. 二进制中1的个数](https://leetcode-cn.com/problems/er-jin-zhi-zhong-1de-ge-shu-lcof/) +- [x] [剑指 Offer 15. 二进制中1的个数](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_15_hammingWeight.java) ## 已解题目 @@ -59,9 +57,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成270) +### 题目列表(更新中—已完成271) -[Leetcode-Java(270+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_14_1_cuttingRope.java) +[Leetcode-Java(270+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_15_hammingWeight.java) #### 剑指offer系列 @@ -79,6 +77,7 @@ | [剑指 Offer 12. 矩阵中的路径](https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/) | [Exist](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_12_exist.java) | [DFS](https://leetcode-cn.com/tag/depth-first-search/) | Medium | | | [剑指 Offer 13. 机器人的运动范围](https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/) | [MovingCount](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_13_movingCount.java) | | Medium | | | [剑指 Offer 14- I. 剪绳子](https://leetcode-cn.com/problems/jian-sheng-zi-lcof/) | [CuttingRope](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_14_1_cuttingRope.java) | [数学]()、[动态规划]() | Medium | | +| [剑指 Offer 15. 二进制中1的个数](https://leetcode-cn.com/problems/er-jin-zhi-zhong-1de-ge-shu-lcof/) | [HammingWeight](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_15_hammingWeight.java) | [位运算](https://leetcode-cn.com/tag/bit-manipulation/) | Easy | | #### 经典题解 From 05c998c0dbd8082da907d0fbe4f42c55e5578785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 11 Aug 2020 14:25:20 +0800 Subject: [PATCH 301/308] feat(MEDIUM): add _16_myPow --- src/pp/arithmetic/offer/_16_myPow.java | 71 ++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/pp/arithmetic/offer/_16_myPow.java diff --git a/src/pp/arithmetic/offer/_16_myPow.java b/src/pp/arithmetic/offer/_16_myPow.java new file mode 100644 index 0000000..0a49745 --- /dev/null +++ b/src/pp/arithmetic/offer/_16_myPow.java @@ -0,0 +1,71 @@ +package pp.arithmetic.offer; + +/** + * Created by wangpeng on 2020-08-11. + * + * 剑指 Offer 16. 数值的整数次方 + * + * 实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。 + * + *   + * + * 示例 1: + * + * 输入: 2.00000, 10 + * 输出: 1024.00000 + * 示例 2: + * + * 输入: 2.10000, 3 + * 输出: 9.26100 + * 示例 3: + * + * 输入: 2.00000, -2 + * 输出: 0.25000 + * 解释: 2-2 = 1/22 = 1/4 = 0.25 + *   + * + * 说明: + * + * -100.0 < x < 100.0 + * n 是 32 位有符号整数,其数值范围是 [−2^31, 2^31 − 1] 。 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/shu-zhi-de-zheng-shu-ci-fang-lcof + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _16_myPow { + + public static void main(String[] args) { + _16_myPow myPow = new _16_myPow(); + System.out.println(myPow.myPow(2.0,10)); + System.out.println(myPow.myPow(2.1,3)); + System.out.println(myPow.myPow(2.0,-2)); + System.out.println(myPow.myPow(0.00001, 2147483647)); + System.out.println(myPow.myPow(2, -2147483648)); + } + + /** + * 解题思路: + * 最简单的方式就是直接循环0-n,将x相乘得出结果,题目中的n范围比较大,这样子效率太低 + * 优化:类似2分拆分,一半一半的计算结果,最终相乘 + * @param x + * @param n + * @return + */ + public double myPow(double x, int n) { + if (n == 0) return 1; + if (n<0){ + //指数是否负数,负数需要取倒数 + x = 1/x; + } + //是否取一半还有剩余一个 + boolean isOdd = n % 2 != 0; + double v = myPow(x, Math.abs(n / 2)); + if (isOdd) { + return v * v * x; + } else { + return v * v; + } + } + +} From 43c49159ed485134a34327a3f8280e52831ab24a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 11 Aug 2020 14:42:01 +0800 Subject: [PATCH 302/308] docs: add _16_myPow --- README.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 64740bd..65204d1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成271道 +- leetcode练习,坚持每天一道,目前已完成272道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -12,17 +12,19 @@ 剑指offer系列-持续多周,每周7题 -- [x] [剑指 Offer 10- II. 青蛙跳台阶问题](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_10_2_numWays.java) +- [x] [剑指 Offer 16. 数值的整数次方](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_16_myPow.java) -- [x] [剑指 Offer 11. 旋转数组的最小数字](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_11_minArray.java) +- [ ] [剑指 Offer 17. 打印从1到最大的n位数](https://leetcode-cn.com/problems/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof/) -- [x] [剑指 Offer 12. 矩阵中的路径](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_12_exist.java) +- [ ] [剑指 Offer 18. 删除链表的节点](https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof/) -- [x] [剑指 Offer 13. 机器人的运动范围](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_13_movingCount.java) +- [ ] [剑指 Offer 19. 正则表达式匹配](https://leetcode-cn.com/problems/zheng-ze-biao-da-shi-pi-pei-lcof/) -- [x] [剑指 Offer 14- I. 剪绳子](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_14_1_cuttingRope.java) +- [ ] [剑指 Offer 20. 表示数值的字符串](https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/) -- [x] [剑指 Offer 15. 二进制中1的个数](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_15_hammingWeight.java) +- [ ] [剑指 Offer 21. 调整数组顺序使奇数位于偶数前面](https://leetcode-cn.com/problems/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof/) + +- [ ] [剑指 Offer 22. 链表中倒数第k个节点](https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/) ## 已解题目 @@ -57,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成271) +### 题目列表(更新中—已完成272) -[Leetcode-Java(270+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_15_hammingWeight.java) +[Leetcode-Java(270+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_16_myPow.java) #### 剑指offer系列 @@ -78,6 +80,7 @@ | [剑指 Offer 13. 机器人的运动范围](https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/) | [MovingCount](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_13_movingCount.java) | | Medium | | | [剑指 Offer 14- I. 剪绳子](https://leetcode-cn.com/problems/jian-sheng-zi-lcof/) | [CuttingRope](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_14_1_cuttingRope.java) | [数学]()、[动态规划]() | Medium | | | [剑指 Offer 15. 二进制中1的个数](https://leetcode-cn.com/problems/er-jin-zhi-zhong-1de-ge-shu-lcof/) | [HammingWeight](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_15_hammingWeight.java) | [位运算](https://leetcode-cn.com/tag/bit-manipulation/) | Easy | | +| [剑指 Offer 16. 数值的整数次方](https://leetcode-cn.com/problems/shu-zhi-de-zheng-shu-ci-fang-lcof/) | [MyPow](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_16_myPow.java) | | Medium | | #### 经典题解 From 5b480122b6a4f89ab7d93ede5fc50111a8e50f57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 11 Aug 2020 15:05:37 +0800 Subject: [PATCH 303/308] feat(EASY): add _17_printNumbers --- src/pp/arithmetic/offer/_17_printNumbers.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/pp/arithmetic/offer/_17_printNumbers.java diff --git a/src/pp/arithmetic/offer/_17_printNumbers.java b/src/pp/arithmetic/offer/_17_printNumbers.java new file mode 100644 index 0000000..6eb52a1 --- /dev/null +++ b/src/pp/arithmetic/offer/_17_printNumbers.java @@ -0,0 +1,56 @@ +package pp.arithmetic.offer; + +import pp.arithmetic.Util; + +/** + * Created by wangpeng on 2020-08-11. + * + * 剑指 Offer 17. 打印从1到最大的n位数 + * + * 输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。 + * + * 示例 1: + * + * 输入: n = 1 + * 输出: [1,2,3,4,5,6,7,8,9] + *   + * + * 说明: + * + * 用返回一个整数列表来代替打印 + * n 为正整数 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _17_printNumbers { + + public static void main(String[] args) { + _17_printNumbers printNumbers = new _17_printNumbers(); + Util.printArray(printNumbers.printNumbers(1)); + Util.printArray(printNumbers.printNumbers(2)); + Util.printArray(printNumbers.printNumbers(3)); + } + + /** + * 解题思路: + * 本题没有什么难度,唯一难的就是咋根据n构建出相应size的数组 + * + * @param n + * @return + */ + public int[] printNumbers(int n) { + char[] len = new char[n]; + for (int i = 0; i < n; i++) { + len[i] = '9'; + } + int size = Integer.parseInt(new String(len)); + int[] retVal = new int[size]; + for (int i = 0; i < size; i++) { + retVal[i] = i+1; + } + + return retVal; + } +} From 0047c51347eb24f0a46578b75b2ccfa78b0b0fdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Tue, 11 Aug 2020 15:08:07 +0800 Subject: [PATCH 304/308] docs: add _17_printNumbers --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 65204d1..e208566 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成272道 +- leetcode练习,坚持每天一道,目前已完成273道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -14,7 +14,7 @@ - [x] [剑指 Offer 16. 数值的整数次方](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_16_myPow.java) -- [ ] [剑指 Offer 17. 打印从1到最大的n位数](https://leetcode-cn.com/problems/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof/) +- [x] [剑指 Offer 17. 打印从1到最大的n位数](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_17_printNumbers.java) - [ ] [剑指 Offer 18. 删除链表的节点](https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof/) @@ -59,9 +59,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成272) +### 题目列表(更新中—已完成273) -[Leetcode-Java(270+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_16_myPow.java) +[Leetcode-Java(270+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_17_printNumbers.java) #### 剑指offer系列 @@ -81,6 +81,7 @@ | [剑指 Offer 14- I. 剪绳子](https://leetcode-cn.com/problems/jian-sheng-zi-lcof/) | [CuttingRope](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_14_1_cuttingRope.java) | [数学]()、[动态规划]() | Medium | | | [剑指 Offer 15. 二进制中1的个数](https://leetcode-cn.com/problems/er-jin-zhi-zhong-1de-ge-shu-lcof/) | [HammingWeight](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_15_hammingWeight.java) | [位运算](https://leetcode-cn.com/tag/bit-manipulation/) | Easy | | | [剑指 Offer 16. 数值的整数次方](https://leetcode-cn.com/problems/shu-zhi-de-zheng-shu-ci-fang-lcof/) | [MyPow](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_16_myPow.java) | | Medium | | +| [剑指 Offer 17. 打印从1到最大的n位数](https://leetcode-cn.com/problems/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof/) | [PrintNumbers](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_17_printNumbers.java) | [数学]() | Easy | | #### 经典题解 From 8a8b2773edef2aaeb4f1f734a1d2a280363372af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 2 Sep 2020 10:10:49 +0800 Subject: [PATCH 305/308] feat(EASY): add _6_minCount --- src/pp/arithmetic/LCP/_6_minCount.java | 62 ++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/pp/arithmetic/LCP/_6_minCount.java diff --git a/src/pp/arithmetic/LCP/_6_minCount.java b/src/pp/arithmetic/LCP/_6_minCount.java new file mode 100644 index 0000000..6176961 --- /dev/null +++ b/src/pp/arithmetic/LCP/_6_minCount.java @@ -0,0 +1,62 @@ +package pp.arithmetic.LCP; + +/** + * Created by wangpeng on 2020-09-02. + * LCP 06. 拿硬币 + *

+ * 桌上有 n 堆力扣币,每堆的数量保存在数组 coins 中。我们每次可以选择任意一堆,拿走其中的一枚或者两枚,求拿完所有力扣币的最少次数。 + *

+ * 示例 1: + *

+ * 输入:[4,2,1] + *

+ * 输出:4 + *

+ * 解释:第一堆力扣币最少需要拿 2 次,第二堆最少需要拿 1 次,第三堆最少需要拿 1 次,总共 4 次即可拿完。 + *

+ * 示例 2: + *

+ * 输入:[2,3,10] + *

+ * 输出:8 + *

+ * 限制: + *

+ * 1 <= n <= 4 + * 1 <= coins[i] <= 10 + *

+ * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/na-ying-bi + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _6_minCount { + + public static void main(String[] args) { + _6_minCount minCount = new _6_minCount(); + System.out.println(minCount.minCount(new int[]{4, 2, 1})); + System.out.println(minCount.minCount(new int[]{2, 3, 10})); + + } + + /** + * 解题思路: + * 需要最少次数,利用贪心的思路,每次尽可能的多拿(也就是2个) + * + * @param coins + * @return + */ + public int minCount(int[] coins) { + if (coins == null) return 0; + int retVal = 0; + for (int i = 0; i < coins.length; i++) { + int coin = coins[i]; + if (coin % 2 == 0) { + retVal += coin / 2; + } else { + retVal += coin / 2 + 1; + } + } + + return retVal; + } +} From 465faf2f36f02d5a41ec2051af571afa9f984aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 2 Sep 2020 10:13:24 +0800 Subject: [PATCH 306/308] docs: add _6_minCount --- README.md | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index e208566..d845c17 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成273道 +- leetcode练习,坚持每天一道,目前已完成274道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -12,19 +12,17 @@ 剑指offer系列-持续多周,每周7题 -- [x] [剑指 Offer 16. 数值的整数次方](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_16_myPow.java) - -- [x] [剑指 Offer 17. 打印从1到最大的n位数](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_17_printNumbers.java) - -- [ ] [剑指 Offer 18. 删除链表的节点](https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof/) - -- [ ] [剑指 Offer 19. 正则表达式匹配](https://leetcode-cn.com/problems/zheng-ze-biao-da-shi-pi-pei-lcof/) - -- [ ] [剑指 Offer 20. 表示数值的字符串](https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/) +- [x] [剑指 Offer 16. 数值的整数次方](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_16_myPow.java) +- [x] [剑指 Offer 17. 打印从1到最大的n位数](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_17_printNumbers.java) +- [ ] [剑指 Offer 18. 删除链表的节点](https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof/) +- [ ] [剑指 Offer 19. 正则表达式匹配](https://leetcode-cn.com/problems/zheng-ze-biao-da-shi-pi-pei-lcof/) +- [ ] [剑指 Offer 20. 表示数值的字符串](https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/) +- [ ] [剑指 Offer 21. 调整数组顺序使奇数位于偶数前面](https://leetcode-cn.com/problems/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof/) +- [ ] [剑指 Offer 22. 链表中倒数第k个节点](https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/) -- [ ] [剑指 Offer 21. 调整数组顺序使奇数位于偶数前面](https://leetcode-cn.com/problems/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof/) +LCP -- [ ] [剑指 Offer 22. 链表中倒数第k个节点](https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/) +- [x] [LCP 06. 拿硬币](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_6_minCount.java) ## 已解题目 @@ -59,9 +57,9 @@ - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成273) +### 题目列表(更新中—已完成274) -[Leetcode-Java(270+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_17_printNumbers.java) +[Leetcode-Java(270+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_6_minCount.java) #### 剑指offer系列 @@ -339,11 +337,12 @@ #### LCP -| No | 题目 | 解决方案 | 难度 | -| ---- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | -| #1 | [LCP 1. 猜数字](https://leetcode-cn.com/problems/guess-numbers/) | [Game](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_1_game.java) | Easy | -| #2 | [LCP 2. 分式化简](https://leetcode-cn.com/problems/deep-dark-fraction/) | [Fraction](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_2_fraction.java) | Easy | -| #3 | [LCP 3. 机器人大冒险](https://leetcode-cn.com/problems/programmable-robot/) | [Robot](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_3_robot.java) | Medium | -| #4 | [LCP 4. 覆盖](https://leetcode-cn.com/problems/broken-board-dominoes/) | [Domino](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_4_domino.java) | Hard | -| #5 | [LCP 5. 发 LeetCoin](https://leetcode-cn.com/problems/coin-bonus/) | [Bonus](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_5_bonus_2.java) | Hard | +| 题目 | 解决方案 | 难度 | 备注 | +| ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | ---- | +| [LCP 1. 猜数字](https://leetcode-cn.com/problems/guess-numbers/) | [Game](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_1_game.java) | Easy | | +| [LCP 2. 分式化简](https://leetcode-cn.com/problems/deep-dark-fraction/) | [Fraction](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_2_fraction.java) | Easy | | +| [LCP 3. 机器人大冒险](https://leetcode-cn.com/problems/programmable-robot/) | [Robot](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_3_robot.java) | Medium | | +| [LCP 4. 覆盖](https://leetcode-cn.com/problems/broken-board-dominoes/) | [Domino](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_4_domino.java) | Hard | | +| [LCP 5. 发 LeetCoin](https://leetcode-cn.com/problems/coin-bonus/) | [Bonus](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_5_bonus_2.java) | Hard | | +| [LCP 06. 拿硬币](https://leetcode-cn.com/problems/na-ying-bi/) | [MinCount](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_6_minCount.java) | Easy | | From e800773f58190bdd6c5fad857eb1fc6a0705b884 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 9 Sep 2020 11:48:57 +0800 Subject: [PATCH 307/308] feat(EASY): add _18_deleteNode --- src/pp/arithmetic/offer/_18_deleteNode.java | 74 +++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/pp/arithmetic/offer/_18_deleteNode.java diff --git a/src/pp/arithmetic/offer/_18_deleteNode.java b/src/pp/arithmetic/offer/_18_deleteNode.java new file mode 100644 index 0000000..0f4dd2e --- /dev/null +++ b/src/pp/arithmetic/offer/_18_deleteNode.java @@ -0,0 +1,74 @@ +package pp.arithmetic.offer; + +import pp.arithmetic.Util; +import pp.arithmetic.model.ListNode; + +/** + * Created by wangpeng on 2020-09-09. + * 剑指 Offer 18. 删除链表的节点 + * + * 给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。 + * + * 返回删除后的链表的头节点。 + * + * 注意:此题对比原题有改动 + * + * 示例 1: + * + * 输入: head = [4,5,1,9], val = 5 + * 输出: [4,1,9] + * 解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9. + * 示例 2: + * + * 输入: head = [4,5,1,9], val = 1 + * 输出: [4,5,9] + * 解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9. + *   + * + * 说明: + * + * 题目保证链表中节点的值互不相同 + * 若使用 C 或 C++ 语言,你不需要 free 或 delete 被删除的节点 + * + * 来源:力扣(LeetCode) + * 链接:https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + */ +public class _18_deleteNode { + + public static void main(String[] args) { + _18_deleteNode deleteNode = new _18_deleteNode(); + ListNode head = new ListNode(4); + head.next = new ListNode(5); + head.next.next = new ListNode(1); + head.next.next.next = new ListNode(9); + ListNode listNode = deleteNode.deleteNode(head, 4); + Util.printListNode(listNode); + } + + /** + * 解题思路: + * 对于链表的问题,最核心的思想就是遍历,使用一个虚拟节点指向头结点,用来缓存返回结果 + * + * @param head + * @param val + * @return + */ + public ListNode deleteNode(ListNode head, int val) { + ListNode dummp = new ListNode(0); + dummp.next = head; + ListNode pre = dummp; + ListNode next = head; + while (next != null) { + if (next.val == val) { + pre.next = next.next; + next.next = null; + return dummp.next; + } + pre = next; + next = next.next; + } + + return null; + } +} From f1b3876b2f3de7c06c17a6a2a6d483541d1af514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Wed, 9 Sep 2020 11:51:30 +0800 Subject: [PATCH 308/308] docs: add _18_deleteNode --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d845c17..a008d61 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LeetCode-Java ## 说明 -- leetcode练习,坚持每天一道,目前已完成274道 +- leetcode练习,坚持每天一道,目前已完成275道 - 解题语言是Java - 每道题都是可编译运行的 - 每道题有自己的方法和他人优秀解法 @@ -14,7 +14,7 @@ - [x] [剑指 Offer 16. 数值的整数次方](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_16_myPow.java) - [x] [剑指 Offer 17. 打印从1到最大的n位数](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_17_printNumbers.java) -- [ ] [剑指 Offer 18. 删除链表的节点](https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof/) +- [x] [剑指 Offer 18. 删除链表的节点](https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof/) - [ ] [剑指 Offer 19. 正则表达式匹配](https://leetcode-cn.com/problems/zheng-ze-biao-da-shi-pi-pei-lcof/) - [ ] [剑指 Offer 20. 表示数值的字符串](https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/) - [ ] [剑指 Offer 21. 调整数组顺序使奇数位于偶数前面](https://leetcode-cn.com/problems/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof/) @@ -57,9 +57,9 @@ LCP - [线段树](https://leetcode-cn.com/tag/segment-tree/)(9) - [二叉搜索树](https://leetcode-cn.com/tag/binary-search-tree/)(15) -### 题目列表(更新中—已完成274) +### 题目列表(更新中—已完成275) -[Leetcode-Java(270+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/LCP/_6_minCount.java) +[Leetcode-Java(270+题解,持续更新、欢迎star&留言&交流)](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_18_deleteNode.java) #### 剑指offer系列 @@ -80,6 +80,7 @@ LCP | [剑指 Offer 15. 二进制中1的个数](https://leetcode-cn.com/problems/er-jin-zhi-zhong-1de-ge-shu-lcof/) | [HammingWeight](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_15_hammingWeight.java) | [位运算](https://leetcode-cn.com/tag/bit-manipulation/) | Easy | | | [剑指 Offer 16. 数值的整数次方](https://leetcode-cn.com/problems/shu-zhi-de-zheng-shu-ci-fang-lcof/) | [MyPow](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_16_myPow.java) | | Medium | | | [剑指 Offer 17. 打印从1到最大的n位数](https://leetcode-cn.com/problems/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof/) | [PrintNumbers](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_17_printNumbers.java) | [数学]() | Easy | | +| [剑指 Offer 18. 删除链表的节点](https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof/) | [DeleteNode](https://github.com/pphdsny/Leetcode-Java/blob/master/src/pp/arithmetic/offer/_18_deleteNode.java) | [链表](https://leetcode-cn.com/tag/linked-list/) | Easy | | #### 经典题解