From c31f54f2ce0d4ddc09c855247aba7bf99bc3dd13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BF=9D=E7=8A=B6?= Date: Fri, 24 Aug 2018 17:12:57 +0800 Subject: [PATCH 001/162] Update README.md --- README.md | 140 +++++++++++++++++++++++++++--------------------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/README.md b/README.md index d7110968..97ae8311 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # awesome-java-leetcode -我如今是一名 Android Developer,大学的我曾是一名 ACMer,我一直认为数据结构和算法是作为一名程序员必须掌握和善于利用的,为了不让数据结构和算法淡出我的记忆,所以我打算重拾 LeetCode 之 Algorithm,语言选择的是 Java,题库会一点点完善起来,按简单,中等,困难分类,相应难度下按题号排序,源代码在 [src][src] 目录中,相关解题都在 [note][note] 目录中,想要学习数据结构和算法或打算刷 LeetCode 的小伙伴们欢迎 star 哦。 +数据结构和算法是作为一名程序员必须掌握和善于利用的,为了不让数据结构和算法淡出我的记忆,所以我打算重拾 LeetCode 之 Algorithm,语言选择的是 Java,题库会一点点完善起来,按简单,中等,困难分类,相应难度下按题号排序,源代码在 [src][src] 目录中,相关解题都在 [note][note] 目录中,想要学习数据结构和算法或打算刷 LeetCode 的小伙伴们欢迎 star 哦。 -如今有机会面试 Facebook,附上 LeetCode 上 Facebook 的面试题目序号,希望可以帮助到以后想入 Facebook 的小伙伴:-) +附上 LeetCode 上 Facebook 的面试题目序号,希望可以帮助到以后想入 Facebook 的小伙伴:-) ``` 1,10,13,15,17,20,23,25,26,28,33,38,43,44,49,50,56,57,67,68,69,71,75,76 @@ -106,71 +106,71 @@ -[src]: https://github.com/Blankj/awesome-java-leetcode/tree/master/src -[note]: https://github.com/Blankj/awesome-java-leetcode/tree/master/note -[companies]: https://github.com/Blankj/awesome-java-leetcode/blob/master/Companies.md - -[001]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/001/README.md -[007]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/007/README.md -[009]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/009/README.md -[013]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/013/README.md -[014]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/014/README.md -[020]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/020/README.md -[021]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/021/README.md -[026]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/026/README.md -[027]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/027/README.md -[028]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/028/README.md -[035]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/035/README.md -[038]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/038/README.md -[053]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/053/README.md -[058]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/058/README.md -[066]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/066/README.md -[067]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/067/README.md -[069]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/069/README.md -[070]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/070/README.md -[083]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/083/README.md -[088]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/088/README.md -[100]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/100/README.md -[101]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/101/README.md -[104]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/104/README.md -[107]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/107/README.md -[108]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/108/README.md -[110]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/110/README.md -[111]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/111/README.md -[112]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/112/README.md -[118]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/118/README.md -[119]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/119/README.md -[121]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/121/README.md -[122]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/122/README.md -[543]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/543/README.md - -[002]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/002/README.md -[003]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/003/README.md -[005]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/005/README.md -[006]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/006/README.md -[008]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/008/README.md -[011]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/011/README.md -[012]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/012/README.md -[015]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/015/README.md -[016]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/016/README.md -[017]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/017/README.md -[018]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/018/README.md -[019]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/019/README.md -[022]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/022/README.md -[024]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/024/README.md -[029]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/029/README.md -[033]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/033/README.md -[043]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/043/README.md -[049]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/049/README.md -[050]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/050/README.md -[056]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/056/README.md -[554]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/554/README.md - -[004]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/004/README.md -[010]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/010/README.md -[023]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/023/README.md -[025]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/025/README.md -[030]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/030/README.md -[044]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/044/README.md -[057]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/057/README.md -[068]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/068/README.md +[src]: https://github.com/zgpeace/awesome-java-leetcode/tree/master/src +[note]: https://github.com/zgpeace/awesome-java-leetcode/tree/master/note +[companies]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/Companies.md + +[001]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/001/README.md +[007]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/007/README.md +[009]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/009/README.md +[013]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/013/README.md +[014]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/014/README.md +[020]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/020/README.md +[021]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/021/README.md +[026]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/026/README.md +[027]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/027/README.md +[028]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/028/README.md +[035]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/035/README.md +[038]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/038/README.md +[053]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/053/README.md +[058]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/058/README.md +[066]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/066/README.md +[067]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/067/README.md +[069]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/069/README.md +[070]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/070/README.md +[083]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/083/README.md +[088]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/088/README.md +[100]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/100/README.md +[101]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/101/README.md +[104]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/104/README.md +[107]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/107/README.md +[108]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/108/README.md +[110]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/110/README.md +[111]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/111/README.md +[112]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/112/README.md +[118]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/118/README.md +[119]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/119/README.md +[121]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/121/README.md +[122]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/122/README.md +[543]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/543/README.md + +[002]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/002/README.md +[003]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/003/README.md +[005]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/005/README.md +[006]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/006/README.md +[008]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/008/README.md +[011]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/011/README.md +[012]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/012/README.md +[015]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/015/README.md +[016]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/016/README.md +[017]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/017/README.md +[018]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/018/README.md +[019]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/019/README.md +[022]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/022/README.md +[024]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/024/README.md +[029]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/029/README.md +[033]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/033/README.md +[043]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/043/README.md +[049]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/049/README.md +[050]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/050/README.md +[056]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/056/README.md +[554]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/554/README.md + +[004]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/004/README.md +[010]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/010/README.md +[023]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/023/README.md +[025]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/025/README.md +[030]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/030/README.md +[044]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/044/README.md +[057]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/057/README.md +[068]: https://github.com/zgpeace/awesome-java-leetcode/blob/master/note/068/README.md From 3e2506b6a7b9b36aa079607e61b959d9ad885a12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BF=9D=E7=8A=B6?= Date: Fri, 24 Aug 2018 17:16:53 +0800 Subject: [PATCH 002/162] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 97ae8311..be1e66cd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # awesome-java-leetcode -数据结构和算法是作为一名程序员必须掌握和善于利用的,为了不让数据结构和算法淡出我的记忆,所以我打算重拾 LeetCode 之 Algorithm,语言选择的是 Java,题库会一点点完善起来,按简单,中等,困难分类,相应难度下按题号排序,源代码在 [src][src] 目录中,相关解题都在 [note][note] 目录中,想要学习数据结构和算法或打算刷 LeetCode 的小伙伴们欢迎 star 哦。 +数据结构和算法是作为一名程序员必须掌握和善于利用的,重拾 LeetCode 之 Algorithm,语言选择的是 Java,题库会一点点完善起来,按简单,中等,困难分类,相应难度下按题号排序,源代码在 [src][src] 目录中,相关解题都在 [note][note] 目录中,想要学习数据结构和算法或打算刷 LeetCode 的小伙伴们欢迎 star 哦。这里的代码是二次修改,因为有些错误,和不完善,fork仓库来源:[Blankj/awesome-java-leetcode](https://github.com/Blankj/awesome-java-leetcode) 附上 LeetCode 上 Facebook 的面试题目序号,希望可以帮助到以后想入 Facebook 的小伙伴:-) From 73b23e5fbe094fe67f7b70c9e9bcd4bfd41a8800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BF=9D=E7=8A=B6?= Date: Fri, 24 Aug 2018 17:21:09 +0800 Subject: [PATCH 003/162] Update README.md --- note/030/README.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/note/030/README.md b/note/030/README.md index 7d5eaa2e..2cb9c427 100644 --- a/note/030/README.md +++ b/note/030/README.md @@ -29,7 +29,15 @@ Output: [] ## 思路 -题意是 +1. 使用HashMap来保存L中所有的字串。 + +2. 暴力破解之。使用i记录我们的查找结果字符串的位置,j记录单个单词的查找位置。j每次移动一个L中单词的位置。 + +3. 注意各种越界条件:i查到离结束还有L*N(L中所有单词总长)的时候,即需要停止。 + + j 也要考虑每一次查找的单词的长度。 + +4. 使用第二个HashMap来记录我们查到的单词。如果所有的单词都查到了,即可记录一个解。 ```java @@ -38,9 +46,9 @@ Output: [] ## 结语 -如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 LeetCode 题解:[awesome-java-leetcode][ajl] +如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 LeetCode 题解:[awesome-java-leetcode][zgpeace] [title]: https://leetcode.com/problems/substring-with-concatenation-of-all-words -[ajl]: https://github.com/Blankj/awesome-java-leetcode +[zgpeace]: https://github.com/zgpeace/awesome-java-leetcode From efc0388c0c7fb85bba211d2bf62807a4a1fac5ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BF=9D=E7=8A=B6?= Date: Fri, 24 Aug 2018 17:52:29 +0800 Subject: [PATCH 004/162] Update README.md --- note/030/README.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/note/030/README.md b/note/030/README.md index 2cb9c427..4a5b48a4 100644 --- a/note/030/README.md +++ b/note/030/README.md @@ -40,6 +40,54 @@ Output: [] 4. 使用第二个HashMap来记录我们查到的单词。如果所有的单词都查到了,即可记录一个解。 ```java +class Solution { + public List findSubstring(String s, String[] words) { + List resultList = new ArrayList(); + if (s == null || s.length() == 0 || words == null || words.length == 0) { + return resultList; + } + Map wordMap = new HashMap(); + Map foundMap = new HashMap(); + for (String word: words) { + if (wordMap.containsKey(word)) { + wordMap.put(word, (wordMap.get(word) + 1)); + } else { + wordMap.put(word, 1); + } + } + int wordCount = words.length; + int wordLen = words[0].length(); + int allLen = wordLen * wordCount; + + for (int i = 0; i <= s.length() - allLen; i++) { + foundMap.clear(); + int foundCount = 0; + for (int j = 0; j < wordCount; j++) { + String tempWord = s.substring(i + j * wordLen, i + (j + 1) * wordLen); + if (wordMap.containsKey(tempWord)) { + if (foundMap.containsKey(tempWord)) { + foundMap.put(tempWord, (foundMap.get(tempWord) + 1)); + } else { + foundMap.put(tempWord, 1); + } + + if (foundMap.get(tempWord) > wordMap.get(tempWord)) { + break; + } + foundCount++; + } else { + break; + } + } + + if (foundCount == wordCount) { + resultList.add(i); + } + } + + return resultList; + } +} ``` From eaba1039650cdc35ac664682e5eff8b8c9e46a3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BF=9D=E7=8A=B6?= Date: Fri, 24 Aug 2018 20:02:50 +0800 Subject: [PATCH 005/162] Update README.md --- note/030/README.md | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/note/030/README.md b/note/030/README.md index 4a5b48a4..71ac8770 100644 --- a/note/030/README.md +++ b/note/030/README.md @@ -27,7 +27,8 @@ Output: [] **Tags:** Hash Table, Two Pointers, String -## 思路 +## 思路 0 +遍历string的字符串,挨个匹配,O(n*wordLength) 1. 使用HashMap来保存L中所有的字串。 @@ -89,6 +90,27 @@ class Solution { } } +``` + +## 思路 1 +通过滑动窗口的思维,窗口大小为words数组的1个单位。 + +An O(N) solution with detailed explanation + +1. travel all the words combinations to maintain a window + +2. there are wl(word len) times travel + +3. each time, n/wl words, mostly 2 times travel for each word + +4. one left side of the window, the other right side of the window + +5. so, time complexity O(wl * 2 * N/wl) = O(2N) + + +```java + + ``` From ab2f30415e1f79fd7e139401d41a88d21496cdf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BF=9D=E7=8A=B6?= Date: Fri, 24 Aug 2018 20:21:19 +0800 Subject: [PATCH 006/162] Update README.md --- note/030/README.md | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/note/030/README.md b/note/030/README.md index 71ac8770..77a4f80d 100644 --- a/note/030/README.md +++ b/note/030/README.md @@ -109,7 +109,56 @@ An O(N) solution with detailed explanation ```java +public List findSubstringByWindowSlide(String s, String[] words) { + List resultList = new ArrayList(); + if (s == null || s.length() == 0 || words == null || words.length == 0) { + return resultList; + } + Map wordMap = new HashMap(); + + int distinguishCount = 0; + for (String word : words) { + wordMap.put(word, wordMap.getOrDefault(word, 0) + 1); + if (wordMap.get(word) == 1) { + distinguishCount += 1; + } + } + int wordLen = words[0].length(); + int wordCount = words.length; + for (int k = 0; k < wordLen; k++) { + Map foundMap = new HashMap(); + int foundCount = 0; + for (int i = k, j = k; j <= s.length() - wordLen; j = j + wordLen) { + + if (j - i >= wordLen * wordCount) { + String firstWord = s.substring(i, i + wordLen); + if (wordMap.containsKey(firstWord)) { + foundMap.put(firstWord, foundMap.get(firstWord) - 1); + if (foundMap.get(firstWord) == wordMap.get(firstWord) - 1) { + foundCount -= 1; + } + } + i += wordLen; + } + + String nextWord = s.substring(j, j + wordLen); + if (wordMap.containsKey(nextWord)) { + foundMap.put(nextWord, foundMap.getOrDefault(nextWord, 0) + 1); + if (wordMap.get(nextWord) == foundMap.get(nextWord)) { + foundCount += 1; + } + } + + if (foundCount == distinguishCount) { + resultList.add(i); + } + } + + } + + return resultList; + } ``` From e2c7d40b1f3efa0ea4d41d4616dc63d35146caa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BF=9D=E7=8A=B6?= Date: Fri, 24 Aug 2018 20:22:00 +0800 Subject: [PATCH 007/162] Update README.md --- note/030/README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/note/030/README.md b/note/030/README.md index 77a4f80d..16df3272 100644 --- a/note/030/README.md +++ b/note/030/README.md @@ -109,7 +109,15 @@ An O(N) solution with detailed explanation ```java -public List findSubstringByWindowSlide(String s, String[] words) { +class Solution { + public List findSubstring(String s, String[] words) { + //1. method Iterate + // return findSubstringByIterate(s, words); + //2. method O(n) + return findSubstringByWindowSlide(s, words); + } + + public List findSubstringByWindowSlide(String s, String[] words) { List resultList = new ArrayList(); if (s == null || s.length() == 0 || words == null || words.length == 0) { return resultList; @@ -159,6 +167,7 @@ public List findSubstringByWindowSlide(String s, String[] words) { return resultList; } +} ``` From 552d775352a9d74d503d84ea7dc550e9329bfe1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BF=9D=E7=8A=B6?= Date: Fri, 26 Oct 2018 08:16:00 +0800 Subject: [PATCH 008/162] Update README.md --- note/101/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/note/101/README.md b/note/101/README.md index 8f0e0b05..9788c480 100644 --- a/note/101/README.md +++ b/note/101/README.md @@ -83,7 +83,7 @@ class Solution { left = q.pop(); right = q.pop(); if (left == null && right == null) continue; - if (left == null || right == null) return false; + if (left == null || right == null) return left == right; if (left.val != right.val) return false; q.add(left.left); q.add(right.right); From d0f18b50efc728b0a0625a3a92bb02c6f5a07351 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 19 Feb 2019 10:38:38 +0800 Subject: [PATCH 009/162] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/LeetCode/src/AddBinary.java | 62 ++++ code/LeetCode/src/AddTwoNumbers.java | 70 +++++ code/LeetCode/src/BalancedBinaryTree.java | 64 ++++ .../src/BestTimeToBuyAndSellStock.java | 78 +++++ .../src/BestTimeToBuyAndSellStockII.java | 88 ++++++ .../src/BinaryTreeLevelOrderTraversalII.java | 120 ++++++++ code/LeetCode/src/BrickWall.java | 116 ++++++++ code/LeetCode/src/ClimbingStairs.java | 93 ++++++ code/LeetCode/src/ContainerWithMostWater.java | 68 +++++ .../LeetCode/src/ConvertSortedArrayToBST.java | 97 ++++++ code/LeetCode/src/CountAndSay.java | 101 +++++++ code/LeetCode/src/DiameterOfBinaryTree.java | 92 ++++++ code/LeetCode/src/DivideTwoIntegers.java | 115 ++++++++ code/LeetCode/src/FourSum.java | 216 ++++++++++++++ code/LeetCode/src/GenerateParentheses.java | 140 +++++++++ code/LeetCode/src/GroupAnagrams.java | 97 ++++++ code/LeetCode/src/HeapOperator.java | 137 +++++++++ code/LeetCode/src/ImplementStrStr.java | 55 ++++ code/LeetCode/src/InsertInterval.java | 127 ++++++++ code/LeetCode/src/IntegerToRoman.java | 108 +++++++ code/LeetCode/src/Interval.java | 13 + code/LeetCode/src/LengthOfLastWord.java | 72 +++++ .../src/LetterCombinationsOfAPhoneNumber.java | 125 ++++++++ code/LeetCode/src/ListNode.java | 7 + code/LeetCode/src/LongestCommonPrefix.java | 59 ++++ .../src/LongestPalindromicSubstring.java | 219 ++++++++++++++ ...stSubstringWithoutRepeatingCharacters.java | 89 ++++++ code/LeetCode/src/Main.java | 6 + .../src/MaximumDepthOfBinaryTree.java | 92 ++++++ code/LeetCode/src/MaximumSubarray.java | 118 ++++++++ .../LeetCode/src/MedianOfTwoSortedArrays.java | 136 +++++++++ code/LeetCode/src/MergeIntervals.java | 115 ++++++++ code/LeetCode/src/MergeKSortedLists.java | 163 ++++++++++ code/LeetCode/src/MergeSoredArray.java | 84 ++++++ code/LeetCode/src/MergeTwoSortedLists.java | 109 +++++++ .../src/MinimumDepthOfBinaryTree.java | 106 +++++++ code/LeetCode/src/MultiplyStrings.java | 119 ++++++++ code/LeetCode/src/PascalTriangle.java | 80 +++++ code/LeetCode/src/PascalTriangleII.java | 95 ++++++ code/LeetCode/src/PathSum.java | 81 +++++ code/LeetCode/src/PlusOne.java | 93 ++++++ code/LeetCode/src/Pow.java | 92 ++++++ .../src/RegularExpressionMatching.java | 279 ++++++++++++++++++ .../src/RemoveDuplicatesFromSortedArray.java | 70 +++++ .../src/RemoveDuplicatesFromSortedList.java | 113 +++++++ code/LeetCode/src/RemoveElement.java | 96 ++++++ .../src/RemoveNthNodeFromEndOfList.java | 94 ++++++ code/LeetCode/src/ReverseNodesInKGroup.java | 128 ++++++++ code/LeetCode/src/RomanToInt.java | 41 +++ code/LeetCode/src/SameTree.java | 112 +++++++ .../src/SearchInRotatedSortedArray.java | 120 ++++++++ code/LeetCode/src/SearchInsertPosition.java | 77 +++++ code/LeetCode/src/Sqrt.java | 49 +++ code/LeetCode/src/StringToIntegerAtoi.java | 148 ++++++++++ .../SubstringWithConcatenationOfAllWords.java | 228 ++++++++++++++ code/LeetCode/src/SwapNodesInPairs.java | 99 +++++++ code/LeetCode/src/SymmetricTree.java | 125 ++++++++ code/LeetCode/src/TextJustification.java | 212 +++++++++++++ code/LeetCode/src/ThreeSum.java | 148 ++++++++++ code/LeetCode/src/ThreeSumClosest.java | 99 +++++++ code/LeetCode/src/TreeNode.java | 8 + code/LeetCode/src/ValidParentheses.java | 74 +++++ code/LeetCode/src/WildcardMatching.java | 203 +++++++++++++ code/LeetCode/src/ZigzagConversion.java | 163 ++++++++++ 64 files changed, 6803 insertions(+) create mode 100644 code/LeetCode/src/AddBinary.java create mode 100644 code/LeetCode/src/AddTwoNumbers.java create mode 100644 code/LeetCode/src/BalancedBinaryTree.java create mode 100644 code/LeetCode/src/BestTimeToBuyAndSellStock.java create mode 100644 code/LeetCode/src/BestTimeToBuyAndSellStockII.java create mode 100644 code/LeetCode/src/BinaryTreeLevelOrderTraversalII.java create mode 100644 code/LeetCode/src/BrickWall.java create mode 100644 code/LeetCode/src/ClimbingStairs.java create mode 100644 code/LeetCode/src/ContainerWithMostWater.java create mode 100644 code/LeetCode/src/ConvertSortedArrayToBST.java create mode 100644 code/LeetCode/src/CountAndSay.java create mode 100644 code/LeetCode/src/DiameterOfBinaryTree.java create mode 100644 code/LeetCode/src/DivideTwoIntegers.java create mode 100644 code/LeetCode/src/FourSum.java create mode 100644 code/LeetCode/src/GenerateParentheses.java create mode 100644 code/LeetCode/src/GroupAnagrams.java create mode 100644 code/LeetCode/src/HeapOperator.java create mode 100644 code/LeetCode/src/ImplementStrStr.java create mode 100644 code/LeetCode/src/InsertInterval.java create mode 100644 code/LeetCode/src/IntegerToRoman.java create mode 100644 code/LeetCode/src/Interval.java create mode 100644 code/LeetCode/src/LengthOfLastWord.java create mode 100644 code/LeetCode/src/LetterCombinationsOfAPhoneNumber.java create mode 100644 code/LeetCode/src/ListNode.java create mode 100644 code/LeetCode/src/LongestCommonPrefix.java create mode 100644 code/LeetCode/src/LongestPalindromicSubstring.java create mode 100644 code/LeetCode/src/LongestSubstringWithoutRepeatingCharacters.java create mode 100644 code/LeetCode/src/Main.java create mode 100644 code/LeetCode/src/MaximumDepthOfBinaryTree.java create mode 100644 code/LeetCode/src/MaximumSubarray.java create mode 100644 code/LeetCode/src/MedianOfTwoSortedArrays.java create mode 100644 code/LeetCode/src/MergeIntervals.java create mode 100644 code/LeetCode/src/MergeKSortedLists.java create mode 100644 code/LeetCode/src/MergeSoredArray.java create mode 100644 code/LeetCode/src/MergeTwoSortedLists.java create mode 100644 code/LeetCode/src/MinimumDepthOfBinaryTree.java create mode 100644 code/LeetCode/src/MultiplyStrings.java create mode 100644 code/LeetCode/src/PascalTriangle.java create mode 100644 code/LeetCode/src/PascalTriangleII.java create mode 100644 code/LeetCode/src/PathSum.java create mode 100644 code/LeetCode/src/PlusOne.java create mode 100644 code/LeetCode/src/Pow.java create mode 100644 code/LeetCode/src/RegularExpressionMatching.java create mode 100644 code/LeetCode/src/RemoveDuplicatesFromSortedArray.java create mode 100644 code/LeetCode/src/RemoveDuplicatesFromSortedList.java create mode 100644 code/LeetCode/src/RemoveElement.java create mode 100644 code/LeetCode/src/RemoveNthNodeFromEndOfList.java create mode 100644 code/LeetCode/src/ReverseNodesInKGroup.java create mode 100644 code/LeetCode/src/RomanToInt.java create mode 100644 code/LeetCode/src/SameTree.java create mode 100644 code/LeetCode/src/SearchInRotatedSortedArray.java create mode 100644 code/LeetCode/src/SearchInsertPosition.java create mode 100644 code/LeetCode/src/Sqrt.java create mode 100644 code/LeetCode/src/StringToIntegerAtoi.java create mode 100644 code/LeetCode/src/SubstringWithConcatenationOfAllWords.java create mode 100644 code/LeetCode/src/SwapNodesInPairs.java create mode 100644 code/LeetCode/src/SymmetricTree.java create mode 100644 code/LeetCode/src/TextJustification.java create mode 100644 code/LeetCode/src/ThreeSum.java create mode 100644 code/LeetCode/src/ThreeSumClosest.java create mode 100644 code/LeetCode/src/TreeNode.java create mode 100644 code/LeetCode/src/ValidParentheses.java create mode 100644 code/LeetCode/src/WildcardMatching.java create mode 100644 code/LeetCode/src/ZigzagConversion.java diff --git a/code/LeetCode/src/AddBinary.java b/code/LeetCode/src/AddBinary.java new file mode 100644 index 00000000..c6fd6c21 --- /dev/null +++ b/code/LeetCode/src/AddBinary.java @@ -0,0 +1,62 @@ +public class AddBinary { + /* + Add Binary + Description + Given two binary strings, return their sum (also a binary string). + + The input strings are both non-empty and contains only characters 1 or 0. + + Example 1: + + Input: a = "11", b = "1" + Output: "100" + Example 2: + + Input: a = "1010", b = "1011" + Output: "10101" + Tags: Math, String + */ + + /* + 思路 + 题意是给你两个二进制串,求其和的二进制串。我们就按照小学算数那么来做,用 carry 表示进位,从后往前算,依次往前, + 每算出一位就插入到最前面即可,直到把两个二进制串都遍历完即可。 + */ + + public static String addBinary(String a, String b) { + StringBuilder sb = new StringBuilder(); + int carray = 0; + int aLastIndex = a.length() - 1; + int bLastIndex = b.length() - 1; + while (aLastIndex >= 0 && bLastIndex >= 0) { + carray = carray + (aLastIndex >= 0 ? a.charAt(aLastIndex--) - '0' : 0); + carray = carray + (bLastIndex >= 0 ? b.charAt(bLastIndex--) - '0' : 0); + sb.insert(0, (char)(carray % 2 + '0')); + carray = carray >> 1; + } + while (aLastIndex >= 0) { + carray = carray + (aLastIndex >= 0 ? a.charAt(aLastIndex--) - '0' : 0); + sb.insert(0, (char)(carray % 2 + '0')); + carray = carray >> 1; + } + while (bLastIndex >= 0) { + carray = carray + (bLastIndex >= 0 ? b.charAt(bLastIndex--) - '0' : 0); + sb.insert(0, (char)(carray % 2 + '0')); + carray = carray >> 1; + } + if (carray > 0) { + sb.insert(0, '1'); + } + + return sb.toString(); + } + + public static void main(String[] args) { + String a1 = "11"; + String b1 = "1"; + System.out.println(a1+ " + " +b1+ " = " + addBinary(a1, b1)); + String a2 = "1010"; + String b2 = "1011"; + System.out.println(a2+ " + " +b2+ " = " + addBinary(a2, b2)); + } +} diff --git a/code/LeetCode/src/AddTwoNumbers.java b/code/LeetCode/src/AddTwoNumbers.java new file mode 100644 index 00000000..3177ecde --- /dev/null +++ b/code/LeetCode/src/AddTwoNumbers.java @@ -0,0 +1,70 @@ +public class AddTwoNumbers { + /* + Add Two Numbers + Description + You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. + + You may assume the two numbers do not contain any leading zero, except the number 0 itself. + + Example + + Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) + Output: 7 -> 0 -> 8 + Explanation: 342 + 465 = 807. + Tags: Linked List, Math + */ + + /* + 思路 + 题意是以链表表示一个数,低位在前,高位在后,所以题中的例子就是 342 + 465 = 807,所以我们模拟计算即可。 + */ + + public ListNode addTwoNumbers(ListNode l1, ListNode l2) { + ListNode resultNode = new ListNode(0); + ListNode headNode = resultNode; + ListNode node1 = l1; + ListNode node2 = l2; + int sum = 0; + while (node1 != null || node2 != null) { + sum = sum / 10; + if (node1 != null) { + sum += node1.val; + node1 = node1.next; + } + if (node2 != null) { + sum += node2.val; + node2 = node2.next; + } + resultNode.next = new ListNode(sum % 10); + resultNode = resultNode.next; + } + if (sum % 10 != 0) { + resultNode.next = new ListNode(1); + } + + return headNode.next; + } + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/BalancedBinaryTree.java b/code/LeetCode/src/BalancedBinaryTree.java new file mode 100644 index 00000000..a5a758f2 --- /dev/null +++ b/code/LeetCode/src/BalancedBinaryTree.java @@ -0,0 +1,64 @@ +public class BalancedBinaryTree { + /* + Balanced Binary Tree + Description + Given a binary tree, determine if it is height-balanced. + + For this problem, a height-balanced binary tree is defined as: + + a binary tree in which the depth of the two subtrees of every node never differ by more than 1. + + Example 1: + + Given the following tree [3,9,20,null,null,15,7]: + + 3 + / \ + 9 20 + / \ + 15 7 + Return true. Example 2: + + Given the following tree [1,2,2,3,3,null,null,4,4]: + + 1 + / \ + 2 2 + / \ + 3 3 + / \ + 4 4 + Return false. + + Tags: Tree, Depth-first Search + */ + + /* + 思路 + 题意是判断一棵二叉树是否是高度平衡的,所谓二叉树高度平衡指的是二叉树的每个节点的两棵子树的高度差都不超过 1, + 那么我们只需计算左右子树的高度,判断其高度差是否不超过 1 即可, + 如果超过 1,就代表其不是高度平衡的,立即返回不是即可,我这里用返回 -1 代表不是。 + */ + + public boolean isBalaced(TreeNode root) { + return helper(root) != -1; + } + + public int helper(TreeNode node) { + if (node == null) { + return 0; + } + int leftInt = helper(node.left); + if (leftInt == -1) { + return -1; + } + int rightInt = helper(node.right); + if (rightInt == -1) { + return -1; + } + if (Math.abs(leftInt - rightInt) > 1) { + return -1; + } + return 1 + Math.max(leftInt, rightInt); + } +} diff --git a/code/LeetCode/src/BestTimeToBuyAndSellStock.java b/code/LeetCode/src/BestTimeToBuyAndSellStock.java new file mode 100644 index 00000000..d01cdf85 --- /dev/null +++ b/code/LeetCode/src/BestTimeToBuyAndSellStock.java @@ -0,0 +1,78 @@ +public class BestTimeToBuyAndSellStock { + /* + Best Time to Buy and Sell Stock + Description + Say you have an array for which the ith element is the price of a given stock on day i. + + If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit. + + Note that you cannot sell a stock before you buy one. + + Example 1: + + Input: [7,1,5,3,6,4] + Output: 5 + Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5. + Not 7-1 = 6, as selling price needs to be larger than buying price. + Example 2: + + Input: [7,6,4,3,1] + Output: 0 + Explanation: In this case, no transaction is done, i.e. max profit = 0. + Tags: Array, Dynamic Programmin + */ + + /* + 思路 + 题意是给出一个数组代表每天的股票金额,让你在最多买卖一次的情况下算出最大的收益额, + 最简单的就是模拟即可,每次记录当前值减去最小值的差值,与上一次的进行比较然后更新最大值即可。 + */ + public int maxProfit(int[] prices) { + int maxProfitInt = 0; + int minPriceInt = Integer.MAX_VALUE; + for (int item: prices) { + if (item < minPriceInt) { + minPriceInt = item; + } + int gap = item - minPriceInt; + if (gap > maxProfitInt) { + maxProfitInt = gap; + } + } + + return maxProfitInt; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/BestTimeToBuyAndSellStockII.java b/code/LeetCode/src/BestTimeToBuyAndSellStockII.java new file mode 100644 index 00000000..24523641 --- /dev/null +++ b/code/LeetCode/src/BestTimeToBuyAndSellStockII.java @@ -0,0 +1,88 @@ +public class BestTimeToBuyAndSellStockII { + /* + Best Time to Buy and Sell Stock II + Description + Say you have an array for which the ith element is the price of a given stock on day i. + + Design an algorithm to find the maximum profit. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times). + + Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again). + + Example 1: + + Input: [7,1,5,3,6,4] + Output: 7 + Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4. + Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3. + Example 2: + + Input: [1,2,3,4,5] + Output: 4 + Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4. + Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are + engaging multiple transactions at the same time. You must sell before buying again. + Example 3: + + Input: [7,6,4,3,1] + Output: 0 + Explanation: In this case, no transaction is done, i.e. max profit = 0. + Tags: Array, Greedy + */ + + /* + 思路 + 题意是给出一个数组代表每天的股票金额,在每天只能买或卖的情况下求出收益最高值, + 这...,这也太简单了吧,把所有相邻递增的值都加起来即可。 + 实际上为greedy 贪婪算法,分析情况: + 1、如果为一直递增,那么相当于最大的减去最小的,比如[1, 4, 5], (4 - 1) + (5 - 4) = 5 - 1; + 2、如果有波峰,波谷,那么递增的则累加,比如[1, 4, 2, 8], (4 -1) + (8 - 2) + */ + public int maxProfit(int[] prices) { + int maxProfitInt = 0; + for (int i = 1; i < prices.length; i++) { + if (prices[i] > prices[i - 1]) { + maxProfitInt += (prices[i] - prices[i - 1]); + } + } + + return maxProfitInt; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/BinaryTreeLevelOrderTraversalII.java b/code/LeetCode/src/BinaryTreeLevelOrderTraversalII.java new file mode 100644 index 00000000..c21c37d9 --- /dev/null +++ b/code/LeetCode/src/BinaryTreeLevelOrderTraversalII.java @@ -0,0 +1,120 @@ +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +public class BinaryTreeLevelOrderTraversalII { + /* + Binary Tree Level Order Traversal II + Description + Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root). + + For example: + + Given binary tree [3,9,20,null,null,15,7], + + 3 + / \ + 9 20 + / \ + 15 7 + return its bottom-up level order traversal as: + + [ + [15,7], + [9,20], + [3] + ] + Tags: Tree, Breadth-first Search + */ + + /* + 思路 0 + 题意是从下往上按层遍历二叉树,每一层是从左到右,按层遍历,很明显, + 宽搜第一时间符合,因为是从下往上,所以插入的时候每次插到链表头即可。 + */ + + public List> levelOrderBottom(TreeNode root) { + if (root == null) return Collections.emptyList(); + List> list = new LinkedList<>(); + LinkedList q = new LinkedList(); + q.add(root); + while (!q.isEmpty()) { + int size = q.size(); + List subList = new LinkedList(); + for (int i = 0; i < size; i++) { + TreeNode node = q.remove(); + subList.add(node.val); + if (node.left != null) { + q.add(node.left); + } + if (node.right != null) { + q.add(node.right); + } + + } + + list.add(0, subList); + } + + return list; + } + + /* + 思路 1 + 另一种思路就是深搜,深搜的时候同时记录深度,然后在相应的层插入节点值即可。 + */ + public List> levelOrderBottomWithDeepestFirst(TreeNode root) { + List> list = new LinkedList<>(); + helperWithDeepestFirst(list, root, 0); + + return list; + } + + public void helperWithDeepestFirst(List> list, TreeNode root, int level) { + if (root == null) { + return; + } + if (level >= list.size()) { + list.add(0, new LinkedList()); + } + helperWithDeepestFirst(list, root.left, level + 1); + helperWithDeepestFirst(list, root.right, level + 1); + list.get(list.size() - level - 1).add(root.val); + + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/BrickWall.java b/code/LeetCode/src/BrickWall.java new file mode 100644 index 00000000..5bed4f8d --- /dev/null +++ b/code/LeetCode/src/BrickWall.java @@ -0,0 +1,116 @@ +import java.util.HashMap; +import java.util.List; + +public class BrickWall { + /* + Brick Wall + Description + There is a brick wall in front of you. The wall is rectangular and has several rows of bricks. The bricks have the same height but different width. You want to draw a vertical line from the top to the bottom and cross the least bricks. + + The brick wall is represented by a list of rows. Each row is a list of integers representing the width of each brick in this row from left to right. + + If your line go through the edge of a brick, then the brick is not considered as crossed. You need to find out how to draw the line to cross the least bricks and return the number of crossed bricks. + + You cannot draw a line just along one of the two vertical edges of the wall, in which case the line will obviously cross no bricks. + + Example: + + Input: + [[1,2,2,1], + [3,1,2], + [1,3,2], + [2,4], + [3,1,2], + [1,3,1,1]] + Output: 2 + Explanation: img + + Note: + + The width sum of bricks in different rows are the same and won't exceed INT_MAX. + + The number of bricks in each row is in range [1,10,000]. The height of wall is in range [1,10,000]. Total number of bricks of the wall won't exceed 20,000. + + Tags: Hash Table + */ + + /* + 思路 + 题意根据图示已经描述得很清楚了,就是在从底部到顶部,求最少交叉的数量,我们可以把每堵墙可以穿过的地方保存到哈希表中, + 每次遇到哈希表中的值加一,代表就是这条路不用交叉的数量,最终我们可以算出不用交叉的最大值,让总墙数减去其值就是最少交叉的数量。 + */ + public int leastBricks(List> wall) { + + int max = 0; + int height = 0; + HashMap vertialPassMap = new HashMap<>(); + if (wall == null) { + return 0; + } + for (List rowList: wall) { + height++; + int edgeIndex = 0; + for (int i = 0, len = rowList.size(); i < len - 1; i++) { + edgeIndex += rowList.get(i); + int indexPass = vertialPassMap.get(edgeIndex) == null ? 0 : vertialPassMap.get(edgeIndex); + vertialPassMap.put(edgeIndex, indexPass + 1); + } + } + for (Integer passNo: vertialPassMap.values()) { + if (passNo > max) { + max = passNo; + } + } + + return height - max; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/ClimbingStairs.java b/code/LeetCode/src/ClimbingStairs.java new file mode 100644 index 00000000..30516387 --- /dev/null +++ b/code/LeetCode/src/ClimbingStairs.java @@ -0,0 +1,93 @@ +public class ClimbingStairs { + /* + Climbing Stairs + Description + You are climbing a stair case. It takes n steps to reach to the top. + + Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? + + Note: Given n will be a positive integer. + + Example 1: + + Input: 2 + Output: 2 + Explanation: There are two ways to climb to the top. + 1. 1 step + 1 step + 2. 2 steps + Example 2: + + Input: 3 + Output: 3 + Explanation: There are three ways to climb to the top. + 1. 1 step + 1 step + 1 step + 2. 1 step + 2 steps + 3. 2 steps + 1 step + Tags: Dynamic Programming + */ + + /* + 思路 + 题意是爬楼梯,每次你只能爬一步或者两步,问到顶层共有多少种方案。 + 我们假设到顶层共有 f(n) 种,那么 f(n) = f(n - 1) + f(n - 2) 肯定是成立的, + 意思就是我们迈向顶层的最后一步是在倒数第一级台阶或者在倒数第二级台阶。 + 数学归纳法证明: + 初始化成立: f(0) = 1(不用走也就是1步到位), f(1) = 1, f(2) = f(0) + f(1); + 假设: f(n) = f(n - 1) + f(n - 2)成立, + 那么: f(n + 1) = f(n - 1) + f(n - 2) + f(n - 1), 所以 f(n + 1) = f(n) + f(n - 1) 成立 + 得证。 + 也就是 c = a + b; a = b; b = c; 循环即可。 + + 算法我对空间复杂度进行了优化,因为在迭代过程中只需要两个变量即可。 + 简化以后 b = a + b; a = b - a; 跟上面的等式一样,省掉了c的空间 + */ + public static int climbStairs(int n) { + int a = 1, b = 1; + while (--n > 0) { + b = b + a; + a = b - a; + } + + return b; + } + + public static void main(String[] args) { + int n1 = 2; + System.out.println("input: " + n1 + " climbStairs: " + climbStairs(n1)); + int n2 = 3; + System.out.println("input: " + n2 + " climbStairs: " + climbStairs(n2)); + int n3 = 20; + System.out.println("input: " + n3 + " climbStairs: " + climbStairs(n3)); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/ContainerWithMostWater.java b/code/LeetCode/src/ContainerWithMostWater.java new file mode 100644 index 00000000..1145acf8 --- /dev/null +++ b/code/LeetCode/src/ContainerWithMostWater.java @@ -0,0 +1,68 @@ +public class ContainerWithMostWater { + /* + Container With Most Water + Description + Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water. + + Note: You may not slant the container and n is at least 2. + + Tags: Array, Two Pointers + */ + + /* + 思路 + 题意是给你 a1, a2, ..., an 这 n 个数,代表 (i, ai) 坐标,让你从中找两个点与 x 轴围成的容器可以容纳最多的水。 + + 不明白的话可以看数据为 1 8 6 2 5 4 8 3 7 所示的图。 + + 如果用暴力法求每种情况的结果,其时间复杂度为 O(n^2),相信肯定会超时,我们可以探索下是否有更巧妙的办法呢, + 题目的标签有双指针,是否就可以想到首尾各放一指针,然后根据条件来收缩。首先计算一次首尾构成的最大面积, + 然后分析下该移动哪个指针,如果移动大的那个指针的话,那样只会减小面积,所以我们要移动小的那个指针,小的那个指针移动到哪呢? + 当然是移动到大于之前的值的地方,否则面积不都比之前小么,然后继续更新最大值即可,借助如上分析写出如下代码应该不是什么难事了吧。 + */ + + public int maxArea(int[] height) { + int max = 0; + int h = 0; + int left = 0; + int right = height.length - 1; + while (left < right) { + h = Math.min(height[left], height[right]); + max = Math.max(max, (right - left) * h); + while (height[left] <= h && left < right) { + left++; + } + while (height[right] <= h && left < right) { + right--; + } + } + + return max; + } + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/ConvertSortedArrayToBST.java b/code/LeetCode/src/ConvertSortedArrayToBST.java new file mode 100644 index 00000000..5675d9bb --- /dev/null +++ b/code/LeetCode/src/ConvertSortedArrayToBST.java @@ -0,0 +1,97 @@ +public class ConvertSortedArrayToBST { + /* + Convert Sorted Array to Binary Search Tree + Description + Given an array where elements are sorted in ascending order, convert it to a height balanced BST. + + For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1. + + Example: + + Given the sorted array: [-10,-3,0,5,9], + + One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST: + + 0 + / \ + -3 9 + / / + -10 5 + Tags: Tree, Depth-first Search + */ + + /* + 思路 + 题意是把一个有序数组转化为一棵二叉搜索树,二叉搜索树具有以下性质: + + 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值; + + 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值; + + 任意节点的左、右子树也分别为二叉查找树; + + 没有键值相等的节点。 + + 所以我们可以用递归来构建一棵二叉搜索树,每次把数组分为两半,把数组中间的值作为其父节点,然后把数组的左右两部分继续构造其左右子树。 + */ + public TreeNode sortedArrayToBST(int[] nums) { + if (nums == null || nums.length == 0) { + return null; + } + + return helper(nums, 0, nums.length - 1); + } + + public TreeNode helper(int[] nums, int leftIndex, int rightIndex) { + if (leftIndex > rightIndex) { + return null; + } + int mid = (leftIndex + rightIndex) >>> 1; + TreeNode node = new TreeNode(nums[mid]); + node.left = helper(nums, leftIndex, mid - 1); + node.right = helper(nums, mid + 1, rightIndex); + System.out.print(node.val + " "); + + return node; + } + + public static void main(String[] args) { + ConvertSortedArrayToBST bst = new ConvertSortedArrayToBST(); + int[] input = {-10,-3,0,5,9}; + bst.sortedArrayToBST(input); + + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/CountAndSay.java b/code/LeetCode/src/CountAndSay.java new file mode 100644 index 00000000..955360a0 --- /dev/null +++ b/code/LeetCode/src/CountAndSay.java @@ -0,0 +1,101 @@ +public class CountAndSay { + /* + Count and Say + Description + The count-and-say sequence is the sequence of integers with the first five terms as following: + + 1. 1 + 2. 11 + 3. 21 + 4. 1211 + 5. 111221 + 1 is read off as "one 1" or 11. + + 11 is read off as "two 1s" or 21. + + 21 is read off as "one 2, then one 1" or 1211. + + Given an integer n, generate the nth term of the count-and-say sequence. + + Note: Each term of the sequence of integers will be represented as a string. + + Example 1: + + Input: 1 + Output: "1" + Example 2: + + Input: 4 + Output: "1211" + Tags: String + */ + + /* + 思路 + 题意是数和说,根据如下序列 1, 11, 21, 1211, 111221, ...,求第 n 个数,规则很简单,就是数和说,数就是数这个数数字有几个, + 说就是说这个数,所以 1 就是 1 个 1:11,11 就是有 2 个 1:21,21 就是 1 个 2、1 个 1:1211,可想而知后面就是 111221, + 思路的话就是按这个逻辑模拟出来即可。 + */ + + public static String countAndSay(int n) { + if (n == 0) { + return ""; + } + String str = "1"; + while (--n > 0) { + int times = 1; + StringBuilder sb = new StringBuilder(); + char[] chars = str.toCharArray(); + int len = chars.length; + for (int i = 1; i < len; i++) { + if (chars[i] == chars[i - 1]) { + times++; + } else { + sb.append(times).append(chars[i - 1]); + times = 1; + } + } + str = sb.append(times).append(chars[len - 1]).toString(); + } + + + return str; + } + + public static void main(String[] args) { + int input1 = 1; + int input2 = 2; + int input3 = 3; + int input4 = 4; + int input5 = 5; + int input6 = 20; + System.out.println("input: " + input1 + " result: " + countAndSay(input1)); + System.out.println("input: " + input2 + " result: " + countAndSay(input2)); + System.out.println("input: " + input3 + " result: " + countAndSay(input3)); + System.out.println("input: " + input4 + " result: " + countAndSay(input4)); + System.out.println("input: " + input5 + " result: " + countAndSay(input5)); + System.out.println("input: " + input6 + " result: " + countAndSay(input6)); + } + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/DiameterOfBinaryTree.java b/code/LeetCode/src/DiameterOfBinaryTree.java new file mode 100644 index 00000000..e927456e --- /dev/null +++ b/code/LeetCode/src/DiameterOfBinaryTree.java @@ -0,0 +1,92 @@ +public class DiameterOfBinaryTree { + /* + Diameter of Binary Tree + Description + Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a binary tree is the length of the longest path between any two nodes in a tree. This path may or may not pass through the root. + + Example: Given a binary tree + + 1 + / \ + 2 3 + / \ + 4 5 + Return 3, which is the length of the path [4,2,1,3] or [5,2,1,3]. + + Note: The length of path between two nodes is represented by the number of edges between them. + + Tags: Tree + */ + + /* + 思路 + 题意是让你算出二叉树中最远的两个节点的距离,分别计算左右子树的最大高度, + 然后不断迭代出其和的最大值就是最终结果。 + */ + + int max = 0; + + public int diameterOfBinaryTree(TreeNode root) { + helper(root); + + return max; + } + + public int helper(TreeNode node) { + if (node == null) { + return 0; + } + int leftInt = helper(node.left); + int rightInt = helper(node.right); + int distance = leftInt + rightInt; + if (distance > max) { + max = distance; + } + return 1 + Math.max(leftInt, rightInt); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/DivideTwoIntegers.java b/code/LeetCode/src/DivideTwoIntegers.java new file mode 100644 index 00000000..e11030fb --- /dev/null +++ b/code/LeetCode/src/DivideTwoIntegers.java @@ -0,0 +1,115 @@ +public class DivideTwoIntegers { + /* + Divide Two Integers + Description + Given two integers dividend and divisor, divide two integers without using multiplication, division and mod operator. + + Return the quotient after dividing dividend by divisor. + + The integer division should truncate toward zero. + + Example 1: + + Input: dividend = 10, divisor = 3 + Output: 3 + Example 2: + + Input: dividend = 7, divisor = -3 + Output: -2 + Note: + + Both dividend and divisor will be 32-bit signed integers. + The divisor will never be 0. + Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231, 231 − 1]. For the purpose of this problem, assume that your function returns 231 − 1 when the division result overflows. + Tags: Math, Binary Search + */ + + /* + 思路 + 题意是让你算两个整型数相除后的结果,如果结果溢出就返回 MAX_INT,但不能使用乘、除、余的操作符, + 如果是用加减操作符的话肯定会超时哈,这样的话我们就只能想到位操作符了。 + + 首先,我们分析下溢出的情况,也就是当被除数为 Integer.MIN_VALUE,除数为 -1 时会溢出, + 因为 |Integer.MIN_VALUE| = Integer.MAX_VALUE + 1。 + + 然后,我们把除数和被除数都转为 long 类型的正数去做下一步操作,我这里以 22 和 3 相除为例子,因为 22 >= 3, + 我们对 3 进行左移一位,也就是乘 2,结果为 6,比 22 小,我们继续对 6 左移一位结果为 12,还是比 22 小, + 我们继续对 12 左移一位为 24,比 22 大,这时我们可以分析出,22 肯定比 3 的 4 倍要大,4 是怎么来的? + 因为我们左移了两次,也就是 1 << 2 = 4,此时我们记下这个 4,然后让 22 - 3 * 4 = 10, + 因为 10 >= 3,对 10 和 3 进行同样的操作,我们可以得到 2,此时加上上次的 4,和为 6, + 也就是 22 比 3 的 6 倍要大,此时还剩余 10 - 6 = 4,因为 4 >= 3,所以对 4 和 3 进行同样的操作, + 我们发现并不能对 3 进行左移了,因为 4 >= 3,所以 1 倍还是有的,所以加上最后的 1,结果为 6 + 1 = 7, + 也就是 22 整除 3 结果为 7。 + + 最终,我们对结果赋予符号位即可,根据以上思路来书写如下代码应该不是难事了吧。 + */ + + public int divide(int dividend, int divisor) { + if (dividend == Integer.MIN_VALUE && divisor == -1) { + return Integer.MAX_VALUE; + } + long dividendL = Math.abs((long)dividend); + long divisorL = Math.abs((long)divisor); + int result = 0; + while (dividendL >= divisorL) { + int multiplier = 1; + long increace = divisorL; + while (dividendL >= (increace << 1)) { + increace <<= 1; + multiplier <<= 1; + } + + dividendL -= increace; + result += multiplier; + } + + return (dividend > 0) ^ (divisor > 0) ? -result : result; + } + + public static void main(String[] args) { + DivideTwoIntegers obj = new DivideTwoIntegers(); + int dividend = 22; + int divisor = 3; + System.out.println("dividend: " + dividend + " ;divisor: " + divisor + " result: " + obj.divide(dividend, divisor)); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/FourSum.java b/code/LeetCode/src/FourSum.java new file mode 100644 index 00000000..c22413ea --- /dev/null +++ b/code/LeetCode/src/FourSum.java @@ -0,0 +1,216 @@ +import java.util.*; + +public class FourSum { + /* + 4Sum + Description + Given an array numsof n integers and an integer target, there are Elements has , b , c , and d in numsSuch That a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target. + + Note: + + The solution set must not contain duplicate quadruplets. + + example: + + Given array nums = [1, 0, -1, 0, -2, 2], and target = 0. + + A solution set is: + [ + [-1, 0, 0, 1], + [-2, -1, 1, 2], + [-2, 0, 0, 2] + ] + Tags: Array, Hash Table, Two Pointers + */ + + /* + 思路 0 + 意是让你题从数组中找出所有四个数的和为target的元素构成的非重复序列,该题和3sum的思路基本一样, + 先对数组进行排序,然后遍历这个排序数组,因为这次是四个元素的和,所以外层需要两重循环, + 然后还是用两个指针分别指向当前元素的下一个和数组尾部,四者的和判断与target的大小来移动两个指针, + 其中细节操作还是优化和去重. + */ + + public List> fourSum(int[] nums, int target) { + int len = nums.length; + if (len < 4) { + return Collections.emptyList(); + } + Arrays.sort(nums); + int max = nums[len - 1]; + if (max * 4 < target) { + return Collections.emptyList(); + } + List> resultList = new ArrayList>(); + int fistMaxIndex = len - 3; + //最小 + for (int i = 0; i < fistMaxIndex; ) { + //最小累加都大于target, 则退出 + if (nums[i] * 4 > target) { + break; + } + //最小太小,则跳过 + if (nums[i] + max * 3 < target) { + while (nums[i] == nums[++i] && i < fistMaxIndex) { } + continue; + } + + int secondMaxIndex = len - 2; + for (int j = i + 1; j < secondMaxIndex; ) { + int subTwo = nums[i] + nums[j]; + //最小累加都大于target, 则退出 + if (subTwo + nums[j] * 2 > target) { + break; + } + ////最小太小,则跳过 + if (subTwo + max * 2 < target) { + while (nums[j] == nums[++j] && j < secondMaxIndex) { } + continue; + } + + int left = j + 1; int right = len - 1; + while (left < right) { + if (subTwo + nums[left] + nums[right] == target) { + resultList.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right])); + while (nums[left] == nums[++left] && left < right) { } + while (nums[right] == nums[--right] && left < right) { } + } else if (subTwo + nums[left] + nums[right] < target) { + while (nums[left] == nums[++left] && left < right) { } + } else { + while (nums[right] == nums[--right] && left < right) { } + } + } + + while (nums[j] == nums[++j] && j < secondMaxIndex) { } + } + + while (nums[i] == nums[++i] && i < fistMaxIndex) { } + } + + + return resultList; + } + + /* + 思路 1 + 从Two Sum , 3sum到现在的4Sum,其实都是把高阶降为低阶,那么我们就可以写出kSum的函数来对其进行降阶处理, + 降到2Sum后那么我们就可以对其进行最后的判断了,代码如下所示,其也做了相应的优化和去重. + */ + public List> fourSumByDegreeDimension(int[] nums, int target) { + int len = nums.length; + if (len < 4) { + return Collections.emptyList(); + } + Arrays.sort(nums); + int max = nums[len - 1]; + if (max * 4 < target) { + return Collections.emptyList(); + } + List> resultList = helperSum(nums, 0, 4, target); + + return resultList; + } + + private List> helperSum(int[] nums, int start, int capacity, int target) { + List> qualifiedList = new ArrayList<>(); + int len = nums.length; + int max = nums[len - 1]; + + if (capacity == 2) { + int left = start; + int right = nums.length - 1; + while (left < right) { + if (nums[left] * 2 > target) { + break; + } + if (nums[left] + nums[right] == target) { +// qualifiedList.add(Arrays.asList(nums[left], nums[right])); + List twoSum = new LinkedList<>(); + twoSum.add(nums[left]); + twoSum.add(nums[right]); + qualifiedList.add(twoSum); + while (nums[left] == nums[++left] && left < right) { } + while (nums[right] == nums[--right] && left < right) { } + } else if (nums[left] + nums[right] < target) { + while (nums[left] == nums[++left] && left < right) { } + } else { + while (nums[right] == nums[--right] && left < right) { } + } + } + + } else { + int end = len - (capacity - 1); + + for (int i = start; i < end; ) { + //太大的时候退出 + if (nums[i] * capacity > target) { + break; + } + //太小的时候,+1 + if (nums[i] + max * (capacity - 1) < target) { + while (nums[i] == nums[++i] && i < end) { } + continue; + } + List> tempList = helperSum(nums, i+1, capacity - 1, target - nums[i]); + for (List subList: tempList) { + subList.add(0, nums[i]); + } + qualifiedList.addAll(tempList); + while (nums[i] == nums[++i] && i < end) { } + } + + } + + return qualifiedList; + } + + public static void main(String[] args) { + int[] input = {1, 0, -1, 0, -2, 2}; + int target = 0; + FourSum obj = new FourSum(); +// List> resultList = obj.fourSum(input, target); + List> resultList = obj.fourSumByDegreeDimension(input, target); + + System.out.print("output: " + resultList); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/GenerateParentheses.java b/code/LeetCode/src/GenerateParentheses.java new file mode 100644 index 00000000..063ca953 --- /dev/null +++ b/code/LeetCode/src/GenerateParentheses.java @@ -0,0 +1,140 @@ +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +public class GenerateParentheses { + /* + Generate Parentheses + Description + Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. + + For example, given n = 3, a solution set is: + + [ + "((()))", + "(()())", + "(())()", + "()(())", + "()()()" + ] + Tags: String, Backtracking + */ + + /* + 思路 0 + 题意是给你 n 值,让你找到所有格式正确的圆括号匹配组,题目中已经给出了 n = 3 的所有结果。 + 遇到这种问题,第一直觉就是用到递归或者堆栈,我们选取递归来解决,也就是 helper 函数的功能, + 从参数上来看肯定很好理解了,leftRest 代表还有几个左括号可以用,rightNeed 代表还需要几个右括号才能匹配, + 初始状态当然是 rightNeed = 0, leftRest = n,递归的终止状态就是 rightNeed == 0 && leftRest == 0, + 也就是左右括号都已匹配完毕,然后把 str 加入到链表中即可。 + */ + + public List generateParenthesis(int n) { + List list = new ArrayList(); + helper(list, "", 0, n); + + return list; + } + + private void helper(List list, String tempStr, int rightNeed, int leftRest) { + if (leftRest == 0 && rightNeed == 0) { + list.add(tempStr); + return; + } + if (rightNeed > 0) { + helper(list, tempStr + ")", rightNeed - 1, leftRest); + } + if (leftRest > 0) { + helper(list, tempStr + "(", rightNeed + 1, leftRest - 1); + } + } + + /* + 思路 1 + 另一种实现方式就是迭代的思想了,我们来找寻其规律如下所示: + + f(0): “” + + f(1): “(“f(0)”)” + + f(2): "(“f(0)”)"f(1), “(“f(1)”)” + + f(3): "(“f(0)”)"f(2), "(“f(1)”)"f(1), “(“f(2)”)” + ... + 可以递推出 f(n) = "(“f(0)”)"f(n-1) , "(“f(1)”)"f(n-2) "(“f(2)”)"f(n-3) … "(“f(i)”)“f(n-1-i) … “(f(n-1)”)” + + 根据如上递推式写出如下代码应该不难了吧。 + */ + public List generateParenthesisByIterator(int n) { + HashMap> queueListMap = new HashMap>(); + queueListMap.put(0, Collections.singletonList("")); + for (int i = 1; i <= n ; i++) { + List list = new ArrayList(); + for (int j = 0; j < i; j++) { + for (String itemJ: queueListMap.get(j)) { + for (String itemIMinusJ: queueListMap.get(i - j - 1)) { + list.add("(" + itemJ + ")" + itemIMinusJ); + } + } + } + queueListMap.put(i, list); + } + + return queueListMap.get(n); + } + + public static void main(String[] args) { + GenerateParentheses obj = new GenerateParentheses(); + int input = 4; +// List list = obj.generateParenthesis(input); + List list = obj.generateParenthesisByIterator(input); + System.out.print("input: " + input + " list count: " + list.size()); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/GroupAnagrams.java b/code/LeetCode/src/GroupAnagrams.java new file mode 100644 index 00000000..dc664601 --- /dev/null +++ b/code/LeetCode/src/GroupAnagrams.java @@ -0,0 +1,97 @@ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +public class GroupAnagrams { + /* + Group Anagrams + Description + Given an array of strings, group anagrams together. + + Example: + + Input: ["eat", "tea", "tan", "ate", "nat", "bat"], + Output: + [ + ["ate","eat","tea"], + ["nat","tan"], + ["bat"] + ] + Note: + + All inputs will be in lowercase. + The order of your output does not matter. + Tags: Hash Table, String + */ + + /* + 思路 + 题意是给你一组字符串,让你把其中同位异构字符串分组,同位异构字符串就是组成字符串的字符都相同, + 但是字符放的位置可以不同。既然要分组,那么关键就是如何确定他们是同位异构字符串呢,想到的自然就是对其排序, + 排序之后他们就都是同一个字符串了,就可以归为一类了,代码如下所示。 + */ + public List> groupAnagrams(String[] strs) { + HashMap map = new HashMap(); + List> resultList = new ArrayList<>(); + int i = 0; + for (String item: strs) { + char[] chars = item.toCharArray(); + Arrays.sort(chars); + String sortItem = String.valueOf(chars); + if (!map.containsKey(sortItem)) { + map.put(sortItem, i++); + ArrayList subList = new ArrayList<>(); + subList.add(item); + resultList.add(subList); + } else { + resultList.get(map.get(sortItem)).add(item); + } + } + + return resultList; + } + + public static void main(String[] args) { + GroupAnagrams obj = new GroupAnagrams(); + String[] input = {"eat", "tea", "tan", "ate", "nat", "bat"}; + List> resultList = obj.groupAnagrams(input); + System.out.println("input: " + Arrays.toString(input)); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/HeapOperator.java b/code/LeetCode/src/HeapOperator.java new file mode 100644 index 00000000..77c2d249 --- /dev/null +++ b/code/LeetCode/src/HeapOperator.java @@ -0,0 +1,137 @@ +import java.util.Arrays; + +/** + * 最小堆, 例子🌰 + * 1 + * 2 3 + * 4 5 6 + */ +public class HeapOperator { + + /** + * 上浮:改变最后一个值,上浮使其成为最小堆 + * @param array 待调整的堆 + */ + public static void upAdjust(int[] array) { + int childIndex = array.length - 1; + int parentIndex = (childIndex -1 ) / 2; + int temp = array[childIndex]; + while (childIndex > 0 && temp < array[parentIndex]) { + //无需真正交换,单项赋值即可 + array[childIndex] = array[parentIndex]; + childIndex = parentIndex; + parentIndex = (parentIndex - 1) / 2; + } + array[childIndex] = temp; + + } + + /** + * 下沉:父节点与两个子节点中小的比较,父节点 > 小的子节点, 则替换 + * @param array 待调整的堆 + * @param parentIndex 要下沉的父节点 + * @param length 堆的有效大小 + */ + public static void downAdjust(int[] array, int parentIndex, int length) { + int childIndex = parentIndex * 2 + 1; + int temp = array[parentIndex]; + while (childIndex < length) { + if (childIndex + 1 < length && array[childIndex + 1] < array[childIndex]) { + childIndex++; + } + + if (temp <= array[childIndex]) { + break; + } + + array[parentIndex] = array[childIndex]; + parentIndex = childIndex; + childIndex = childIndex * 2 + 1; + } + array[parentIndex] = temp; + } + + /** + * 建堆 + * @param array 待调整的堆 + */ + public static void buildHeap(int[] array) { + // 从最后一个非叶子节点开始,依次下沉调整 + int length = array.length; + int lastIndex = length -1; + int parentIndex = (lastIndex - 1) / 2; + for (int i = parentIndex; i >= 0; i--) { + downAdjust(array, i, length); + } + } + + /** + * 堆排序 + * @param array + */ + public static void heapSort(int[] array) { + //建堆 + buildHeap(array); + System.out.println(Arrays.toString(array)); + + int length = array.length; + int lastIndex = length -1; + + for (int i = lastIndex; i > 0 ; i--) { + // 把第一个跟最后一个交换 + int temp = array[i]; + array[i] = array[0]; + array[0] = temp; + + downAdjust(array, 0, i); + } + } + + public static void main(String[] args) { +// int[] array = new int[]{1,3,2,6,5,7,8,9,10,0}; +// upAdjust(array); +// System.out.println(Arrays.toString(array)); +// +// array = new int[] {7,1,3,10,5,2,8,9,6}; +// buildHeap(array); +// System.out.println(Arrays.toString(array)); + + int[] arr = new int[] {1,3,2,6,5,7,8,9,10,0}; + heapSort(arr); + System.out.println(Arrays.toString(arr)); + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/code/LeetCode/src/ImplementStrStr.java b/code/LeetCode/src/ImplementStrStr.java new file mode 100644 index 00000000..eef99b8b --- /dev/null +++ b/code/LeetCode/src/ImplementStrStr.java @@ -0,0 +1,55 @@ +public class ImplementStrStr { + /* + Implement strStr(). + + Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. + + Example 1: + + Input: haystack = "hello", needle = "ll" + Output: 2 + Example 2: + + Input: haystack = "aaaaa", needle = "bba" + Output: -1 + Clarification: + + What should we return when needle is an empty string? This is a great question to ask during an interview. + + For the purpose of this problem, we will return 0 when needle is an empty string. This is consistent to C's strstr() and Java's indexOf(). + */ + + /* + 思路 + 题意是从主串中找到子串的索引,如果找不到则返回-1,当子串长度大于主串,直接返回-1,然后我们只需要遍历比较即可。 + */ + public static int strStr(String haystack, String needle) { + int haystackLen = haystack.length(); + int needleLen = needle.length(); + if (haystackLen < needleLen) { + return -1; + } + for (int i = 0; ; i++) { + if (i + needleLen > haystackLen) { + return -1; + } + for (int j = 0; ; j++) { + if (j == needleLen) { + return i; + } + if (haystack.charAt(i+j) != needle.charAt(j)) { + break; + } + } + } + } + + public static void main(String[] args) { + String haystack1 = "hello", needle1 = "ll"; + System.out.println("haystack: " + haystack1 + "; needle: " + needle1 + "; resullt: " + strStr(haystack1, needle1)); + String haystack2 = "aaaaa", needle2 = "bba"; + System.out.println("haystack: " + haystack2 + "; needle: " + needle2 + "; resullt: " + strStr(haystack2, needle2)); + } + + +} diff --git a/code/LeetCode/src/InsertInterval.java b/code/LeetCode/src/InsertInterval.java new file mode 100644 index 00000000..500296d1 --- /dev/null +++ b/code/LeetCode/src/InsertInterval.java @@ -0,0 +1,127 @@ +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class InsertInterval { + /* + Insert Interval + Description + Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary). + + You may assume that the intervals were initially sorted according to their start times. + + Example 1: + + Input: intervals = [[1,3],[6,9]], newInterval = [2,5] + Output: [[1,5],[6,9]] + Example 2: + + Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8] + Output: [[1,2],[3,10],[12,16]] + Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10]. + Tags: Array, Sort + */ + + /* + 思路 + 题意是给你一组有序区间,和一个待插入区间,让你待插入区间插入到前面的区间中,我们分三步走: + + 首先把有序区间中小于待插入区间的部分加入到结果中; + + 其次是插入待插入区间,如果有交集的话取两者交集的端点值; + + 最后把有序区间中大于待插入区间的部分加入到结果中; + */ + + public List insert(List intervals, Interval newInterval) { + if (intervals.isEmpty()) { + return Collections.singletonList(newInterval); + } + List resultList = new ArrayList(); + int i = 0; + //less than + for( ; i < intervals.size(); i++) { + Interval item = intervals.get(i); + if (item.end < newInterval.start) { + resultList.add(item); + } else { + break; + } + } + + //cross area + for ( ; i < intervals.size(); i++) { + Interval item = intervals.get(i); + if (item.start <= newInterval.end) { + newInterval.start = Math.min(item.start, newInterval.start); + newInterval.end = Math.max(item.end, newInterval.end); + } else { + break; + } + } + + resultList.add(newInterval); + + //more than + for ( ; i < intervals.size(); i++) { + resultList.add(intervals.get(i)); + } + + return resultList; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/IntegerToRoman.java b/code/LeetCode/src/IntegerToRoman.java new file mode 100644 index 00000000..7c1088e3 --- /dev/null +++ b/code/LeetCode/src/IntegerToRoman.java @@ -0,0 +1,108 @@ +public class IntegerToRoman { + /* + Integer to Roman + Description + Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M. + + Symbol Value + I 1 + V 5 + X 10 + L 50 + C 100 + D 500 + M 1000 + For example, two is written as II in Roman numeral, just two one's added together. Twelve is written as, XII, which is simply X + II. The number twenty seven is written as XXVII, which is XX + V + II. + + Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used: + + I can be placed before V (5) and X (10) to make 4 and 9. + X can be placed before L (50) and C (100) to make 40 and 90. + C can be placed before D (500) and M (1000) to make 400 and 900. + Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999. + + Example 1: + + Input: 3 + Output: "III" + Example 2: + + Input: 4 + Output: "IV" + Example 3: + + Input: 9 + Output: "IX" + Example 4: + + Input: 58 + Output: "LVIII" + Explanation: C = 100, L = 50, XXX = 30 and III = 3. + Example 5: + + Input: 1994 + Output: "MCMXCIV" + Explanation: M = 1000, CM = 900, XC = 90 and IV = 4. + Tags: Math, String + */ + + /* + 思路 + 题意是整型数转罗马数字,范围从 1 到 3999,查看下百度百科的罗马数字介绍如下: + + 相同的数字连写,所表示的数等于这些数字相加得到的数,如 Ⅲ=3; + + 小的数字在大的数字的右边,所表示的数等于这些数字相加得到的数,如 Ⅷ=8、Ⅻ=12; + + 小的数字(限于 Ⅰ、X 和 C)在大的数字的左边,所表示的数等于大数减小数得到的数,如 Ⅳ=4、Ⅸ=9。 + + 那么我们可以把整数的每一位分离出来,让其每一位都用相应的罗马数字位表示,最终拼接完成。比如 621 我们可以分离百、十、个分别为 6、2、1,那么 600 对应的罗马数字是 DC,20 对应的罗马数字是 XX,1 对应的罗马数字是 I,所以最终答案便是 DCXXI。 + */ + + public String intToRoman(int num) { + String[] m = {"", "M", "MM", "MMM"}; + String[] c = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"}; + String[] x = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"}; + String[] i = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"}; + + return m[num / 1000] + c[(num % 1000) / 100] + x[(num % 100) / 10] + i[num % 10]; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/Interval.java b/code/LeetCode/src/Interval.java new file mode 100644 index 00000000..173add88 --- /dev/null +++ b/code/LeetCode/src/Interval.java @@ -0,0 +1,13 @@ +public class Interval { + int start; + int end; + Interval() { + start = 0; + end = 0; + } + + Interval(int s, int e) { + start = s; + end = e; + } +} diff --git a/code/LeetCode/src/LengthOfLastWord.java b/code/LeetCode/src/LengthOfLastWord.java new file mode 100644 index 00000000..1808a927 --- /dev/null +++ b/code/LeetCode/src/LengthOfLastWord.java @@ -0,0 +1,72 @@ +public class LengthOfLastWord { + /* + Length of Last Word + Description + Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string. + + If the last word does not exist, return 0. + + Note: A word is defined as a character sequence consists of non-space characters only. + + Example: + + Input: "Hello World" + Output: 5 + Tags: String + */ + + /* + 思路 + 题意是让你从一个只包含大小字母和空格字符的字符串中得到最后一个单词的长度,很简单, + 我们倒序遍历,先得到最后一个非空格字符的索引,然后再得到它前面的空格字符索引,两者相减即可。 + 当然,我们使用 API 来完成这件事更加方便,只需一行代码 return s.trim().length() - s.trim().lastIndexOf(" ") - 1;, + 但我相信作者出这道题的目的肯定不是考你 API 的使用,所以我们还是用自己的思路来实现。 + */ + + public static int lengthOfLastWord(String s) { + int lastIndex = s.length() - 1; + while(lastIndex >= 0 && s.charAt(lastIndex) == ' ') { + lastIndex--; + } + int end = lastIndex; + while (lastIndex >= 0 && s.charAt(lastIndex) != ' ') { + lastIndex--; + } + + return end - lastIndex; + } + + public static void main(String[] args) { + String input1 = "Hello World"; + String input2 = "a"; + System.out.println("input: " +input1+ " ,output: " + lengthOfLastWord(input1)); + System.out.println("input: " +input2+ " ,output: " + lengthOfLastWord(input2)); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/LetterCombinationsOfAPhoneNumber.java b/code/LeetCode/src/LetterCombinationsOfAPhoneNumber.java new file mode 100644 index 00000000..a6329055 --- /dev/null +++ b/code/LeetCode/src/LetterCombinationsOfAPhoneNumber.java @@ -0,0 +1,125 @@ +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +public class LetterCombinationsOfAPhoneNumber { + /* + Letter Combinations of a Phone Number + Description + Given a digit string, return all possible letter combinations that the number could represent. + + A mapping of digit to letters (just like on the telephone buttons) is given below. + + img + + Example: + + Input: "23" + Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. + Note: + + Although the above answer is in lexicographical order, your answer could be in any order you want. + + Tags: String, Backtracking + */ + + /* + 思路 0 + 题意是给你按键,让你组合出所有不同结果,首先想到的肯定是回溯了,对每个按键的所有情况进行回溯, + 回溯的终点就是结果字符串长度和按键长度相同。 + */ + static final String[] lettersArray = new String[]{"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; + + public List letterCombinations(String digits) { + if (digits == null || digits.length() == 0) { + return Collections.emptyList(); + } + int len = digits.length(); + List resultList = new ArrayList(); + helper(resultList, digits, ""); + + return resultList; + } + + public void helper(List list, String digits, String letters) { + if (digits.length() == letters.length()) { + list.add(letters); + return; + } + + for (char c: lettersArray[digits.charAt(letters.length()) - '2'].toCharArray()) { + helper(list, digits, letters + c); + } + } + + /* + 思路 1 + 还有一种思路就是利用队列,根据上一次队列中的值,该值拼接当前可选值来不断迭代其结果,具体代码如下。 + */ + public List letterCombinationsWithQueue(String digits) { + if (digits == null || digits.length() == 0) { + return Collections.emptyList(); + } + int len = digits.length(); + char[] digitArray = digits.toCharArray(); + LinkedList resultList = new LinkedList(); + resultList.add(""); + for (int i = 0; i < len; i++) { + char digit = digitArray[i]; + while (resultList.getFirst().length() == i) { + String pop = resultList.removeFirst(); + for (char c: lettersArray[digit - '2'].toCharArray()) { + resultList.addLast(pop + c); + } + } + } + + return resultList; + } + + + public static void main(String[] args) { + String input = "23"; + + LetterCombinationsOfAPhoneNumber obj = new LetterCombinationsOfAPhoneNumber(); +// List list = obj.letterCombinations(input); + List list = obj.letterCombinationsWithQueue(input); + System.out.println(list); + + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/ListNode.java b/code/LeetCode/src/ListNode.java new file mode 100644 index 00000000..a6eb17f1 --- /dev/null +++ b/code/LeetCode/src/ListNode.java @@ -0,0 +1,7 @@ +public class ListNode { + int val; + ListNode next; + ListNode(int x) { + val = x; + } +} diff --git a/code/LeetCode/src/LongestCommonPrefix.java b/code/LeetCode/src/LongestCommonPrefix.java new file mode 100644 index 00000000..b91e4688 --- /dev/null +++ b/code/LeetCode/src/LongestCommonPrefix.java @@ -0,0 +1,59 @@ +public class LongestCommonPrefix { + /* + Longest Common Prefix + Description + Write a function to find the longest common prefix string amongst an array of strings. + + If there is no common prefix, return an empty string "". + + Example 1: + + Input: ["flower","flow","flight"] + Output: "fl" + Example 2: + + Input: ["dog","racecar","car"] + Output: "" + Explanation: There is no common prefix among the input strings. + Note: + + All given inputs are in lowercase letters a-z. + + Tags: String + */ + + /* + 思路 + 题意是让你从字符串数组中找出公共前缀,我的想法是找出最短的那个字符串的长度 minLen, + 然后在 0...minLen 的范围比较所有字符串,如果比较到有不同的字符,那么直接返回当前索引长度的字符串即可, + 否则最后返回最短的字符串即可。 + */ + public static String longestCommonPrefix(String[] strs) { + int len = strs.length; + if (len == 0) { + return ""; + } + + int minLenght = Integer.MAX_VALUE; + for (String item : strs) { + minLenght = Integer.min(minLenght, item.length()); + } + + for (int j = 0; j < minLenght; ++j) { + for (int i = 1; i < len; ++i) { + if (strs[0].charAt(j) != strs[i].charAt(j)) { + return strs[0].substring(0, j); + } + } + } + + return strs[0].substring(0, minLenght); + } + + public static void main(String[] args) { + String[] inputList = {"flower","flow","flight"}; + System.out.println("input: " +"'flower','flow','flight'"+ " commonPrefix: " + longestCommonPrefix(inputList)); + } + + +} diff --git a/code/LeetCode/src/LongestPalindromicSubstring.java b/code/LeetCode/src/LongestPalindromicSubstring.java new file mode 100644 index 00000000..ff949feb --- /dev/null +++ b/code/LeetCode/src/LongestPalindromicSubstring.java @@ -0,0 +1,219 @@ +public class LongestPalindromicSubstring { + /* + Longest Palindromic Substring + Description + Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. + + Example 1: + + Input: "babad" + + Output: "bab" + + Note: "aba" is also a valid answer. + Example 2: + + Input: "cbbd" + + Output: "bb" + Tags: String, Dynamic Programming + */ + + /* + 思路 0 + 题意是寻找出字符串中最长的回文串,所谓回文串就是正序和逆序相同的字符串,也就是关于中间对称。 + 我们先用最常规的做法,依次去求得每个字符的最长回文,要注意每个字符有奇数长度的回文串和偶数长度的回文串两种情况, + 相信你可以很轻易地从如下代码中找到相关代码,记录最长回文的始末位置即可, + 时间复杂度的话,首先要遍历一遍字符串,然后对每个字符都去求得最长回文,所以时间复杂度为 O(n^2)。 + */ + int start = 0, end = 0; + public String longestPalindrome(String s) { + int length = s.length(); + if (length <= 1) { + return s; + } + char[] charArray = s.toCharArray(); + for (int i = 0; i < length; i++) { + helper(charArray, i, i); + helper(charArray, i, i + 1); + } + + return s.substring(start, end + 1); + } + + public void helper(char[] charArray, int leftInt, int rightInt) { + while (leftInt >= 0 && rightInt < charArray.length && charArray[leftInt] == charArray[rightInt]) { + leftInt--; + rightInt++; + } + if (end - start < rightInt - leftInt - 2) { + start = leftInt + 1; + end = rightInt - 1; + } + } + + /* + 如果利用暴力法遍历所有字串是否回文的情况这道题肯定是 Time Limit Exceeded 的,那么我们是否可以把之前遍历的结果利用上呢,那么动态规划的想法就呼之欲出了,我们定义 dp[i][j] 的意思为字符串区间 [i, j] 是否为回文串,那么我们分三种情况: + + 当 i == j 时,那么毫无疑问 dp[i][j] = true; + + 当 i + 1 == j 时,那么 dp[i][j] 的值取决于 s[i] == s[j]; + + 当 i + 1 < j 时,那么 dp[i][j] 的值取决于 dp[i + 1][j - 1] && s[i] == s[j]。 + + 根据以上的动态转移方程,我们的问题即可迎刃而解,时间复杂度的话显而易见,也是 O(n^2)。 + */ + public String longestPalindromeWithDynamic(String s) { + int length = s.length(); + if (length <= 1) { + return s; + } + char[] charArray = s.toCharArray(); + int start = 0, end = 0; + boolean[][] dynamicZoomFlag = new boolean[length][length]; + for (int i = 0; i < length; i++) { + dynamicZoomFlag[i][i] = true; + for (int j = 0; j < i; j++) { + if (j + 1 == i) { + dynamicZoomFlag[j][i] = charArray[j] == charArray[i]; + } else { + dynamicZoomFlag[j][i] = dynamicZoomFlag[j+1][i-1] && charArray[j] == charArray[i]; + } + if (dynamicZoomFlag[j][i] && i - j > end - start) { + start = j; + end = i; + } + } + + } + + return s.substring(start, end + 1); + } + + /* + 思路 2 + 马拉车算法(Manacher's Algorithm) + + 背景 + 给定一个字符串,求出其最长回文子串(回文字符串就是从左到右读和从右往左读完全一样,也就是字符串关于中间对称)。例如: + + s = "babad",最长回文长度为 3,可以是 bab 或者 aba; + + s = "cbbda",最长回文长度为 2,即 bb; + + s = "abcde",最长回文长度为 1,即单个字符本身。 + + 这个问题等同于 LeetCode 上的 Longest Palindromic Substring,其相关题解可以查看这里:传送门 + + 以上问题的传统思路大概是遍历每一个字符,以该字符为中心向两边查找,其时间复杂度为 O(n^2),效率很差。 + + 1975 年,一个叫 Manacher 的人发明了 Manacher 算法(中文名:马拉车算法),该算法可以把时间复杂度提升到 O(n),下面我以我理解的思路来讲解其原理。 + + 分析 + 由于回文串的奇偶行不确定,比如 lol 是奇回文,而 lool 是偶回文,马拉车算法的第一步就是对其进行预处理,做法就是在每个字符两侧都加上一个特殊字符,一般就是不会出现在原串中的即可,我们可以选取 #,那么 + + lol -> #l#o#l# + lool -> #l#o#o#l# + 这样处理后,不管原来字符串长度是奇数还是偶数,最终得到的长度都将是奇数,从而能把两种情况合并起来一起考虑,记预处理后的字符串为 str。 + + 我们把一个回文串中最左或最右位置的字符与其对称轴的距离称为回文半径。 + + 马拉车算法定义了一个回文半径数组 len,用 len[i] 表示以第 i 个字符为对称轴的回文串的回文半径,比如以 str[i] 为中心的最长回文串是 str[l, r],那么 len[i] = r - i + 1 + + 我们以 lollool 为例,参看下表。 + + str # l # o # l # l # o # o # l # + len[] 1 2 1 4 l 2 5 2 1 2 5 2 1 2 1 + 可以发现 len[i] - 1 就等于该回文串在原串中的长度。 + + 证明:在转换后的字符串 str 中,那么对于以 str[i] 为中心的最长回文串的长度为 2 * len[i] - 1,其中又有 len[i] 个分隔符,所以在原字符串中的回文串长度就是 len[i] - 1。 + + 那么我们剩下的工作就是求 len 数组。 + + 为了防止数组越界,我们在首位再加上非 # 的不常用字符,比如 ~,那么 lollool 就表示为 ~#l#o#l#l#o#o#l#~,这样我们就省去写很多 if else 的边界处理。 + */ + public String longestPalindromeWithManacher(String s) { + int length = s.length(); + if (length <= 1) { + return s; + } + char[] charArray = s.toCharArray(); + + StringBuilder sb = new StringBuilder(); + sb.append('#'); + for (int i = 0; i < length; i++) { + sb.append(charArray[i]); + sb.append('#'); + } + int[] radius = new int[sb.length()]; + int right = -1; + int id = -1; + for (int i = 0; i < sb.length(); i++) { + int r = 1; + if (i <= right) { + r = Math.min(radius[id] - (i - id), radius[id - (i - id)]); + } + while (i - r >= 0 && i + r < sb.length() && sb.charAt(i - r) == sb.charAt(i + r)) { + r++; + } + if (i + r - 1 > right) { + right = i + r - 1; + id = i; + } + radius[i] = r; + } + + int maxLength = -1; + int leftInt = -1; + int longestLength = -1; + for (int i = 0; i < radius.length; i++) { + if (radius[i] > maxLength) { + maxLength = radius[i]; + longestLength = (maxLength - 1) * 2; + leftInt = i - (maxLength - 1); + } + } + + return sb.substring(leftInt, leftInt + longestLength + 1).replace("#", ""); + } + + public static void main(String[] args) { +// String input = "babad"; + String input = "aaaa"; + LongestPalindromicSubstring obj = new LongestPalindromicSubstring(); +// String output = obj.longestPalindrome(input); +// String output = obj.longestPalindromeWithDynamic(input); + String output = obj.longestPalindromeWithManacher(input); + System.out.println("input: " + input + " ;output: " + output); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/LongestSubstringWithoutRepeatingCharacters.java b/code/LeetCode/src/LongestSubstringWithoutRepeatingCharacters.java new file mode 100644 index 00000000..e863a40d --- /dev/null +++ b/code/LeetCode/src/LongestSubstringWithoutRepeatingCharacters.java @@ -0,0 +1,89 @@ +public class LongestSubstringWithoutRepeatingCharacters { + /* + Longest Substring Without Repeating Characters + Description + Given a string, find the length of the longest substring without repeating characters. + + Examples: + + Given "abcabcbb", the answer is "abc", which the length is 3. + + Given "bbbbb", the answer is "b", with the length of 1. + + Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring. + + Tags: Hash Table, Two Pointers, String + */ + + /* + 思路 + 题意是计算不带重复字符的最长子字符串的长度,开辟一个 hash 数组来存储该字符上次出现的位置, + 比如 hash[a] = 3 就是代表 a 字符前一次出现的索引在 3,遍历该字符串,获取到上次出现的最大索引(只能向前,不能退后), + 与当前的索引做差获取的就是本次所需长度,从中迭代出最大值就是最终答案。 + */ + + public int lengthOfLongestSubstring(String s) { + int max = 0; + int previous = 0; + if (s == null || s.length() == 0) { + return max; + } + int[] charIndexArray = new int[128]; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (charIndexArray[c] > previous) { + previous = charIndexArray[c]; + } + int currentLongChar = i - previous + 1; + if (currentLongChar > max) { + max = currentLongChar; + } + charIndexArray[c] = i + 1; + } + + return max; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/Main.java b/code/LeetCode/src/Main.java new file mode 100644 index 00000000..a0428dac --- /dev/null +++ b/code/LeetCode/src/Main.java @@ -0,0 +1,6 @@ +public class Main { + + public static void main(String[] args) { + System.out.println("Hello World!"); + } +} diff --git a/code/LeetCode/src/MaximumDepthOfBinaryTree.java b/code/LeetCode/src/MaximumDepthOfBinaryTree.java new file mode 100644 index 00000000..09dd443e --- /dev/null +++ b/code/LeetCode/src/MaximumDepthOfBinaryTree.java @@ -0,0 +1,92 @@ +public class MaximumDepthOfBinaryTree { + /* + Maximum Depth of Binary Tree + Description + Given a binary tree, find its maximum depth. + + The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. + + Note: A leaf is a node with no children. + + Example: + + Given binary tree [3,9,20,null,null,15,7], + + 3 + / \ + 9 20 + / \ + 15 7 + return its depth = 3. + + Tags: Tree, Depth-first Search + */ + + /* + + 题意是找到二叉树的最大深度,很明显,深搜即可,每深入一次节点加一即可,然后取左右子树的最大深度。 + */ + public int maxDepth(TreeNode root) { + if (root == null) { + return 0; + } + return 1 + Math.max(maxDepth(root.left), maxDepth(root.right)); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/MaximumSubarray.java b/code/LeetCode/src/MaximumSubarray.java new file mode 100644 index 00000000..ffa4a973 --- /dev/null +++ b/code/LeetCode/src/MaximumSubarray.java @@ -0,0 +1,118 @@ +public class MaximumSubarray { + /* + Maximum Subarray + Description + Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum. + + Example: + + Input: [-2,1,-3,4,-1,2,1,-5,4], + Output: 6 + Explanation: [4,-1,2,1] has the largest sum = 6. + Follow up: + + If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle. + + Tags: Array, Divide and Conquer, Dynamic Programming + */ + + /* + 思路 0 + 题意是求数组中子数组的最大和,这种最优问题一般第一时间想到的就是动态规划, + 我们可以这样想,当部分序列和大于零的话就一直加下一个元素即可,并和当前最大值进行比较, + 如果出现部分序列小于零的情况,那肯定就是从当前元素算起。 + 其转移方程就是 dp[i] = nums[i] + (dp[i - 1] > 0 ? dp[i - 1] : 0);, + 由于我们不需要保留 dp 状态,故可以优化空间复杂度为 1,即 dp = nums[i] + (dp > 0 ? dp : 0);。 + */ + public static int maxSubArray(int[] nums) { + int maxSum = nums[0]; + int passSum = maxSum; + + int startIndex = 0; + int endIndex = 0; + for (int i = 1; i < nums.length; i++) { + if (passSum <= 0) { + startIndex = i; + } + passSum = nums[i] + (passSum > 0 ? passSum : 0); + if (passSum > maxSum) { + maxSum = passSum; + endIndex = i; + } + } + + System.out.print("maxSubArray: ["); + for (int i = startIndex; i <= endIndex; i++) { + System.out.print(nums[i] + ", "); + } + System.out.print("] \n"); + + return maxSum; + } + + public static void main(String[] args) { + int[] input = {-2,1,-3,4,-1,2,1,-5,4}; + System.out.println("input: " + input); +// System.out.println("maxSum: " + maxSubArray(input)); + + System.out.println("maxSum: " + maxSubArrayWithDivideConquer(input)); + } + + /* + 思路 1 + 题目也给了我们另一种思路,就是分治,所谓分治就是把问题分割成更小的,最后再合并即可, + 我们把 nums 一分为二先,那么就有两种情况,一种最大序列包括中间的值,一种就是不包括,也就是在左边或者右边; + 当最大序列在中间的时候那我们就把它两侧的最大和算出即可;当在两侧的话就继续分治即可。 + */ + public static int maxSubArrayWithDivideConquer(int[] nums) { + return devideHelper(nums, 0, nums.length - 1); + } + + private static int devideHelper(int[] nums, int left, int right) { + if (left >= right) return nums[left]; + int mid = (left + right) >> 1; + int leftDevideMax = devideHelper(nums, left, mid); + int rightDevideMax = devideHelper(nums, mid + 1, right); + int leftMax = nums[mid]; + int rightMax = nums[mid + 1]; + int temp = 0; + for (int i = mid; i >= left ; --i) { + temp += nums[i]; + if (temp > leftMax) { + leftMax = temp; + } + } + + temp = 0; + for (int i = mid + 1; i <= right ; i++) { + temp += nums[i]; + if (temp > rightMax) { + rightMax = temp; + } + } + + return Math.max(Math.max(leftDevideMax, rightDevideMax), leftMax + rightMax); + } + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/MedianOfTwoSortedArrays.java b/code/LeetCode/src/MedianOfTwoSortedArrays.java new file mode 100644 index 00000000..59fe3b63 --- /dev/null +++ b/code/LeetCode/src/MedianOfTwoSortedArrays.java @@ -0,0 +1,136 @@ +public class MedianOfTwoSortedArrays { + /* + Median of Two Sorted Arrays + Description + There are two sorted arrays nums1 and nums2 of size m and n respectively. + + Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). + + Example 1: + + nums1 = [1, 3] + nums2 = [2] + + The median is 2.0 + Example 2: + + nums1 = [1, 2] + nums2 = [3, 4] + + The median is (2 + 3)/2 = 2.5 + Tags: Array, Binary Search, Divide and Conquer + */ + + /* + 思路 + 题意是给你两个已排序的递增数组,让你找出其中位数。 + + 乍一看这题并不是很难,因为两序列有序,所以我们很容想到时间复杂度为 O(m + n) 的做法:依次取出两数组中较小的元素, + 然后找到中间的元素即可。但这题要求的时间复杂度为 O(log(m + n)),那么我们自然而然地就能想到二分查找法进行求解。 + + 题目是让找两数组的中位数,我们可以泛化为求两数组中第 k 大的元素,那么,求中位数就是其中的一个特例而已。 + helper 函数所起到的作用就是求两数组中第 k 大的元素,下面来解释其原理: + + 假设数组分别记为 A,B,当前需要搜索第 k 大的数,于是我们可以考虑从数组 A 中取出前 m 个元素,从数组 B 中取出前 k - m 个元素。 + 由于数组 A,B 分别排序,则 A[m - 1] 大于从数组 A 中取出的其他所有元素,B[k - m - 1] 大于数组 B 中取出的其他所有元素。 + 此时,尽管取出元素之间的相对大小关系不确定,但 A[m - 1] 与 B[k - m - 1] 的较大者一定是这 k 个元素中最大的。 + 那么,较小的那个元素一定不是第 k 大的,这里留给读者自己想象。 + + 为叙述方便,假设 A[m - 1] 是较小的那个元素,那么我们可以把 A[0],A[1]...A[m - 1] 排除掉,并且更新 k 值为 k - m, + 也就是下一次就是从剩余的元素中寻找第 k - m 大的元素,这样,我们就完成了一次范围缩小,同理进行下一轮的操作。 + + 那么什么时候停止操作呢?分两种情况: + + 当某个数组的数都被取完了,那么直接返回另一个数组的后 k 个元素即可。 + + 当 k = 1 时,也就是只需再找一个数即可,也就是取两者当前较小的那个即可。 + + 特别地,我们选取 m = k / 2,下面是我画的草图,希望能帮助大家理解。 + */ + + public double findMedianSortedArrays(int[] nums1, int[] nums2) { + int len = nums1.length + nums2.length; + if (len % 2 == 0) { + return (helper(nums1, 0, nums2, 0, len / 2) + helper(nums1, 0, nums2, 0, (len / 2 + 1))) / 2.0; + } + return helper(nums1, 0, nums2, 0, (len / 2 + 1)); + } + + public double helper(int[] nums1, int index1, int[] nums2, int index2, int k) { + if (index1 >= nums1.length) { + return nums2[index2 + k - 1]; + } + if (index2 >= nums2.length) { + return nums1[index1 + k - 1]; + } + if (k == 1) { + return Math.min(nums1[index1], nums2[index2]); + } + int offset = k / 2; + int position1 = index1 + offset - 1; + int position2 = index2 + offset - 1; + int value1 = position1 < nums1.length ? nums1[position1] : Integer.MAX_VALUE; + int value2 = position2 < nums2.length ? nums2[position2] : Integer.MAX_VALUE; + if (value1 < value2) { + return helper(nums1, index1 + offset, nums2, index2, k - offset); + } + return helper(nums1, index1, nums2, index2 + offset, k - offset); + } + + public static void main(String[] args) { + MedianOfTwoSortedArrays obj = new MedianOfTwoSortedArrays(); + int[] input1 = {1, 3}; + int[] input2 = {2}; + System.out.println("result: " + obj.findMedianSortedArrays(input1, input2)); + + int[] input3 = {1, 2}; + int[] input4 = {3, 4}; + System.out.println("result: " + obj.findMedianSortedArrays(input3, input4)); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/MergeIntervals.java b/code/LeetCode/src/MergeIntervals.java new file mode 100644 index 00000000..aa99402f --- /dev/null +++ b/code/LeetCode/src/MergeIntervals.java @@ -0,0 +1,115 @@ +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +public class MergeIntervals { + /* + Merge Intervals + Description + Given a collection of intervals, merge all overlapping intervals. + + Example 1: + + Input: [[1,3],[2,6],[8,10],[15,18]] + Output: [[1,6],[8,10],[15,18]] + Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6]. + Example 2: + + Input: [[1,4],[4,5]] + Output: [[1,5]] + Explanation: Intervals [1,4] and [4,5] are considerred overlapping. + Tags: Array, Sort + */ + + /* + 思路 + 题意是给你一组区间,让你把区间合并成没有交集的一组区间。我们可以把区间按 start 进行排序, + 然后遍历排序后的区间,如果当前的 start 小于前者的 end,那么说明这两个存在交集, + 我们取两者中较大的 end 即可;否则的话直接插入到结果序列中即可。 + */ + public List merge(List intervals) { + if (intervals == null || intervals.size() <= 1) { + return intervals; + } + intervals.sort(new Comparator() { + @Override + public int compare(Interval o1, Interval o2) { + if (o1.start < o2.start) { + return -1; + } else if (o1.start > o2.start) { + return 1; + } + return 0; + } + }); + int start = intervals.get(0).start; + int end = intervals.get(0).end; + List list = new ArrayList<>(); + for (int i = 1; i < intervals.size(); i++) { + Interval item = intervals.get(i); + if (end >= item.start) { + end = Math.max(end, item.end); + } else { + list.add(new Interval(start, end)); + start = item.start; + end = item.end; + } + } + list.add(new Interval(start, end)); + + return list; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/MergeKSortedLists.java b/code/LeetCode/src/MergeKSortedLists.java new file mode 100644 index 00000000..56b74bcd --- /dev/null +++ b/code/LeetCode/src/MergeKSortedLists.java @@ -0,0 +1,163 @@ +import java.util.Comparator; +import java.util.PriorityQueue; + +public class MergeKSortedLists { + /* + Merge k Sorted Lists + Description + Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. + + Example: + + Input: + [ + 1->4->5, + 1->3->4, + 2->6 + ] + Output: 1->1->2->3->4->4->5->6 + Tags: Linked List, Divide and Conquer, Heap + */ + + /* + 思路 0 + 题意是合并多个已排序的链表,分析并描述其复杂度,我们可以用分治法来两两合并他们, + 假设 k 为总链表个数,N 为总元素个数,那么其时间复杂度为 O(Nlogk)。 + */ + + public ListNode mergeKLists(ListNode[] lists) { + if (lists == null || lists.length == 0) { + return null; + } + return helper(lists, 0, lists.length - 1); + } + + public ListNode helper(ListNode[] lists, int left, int right) { + if (left >= right) { + return lists[left]; + } + int mid = (left + right) >>> 1; + ListNode l0 = helper(lists, left, mid); + ListNode l1 = helper(lists, mid + 1, right); + + return merge2ListNode(l0, l1); + } + + public ListNode merge2ListNode(ListNode nodeFirst, ListNode nodeSecond) { + ListNode node = new ListNode(0); + ListNode temp = node; + while (nodeFirst != null && nodeSecond != null) { + if (nodeFirst.val < nodeSecond.val) { + temp.next = new ListNode(nodeFirst.val); + nodeFirst = nodeFirst.next; + } else { + temp.next = new ListNode(nodeSecond.val); + nodeSecond = nodeSecond.next; + } + + temp = temp.next; + } + temp.next = nodeFirst != null ? nodeFirst : nodeSecond; + + return node.next; + } + + /* + 思路 1 + 还有另一种思路是利用优先队列,该数据结构用到的是堆排序,所以对总链表个数为 k 的复杂度为 logk, + 总元素为个数为 N 的话,其时间复杂度也为 O(Nlogk)。 + */ + public ListNode mergeKListsByPriorityQueue(ListNode[] lists) { + if (lists == null || lists.length == 0) { + return null; + } + PriorityQueue queue = new PriorityQueue(lists.length, new Comparator() { + @Override + public int compare(ListNode o1, ListNode o2) { + if (o1.val < o2.val) { + return -1; + } else if(o1.val == o2.val) { + return 0; + } else { + return 1; + } + } + }); + ListNode node = new ListNode(0); + ListNode temp = node; + for (ListNode l : lists) { + if (l != null) { + queue.add(l); + } + } + while (!queue.isEmpty()) { + temp.next = queue.poll(); + temp = temp.next; + if (temp.next != null) { + queue.add(temp.next); + } + } + + return node.next; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/MergeSoredArray.java b/code/LeetCode/src/MergeSoredArray.java new file mode 100644 index 00000000..5354c8c2 --- /dev/null +++ b/code/LeetCode/src/MergeSoredArray.java @@ -0,0 +1,84 @@ +public class MergeSoredArray { + /* + Merge Sorted Array + Description + Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. + + Note: + + The number of elements initialized in nums1 and nums2 are m and n respectively. + You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. + Example: + + Input: + nums1 = [1,2,3,0,0,0], m = 3 + nums2 = [2,5,6], n = 3 + + Output: [1,2,2,3,5,6] + Tags: Array, Two Pointers + */ + + /* + 思路 + 题意是给两个已排序的数组 nums1 和 nums2,合并 nums2 到 nums1 中,两数组元素个数分别为 m 和 n, + 而且 nums1 数组的长度足够容纳 m + n 个元素,如果我们按顺序排下去,那肯定要开辟一个新数组来保存元素, + 如果我们选择逆序,这样利用 nums1 自身空间足矣,不会出现覆盖的情况,依次把大的元素插入到 nums1 的末尾,确保 nums2 中的元素全部插入到 nums1 即可。 + */ + public static void merge(int[] nums1, int m, int[] nums2, int n) { + int position = m + n - 1; + m--; + n--; + while (m >= 0 && n >= 0) { + nums1[position--] = nums1[m] > nums2[n] ? nums1[m--] : nums2[n--]; + } + while (n >= 0) { + nums1[position--] = nums2[n--]; + } + + System.out.print("result: "); + for (int item: nums1) { + System.out.print(item +" "); + } + } + + public static void main(String[] args) { + int[] nums1 = {1,2,3,0,0,0}; + int m = 3; + int[] nums2 = {2,5,6}; + int n = 3; + merge(nums1, m, nums2,n); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/MergeTwoSortedLists.java b/code/LeetCode/src/MergeTwoSortedLists.java new file mode 100644 index 00000000..50e95f53 --- /dev/null +++ b/code/LeetCode/src/MergeTwoSortedLists.java @@ -0,0 +1,109 @@ +import java.util.List; + +public class MergeTwoSortedLists { + /* + Merge Two Sorted Lists + Description + Merge two sorted linked lists and return it as a new list. + The new list should be made by splicing together the nodes of the first two lists. + + Example: + + Input: 1->2->4, 1->3->4 + Output: 1->1->2->3->4->4 + Tags: Linked List + */ + + /* + 思路 + 题意是用一个新链表来合并两个已排序的链表,那我们只需要从头开始比较已排序的两个链表,新链表指针每次指向值小的节点, + 依次比较下去,最后,当其中一个链表到达了末尾,我们只需要把新链表指针指向另一个没有到末尾的链表此时的指针即可。 + */ + + /** + * Definition for singly-linked list. + */ + public static class ListNode { + int val; + ListNode next; + ListNode(int x) { + val = x; + } + + @Override + public String toString() { + String data = ""; + ListNode temp = this; + while (temp != null) { + data = data + temp.val + " "; + temp = temp.next; + } + return data; + } + } + + public static ListNode mergeTwoLists(ListNode l1, ListNode l2) { + ListNode head = new ListNode(0); + ListNode temp = head; + while (l1 != null && l2 != null) { + if (l1.val < l2.val) { + temp.next = l1; + l1 = l1.next; + } else { + temp.next = l2; + l2 = l2.next; + } + + temp = temp.next; + } + + temp.next = l1 != null ? l1 : l2; + + return head.next; + } + + public static void main(String[] args) { + int[] inputList1 = {1, 2, 4}; + int[] inputList2 = {1, 3, 4}; + ListNode l1 = buildListNode(inputList1); + ListNode l2 = buildListNode(inputList2); + System.out.println("l1: " + l1.toString()); + System.out.println("l2: " + l2.toString()); + + ListNode result = mergeTwoLists(l1, l2); + System.out.println("result: " + result.toString()); + + } + + public static ListNode buildListNode(int[] intArray) { + ListNode headL1 = new ListNode(0); + ListNode l1 = headL1; + for (int i = 0; i < intArray.length; i++) { + ListNode newNode = new ListNode(intArray[i]); + l1.next = newNode; + l1 = l1.next; + } + + return headL1.next; + } + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/MinimumDepthOfBinaryTree.java b/code/LeetCode/src/MinimumDepthOfBinaryTree.java new file mode 100644 index 00000000..8a3d12f5 --- /dev/null +++ b/code/LeetCode/src/MinimumDepthOfBinaryTree.java @@ -0,0 +1,106 @@ +import java.util.LinkedList; + +public class MinimumDepthOfBinaryTree { + /* + Minimum Depth of Binary Tree + Description + Given a binary tree, find its minimum depth. + + The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. + + Note: A leaf is a node with no children. + + Example: + + Given binary tree [3,9,20,null,null,15,7], + + 3 + / \ + 9 20 + / \ + 15 7 + return its minimum depth = 2. + + Tags: Tree, Depth-first Search, Breadth-first Search + */ + + /* + 思路 0 + 题意是查找二叉树的最小深度,也就是找到从根结点到叶子节点的最小深度,最容易想到的当然是深搜, + 如果节点的左右深度都不是 0 的话,说明该节点含有左右子树,所以它的最小高度就是 1 加上其左右子树高度较小者, + 否则如果左子树为空或者右子树为空或者两者都为空,那么就是 1 加上非空子树高度。 + */ + + public int minDepthWithDeepFirst(TreeNode root) { + return helperForDeepFirst(root); + } + + public int helperForDeepFirst(TreeNode node) { + if (node == null) { + return 0; + } + int leftInt = helperForDeepFirst(node.left); + int rightInt = helperForDeepFirst(node.right); + if (leftInt != 0 && rightInt != 0) { + return 1 + Math.min(leftInt, rightInt); + } + return 1 + leftInt + rightInt; + } + + /* + 思路 1 + 第二种思路就是利用宽搜了,搜索到该层有叶子节点,那就返回该层宽度即可。 + */ + public int minDepthWithBreadthFirst(TreeNode root) { + if (root == null) { + return 0; + } + LinkedList list = new LinkedList(); + list.add(root); + int minDepth = 1; + while (list.size() != 0) { + int size = list.size(); + for (int i = 0; i < size; i++) { + TreeNode node = list.pop(); + if (node.left == null && node.right == null) { + return minDepth; + } + + if (node.left != null) { + list.add(node.left); + } + if (node.right != null) { + list.add(node.right); + } + + } + + minDepth++; + } + + return minDepth; + } + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/MultiplyStrings.java b/code/LeetCode/src/MultiplyStrings.java new file mode 100644 index 00000000..fe212779 --- /dev/null +++ b/code/LeetCode/src/MultiplyStrings.java @@ -0,0 +1,119 @@ +public class MultiplyStrings { + /* + Multiply Strings + Description + Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and num2, also represented as a string. + + Example 1: + + Input: num1 = "2", num2 = "3" + Output: "6" + Example 2: + + Input: num1 = "123", num2 = "456" + Output: "56088" + Note: + + The length of both num1 and num2 is < 110. + Both num1 and num2 contain only digits 0-9. + Both num1 and num2 do not contain any leading zero, except the number 0 itself. + You must not use any built-in BigInteger library or convert the inputs to integer directly. + Tags: Math, String + */ + + /* + 思路 + 题意是让你计算两个非负字符串的乘积,我们模拟小学数学的方式来做,一位一位模拟计算,再各位累加。 + */ + public String multiply(String num1, String num2) { + if (num1.equals("0") || num2.equals("0")) { + return "0"; + } + int l1 = num1.length(); + int l2 = num2.length(); + int l = l1 + l2; + int[] sumArray = new int[l]; + char[] chars1 = num1.toCharArray(); + char[] chars2 = num2.toCharArray(); + for (int i = l1 - 1; i >= 0; i--) { + int item1 = chars1[i] - '0'; + for (int j = l2 - 1; j >= 0; j--) { + int item2 = chars2[j] - '0'; + sumArray[(i + j + 1)] += item1 * item2; + } + } + + for (int k = l - 1; k >= 0; k--) { + if (sumArray[k] > 9) { + sumArray[k - 1] += sumArray[k] / 10; + sumArray[k] = sumArray[k] % 10; + } + } + + int i = 0; + while (sumArray[i] == 0) { + i++; + } + StringBuilder sb = new StringBuilder(); + for (int j = i; j < l; j++) { + sb.append(((char)('0' + sumArray[j]))); + } + + return sb.toString(); + } + + public static void main(String[] args) { + MultiplyStrings obj = new MultiplyStrings(); + String num1 = "2", num2 = "3"; + System.out.println("input1: " + num1 + " ,input2: " + num2 + " ,result: " + obj.multiply(num1, num2)); + + String num3 = "123", num4 = "456"; + System.out.println("input1: " + num3 + " ,input2: " + num4 + " ,result: " + obj.multiply(num3, num4)); + + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/PascalTriangle.java b/code/LeetCode/src/PascalTriangle.java new file mode 100644 index 00000000..0eec4eb3 --- /dev/null +++ b/code/LeetCode/src/PascalTriangle.java @@ -0,0 +1,80 @@ +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class PascalTriangle { + /* + Pascal's Triangle + Description + Given a non-negative integer numRows, generate the first numRows of Pascal's triangle. + + img In Pascal's triangle, each number is the sum of the two numbers directly above it. + + Example: + + Input: 5 + Output: + [ + [1], + [1,1], + [1,2,1], + [1,3,3,1], + [1,4,6,4,1] + ] + Tags: Array + */ + + /* + 思路 + 题意是给出行数,输出帕斯卡尔三角形,很简单的模拟,就不多说了。 + */ + public List> generate(int numRows) { + if (numRows < 1) { + return Collections.emptyList(); + } + List> list = new ArrayList>(); + for (int i = 0; i < numRows; i++) { + List subList = new ArrayList(); + for (int j = 0; j <= i; j++) { + if (j == 0 || i == j) { + subList.add(1); + continue; + } + + List preList = list.get(i - 1); + subList.add(preList.get(j - 1) + preList.get(j)); + } + + list.add(subList); + } + + return list; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/PascalTriangleII.java b/code/LeetCode/src/PascalTriangleII.java new file mode 100644 index 00000000..ba887b70 --- /dev/null +++ b/code/LeetCode/src/PascalTriangleII.java @@ -0,0 +1,95 @@ +import java.util.ArrayList; +import java.util.List; + +public class PascalTriangleII { + /* + Pascal's Triangle II + Description + Given a non-negative index k where k ≤ 33, return the kth index row of the Pascal's triangle. + + Note that the row index starts from 0. + + img In Pascal's triangle, each number is the sum of the two numbers directly above it. + + Example: + + Input: 3 + Output: [1,3,3,1] + Follow up: + + Could you optimize your algorithm to use only O(k) extra space? + + Tags: Array + */ + + /* + 思路 + 题意是指定输出帕斯卡尔三角形的某一行,模拟即可, + 观察规律: + 1、每行的个数为rowIndex + 1, 比如 rowIndex = 0, num = 1 + 2、下一行比上一行多一个数,比如 f(n + 1) - f(n) = 1 + 3、每行的首尾都是1,所以只要计算1 ~ Max - 1。 + 4、O(k)的空间只能用一维数组,为了不污染前面的数据,所以送从后面算起即可 + 优化后的代码如下所示。 + */ + public List getRow(int rowIndex) { + List list = new ArrayList(); + for (int i = 0; i <= rowIndex; i++) { + list.add(1); + for (int j = i - 1; j > 0; j--) { + list.set(j, list.get(j - 1) + list.get(j)); + } + } + + return list; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/PathSum.java b/code/LeetCode/src/PathSum.java new file mode 100644 index 00000000..8606ee9e --- /dev/null +++ b/code/LeetCode/src/PathSum.java @@ -0,0 +1,81 @@ +public class PathSum { + /* + Path Sum + Description + Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. + + Note: A leaf is a node with no children. + + Example: + + Given the below binary tree and sum = 22, + + 5 + / \ + 4 8 + / / \ + 11 13 4 + / \ \ + 7 2 1 + return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22. + + Tags: Tree, Depth-first Search + */ + + /* + 思路 + 题意是查找二叉树中是否存在从根结点到叶子的路径和为某一值, + 利用深搜在遇到叶子节点时判断是否满足即可。 + */ + public boolean hasPathSum(TreeNode root, int sum) { + if (root == null) { + return false; + } + if (root.left == null && root.right == null) { + return root.val == sum; + } + int lessSum = sum - root.val; + return hasPathSum(root.left, lessSum) || hasPathSum(root.right, lessSum); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/PlusOne.java b/code/LeetCode/src/PlusOne.java new file mode 100644 index 00000000..92e85a61 --- /dev/null +++ b/code/LeetCode/src/PlusOne.java @@ -0,0 +1,93 @@ +public class PlusOne { + /* + Given a non-empty array of digits representing a non-negative integer, plus one to the integer. + + The digits are stored such that the most significant digit is at the head of the list, and each element in the array contain a single digit. + + You may assume the integer does not contain any leading zero, except the number 0 itself. + + Example 1: + + Input: [1,2,3] + Output: [1,2,4] + Explanation: The array represents the integer 123. + Example 2: + + Input: [4,3,2,1] + Output: [4,3,2,2] + Explanation: The array represents the integer 4321. + */ + + /* + 思路 + 题意是给你一个数字数组,高位在前,并且首位不为 0 除非这个数组就是 [0],让你给该数组低位加一求其结果, + 那么我们就模拟小学数学那样进位去算即可,如果一直进位到首位,这种情况也就是都是由 9 组成的数组, + 此时我们只要 new 出一个多一个长度的数组即可,并把第 0 个元素赋 1 即可。 + */ + public static int[] plusOne(int[] digits) { + int lastIndex = digits.length - 1; + if (digits[lastIndex] < 9) { + digits[lastIndex]++; + } else { + do { + digits[lastIndex--] = 0; + }while (lastIndex >= 0 && digits[lastIndex] == 9); + + if (digits[0] != 0) { + digits[lastIndex]++; + } else { + digits = new int[digits.length + 1]; + digits[0] = 1; + } + } + + printArray(digits, false); + + return digits; + } + + public static void printArray(int[] input, boolean isInput) { + System.out.print(isInput ? "Input: " : "Output: "); + for (int i = 0; i < input.length; i++) { + System.out.print(input[i]); + } + System.out.println(); + } + + public static void main(String[] args) { + int[] input1 = {1,2,3}; + printArray(input1, true); + plusOne(input1); + + int[] input2 = {9,9,9}; + printArray(input2, true); + plusOne(input2); + + } + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/Pow.java b/code/LeetCode/src/Pow.java new file mode 100644 index 00000000..11df92aa --- /dev/null +++ b/code/LeetCode/src/Pow.java @@ -0,0 +1,92 @@ +public class Pow { + /* + Pow(x, n) + Description + Implement pow(x, n), which calculates x raised to the power n (xn). + + Example 1: + + Input: 2.00000, 10 + Output: 1024.00000 + Example 2: + + Input: 2.10000, 3 + Output: 9.26100 + Example 3: + + Input: 2.00000, -2 + Output: 0.25000 + Explanation: 2^-2 = 1/2^2 = 1/4 = 0.25 + Note: + + -100.0 < x < 100.0 + n is a 32-bit signed integer, within the range [−231, 231 − 1] + Tags: Math, Binary Search + */ + + /* + 思路 + 题意是让你计算 x^n,如果直接计算肯定会超时,那么我们可以想到可以使用二分法来降低时间复杂度。 + */ + + public double myPow(double x, int n) { + if (n < 0) { + return helper(1/x, -n); + } + + return helper(x, n); + } + + private double helper(double x, int n) { + if (n == 0) { + return 1; + } + if (n == 1) { + return x; + } + double d = helper(x, (n >>> 1)); + if (n % 2 == 0) { + return d * d; + } + + return d * d * x; + } + + public static void main(String[] args) { + Pow obj = new Pow(); + double x = 2; + int n = 10; + System.out.println("x: " + x + " ,n: " + n + " ,pow: " + obj.myPow(x, n)); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/RegularExpressionMatching.java b/code/LeetCode/src/RegularExpressionMatching.java new file mode 100644 index 00000000..450990ba --- /dev/null +++ b/code/LeetCode/src/RegularExpressionMatching.java @@ -0,0 +1,279 @@ +public class RegularExpressionMatching { + /* + Regular Expression Matching + Description + Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*'. + + '.' Matches any single character. + '*' Matches zero or more of the preceding element. + The matching should cover the entire input string (not partial). + + Note: + + s could be empty and contains only lowercase letters a-z. + p could be empty and contains only lowercase letters a-z, and characters like . or *. + Example 1: + + Input: + s = "aa" + p = "a" + Output: false + Explanation: "a" does not match the entire string "aa". + Example 2: + + Input: + s = "aa" + p = "a*" + Output: true + Explanation: '*' means zero or more of the precedeng element, 'a'. Therefore, by repeating 'a' once, it becomes "aa". + Example 3: + + Input: + s = "ab" + p = ".*" + Output: true + Explanation: ".*" means "zero or more (*) of any character (.)". + Example 4: + + Input: + s = "aab" + p = "c*a*b" + Output: true + Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore it matches "aab". + Example 5: + + Input: + s = "mississippi" + p = "mis*is*p*." + Output: false + Tags: String, Dynamic Programming, Backtracking + */ + + /* + 思路 0 + 题意是让让你从判断 s 字符串是否正则匹配于 p,这道题和 Wildcard Matching 很是相似, + 区别在于 *,通配符的 * 是可以随意出现的,跟前面字符没有任何关系,其作用是可以表示任意字符串; + 而正则匹配的 * 不能单独存在,前面必须具有一个字符,其意义是表明前面的这个字符个数可以是任意个数,包括 0 个。 + 首先我们用递归的方式来实现,其思路如下: + + 如果 s 和 p 都为空,那么返回 true; + + 如果 p 的长度为 1,当 s 的长度也为 1,并且他们首位匹配则返回 true,否则返回 false; + + 如果 p 的第二个字符不为 '*',如果 s 为空,那就返回 false,首位匹配则返回递归调用他们去掉首位的子字符串,否则返回 false; + + 如果 p 的第二个字符为 '*',循环当 s 不为空,且首位匹配,如果递归调用是否匹配 s 字符串和 p 去掉前两位的子字符串,则返回 true, + 否则 s 去掉首字母继续循环; + + 返回递归调用 s 字符串和 p 去掉前两位的子字符串是否匹配。 + */ + + public boolean isMathByLoop(String s, String p) { + if (p.isEmpty()) { + return s.isEmpty(); + } + if (p.length() == 1) { + return s.length() == 1 && (p.charAt(0) == s.charAt(0) || p.charAt(0) == '.'); + } + if (p.charAt(1) != '*') { + if (s.isEmpty()) { + return false; + } + return (p.charAt(0) == s.charAt(0) || p.charAt(0) == '.') && isMathByLoop(s.substring(1), p.substring(1)); + } + //p.charAt(1) == '*' + while (!s.isEmpty() && p.charAt(1) == '*' && (p.charAt(0) == s.charAt(0) || p.charAt(0) == '.')) { + if (isMathByLoop(s, p.substring(2))) { + return true; + } else { + s = s.substring(1); + } + } + + return isMathByLoop(s, p.substring(2)); + } + + /* + 思路 1 + 我们可以把上面的思路更简单化,如下: + + 如果 s 和 p 都为空,那么返回 true; + + 如果 p 的第二个字符为 *,由于 * 前面的字符个数可以为任意,那么我们先递归调用个数为 0 的情况; + 或者当 s 不为空,如果他们的首字母匹配,那么我们就递归调用去掉去掉首字母的 s 和完整的 p; + + 如果 p 的第二个字符不为 *,那么我们就老老实实判断第一个字符是否匹配并且递归调用他们去掉首位的子字符串。 + */ + public boolean isMathByLoopLess(String s, String p) { + if (p.isEmpty()) { + return s.isEmpty(); + } + if (p.length() > 1 && p.charAt(1) == '*') { + return isMathByLoopLess(s, p.substring(2)) || (!s.isEmpty() && (p.charAt(0) == s.charAt(0) || p.charAt(0) == '.') && isMathByLoopLess(s.substring(1), p)); + } + return !s.isEmpty() && (s.charAt(0) == p.charAt(0) || p.charAt(0) == '.') && isMathByLoopLess(s.substring(1), p.substring(1)); + } + + /* + 思路 2 + 另一种思路就是动态规划了,我们定义 dp[i][j] 的真假来表示 s[0..i) 是否匹配 p[0..j),通过思路 1,我们可以确定其状态转移方程如下所示: + + 如果 p[j - 1] == '*', dp[i][j] = dp[i][j - 2] || (pc[j - 2] == sc[i - 1] || pc[j - 2] == '.') && dp[i - 1][j];; + + 如果 p[j - 1] != '*',dp[i][j] = dp[i - 1][j - 1] && (pc[j - 1] == '.' || pc[j - 1] == sc[i - 1]);。 + */ + public boolean isMathByDynamic(String s, String p) { + if (p.isEmpty()) { + return s.isEmpty(); + } + int sl = s.length(); + int pl = p.length(); + boolean[][] spArray = new boolean[sl + 1][pl + 1]; + char[] schars = s.toCharArray(); + char[] pchars = p.toCharArray(); + spArray[0][0] = true; + for (int i = 2; i <= pl; i++) { + if (pchars[i - 1] == '*' && spArray[0][i - 2]) { + spArray[0][i] = true; + } + } + for (int i = 1; i <= sl; i++) { + for (int j = 1; j <= pl; j++) { + if (pchars[j - 1] == '*') { + spArray[i][j] = spArray[i][j - 2] || (spArray[i - 1][j] && (schars[i - 1] == pchars[j - 2] || pchars[j - 2] == '.')); + } else { + spArray[i][j] = spArray[i - 1][j - 1] && (schars[i - 1] == pchars[j - 1] || pchars[j - 1] == '.'); + } + } + } + + return spArray[sl][pl]; + } + + public static void main(String[] args) { + RegularExpressionMatching obj = new RegularExpressionMatching(); +// String s0 = "ab"; +// String p0 = ".*c"; +// System.out.println("s: " +s0+ " ,p: " +p0+ " ,result: " +obj.isMathByLoop(s0, p0)); +// +// String s1 = "aa"; +// String p1 = "a"; +// System.out.println("s: " +s1+ " ,p: " +p1+ " ,result: " +obj.isMathByLoop(s1, p1)); +// +// String s2 = "aa"; +// String p2 = "a*"; +// System.out.println("s: " +s2+ " ,p: " +p2+ " ,result: " +obj.isMathByLoop(s2, p2)); +// +// String s3 = "aa"; +// String p3 = ".*"; +// System.out.println("s: " +s3+ " ,p: " +p3+ " ,result: " +obj.isMathByLoop(s3, p3)); +// +// String s4 = "aab"; +// String p4 = "c*a*b"; +// System.out.println("s: " +s4+ " ,p: " +p4+ " ,result: " +obj.isMathByLoop(s4, p4)); +// +// String s5 = "mississippi"; +// String p5 = "mis*is*p*."; +// System.out.println("s: " +s5+ " ,p: " +p5+ " ,result: " +obj.isMathByLoop(s5, p5)); + /* + s: ab ,p: .*c ,result: false + s: aa ,p: a ,result: false + s: aa ,p: a* ,result: true + s: aa ,p: .* ,result: true + s: aab ,p: c*a*b ,result: true + s: mississippi ,p: mis*is*p*. ,result: false + */ + +// String s0 = "ab"; +// String p0 = ".*c"; +// System.out.println("s: " +s0+ " ,p: " +p0+ " ,result: " +obj.isMathByLoopLess(s0, p0)); +// +// String s1 = "aa"; +// String p1 = "a"; +// System.out.println("s: " +s1+ " ,p: " +p1+ " ,result: " +obj.isMathByLoopLess(s1, p1)); +// +// String s2 = "aa"; +// String p2 = "a*"; +// System.out.println("s: " +s2+ " ,p: " +p2+ " ,result: " +obj.isMathByLoopLess(s2, p2)); +// +// String s3 = "aa"; +// String p3 = ".*"; +// System.out.println("s: " +s3+ " ,p: " +p3+ " ,result: " +obj.isMathByLoopLess(s3, p3)); +// +// String s4 = "aab"; +// String p4 = "c*a*b"; +// System.out.println("s: " +s4+ " ,p: " +p4+ " ,result: " +obj.isMathByLoopLess(s4, p4)); +// +// String s5 = "mississippi"; +// String p5 = "mis*is*p*."; +// System.out.println("s: " +s5+ " ,p: " +p5+ " ,result: " +obj.isMathByLoopLess(s5, p5)); + + String s0 = "ab"; + String p0 = ".*c"; + System.out.println("s: " +s0+ " ,p: " +p0+ " ,result: " +obj.isMathByDynamic(s0, p0)); + + String s1 = "aa"; + String p1 = "a"; + System.out.println("s: " +s1+ " ,p: " +p1+ " ,result: " +obj.isMathByDynamic(s1, p1)); + + String s2 = "aa"; + String p2 = "a*"; + System.out.println("s: " +s2+ " ,p: " +p2+ " ,result: " +obj.isMathByDynamic(s2, p2)); + + String s3 = "aa"; + String p3 = ".*"; + System.out.println("s: " +s3+ " ,p: " +p3+ " ,result: " +obj.isMathByDynamic(s3, p3)); + + String s4 = "aab"; + String p4 = "c*a*b"; + System.out.println("s: " +s4+ " ,p: " +p4+ " ,result: " +obj.isMathByDynamic(s4, p4)); + + String s5 = "mississippi"; + String p5 = "mis*is*p*."; + System.out.println("s: " +s5+ " ,p: " +p5+ " ,result: " +obj.isMathByDynamic(s5, p5)); + + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/RemoveDuplicatesFromSortedArray.java b/code/LeetCode/src/RemoveDuplicatesFromSortedArray.java new file mode 100644 index 00000000..39422fbc --- /dev/null +++ b/code/LeetCode/src/RemoveDuplicatesFromSortedArray.java @@ -0,0 +1,70 @@ +public class RemoveDuplicatesFromSortedArray { + /* + Remove Duplicates from Sorted Array + Description + Given a sorted array nums, remove the duplicates in-place such that each element appear only once and return the new length. + + Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory. + + Example 1: + + Given nums = [1,1,2], + + Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. + + It doesn't matter what you leave beyond the returned length. + Example 2: + + Given nums = [0,0,1,1,1,2,2,3,3,4], + + Your function should return length = 5, with the first five elements of nums being modified to 0, 1, 2, 3, and 4 respectively. + + It doesn't matter what values are set beyond the returned length. + Clarification: + + Confused why the returned value is an integer but your answer is an array? + + Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well. + + Internally you can think of this: + + // nums is passed in by reference. (i.e., without making a copy) + int len = removeDuplicates(nums); + + // any modification to nums in your function would be known by the caller. + // using the length returned by your function, it prints the first len elements. + for (int i = 0; i < len; i++) { + print(nums[i]); + } + Tags: Array, Two Pointers + */ + + /* + 思路 + 题意是让你从一个有序的数组中移除重复的元素,并返回之后数组的长度。我的思路是判断长度小于等于 1 的话直接返回原长度即可, + 否则的话遍历一遍数组,用一个 tail 变量指向尾部,如果后面的元素和前面的元素不同,就让 tail 变量加一,最后返回 tail 即可。 + */ + + public static int removeDuplicates(int[] nums) { + int len = nums.length; + if (len <= 1) { + return len; + } + int last = 1; + for (int i = 1; i < len; i++) { + if (nums[i] != nums[i - 1]) { + nums[last++] = nums[i]; + } + + } + + return last; + } + + public static void main(String[] args) { + int[] inputArray1 = {1,1,2}; + System.out.println("inputArray1: " + inputArray1.toString() + " result: " + removeDuplicates(inputArray1)); + int[] inputArray2 = {0,0,1,1,1,2,2,3,3,4}; + System.out.println("inputArray2: " + inputArray2.toString() + " result: " + removeDuplicates(inputArray2)); + } +} diff --git a/code/LeetCode/src/RemoveDuplicatesFromSortedList.java b/code/LeetCode/src/RemoveDuplicatesFromSortedList.java new file mode 100644 index 00000000..f9d6f40d --- /dev/null +++ b/code/LeetCode/src/RemoveDuplicatesFromSortedList.java @@ -0,0 +1,113 @@ + +public class RemoveDuplicatesFromSortedList { + /* + Remove Duplicates from Sorted List + Description + Given a sorted linked list, delete all duplicates such that each element appear only once. + + Example 1: + + Input: 1->1->2 + Output: 1->2 + Example 2: + + Input: 1->1->2->3->3 + Output: 1->2->3 + Tags: Linked List + */ + + /* + 思路 + 题意是删除链表中重复的元素,很简单,我们只需要遍历一遍链表, + 遇到链表中相邻元素相同时,把当前指针指向下下个元素即可。 + */ + + //Definition for singly-linked list. + public static class ListNode { + int val; + ListNode next; + ListNode(int x) { + val = x; + next = null; + } + + @Override + public String toString() { + ListNode temp = this; + String valString = ""; + while (temp != null) { + valString = valString + temp.val + "->"; + temp = temp.next; + } + + return valString; + } + } + + public static ListNode deleteDuplicates(ListNode head) { + if (head == null || head.next == null) { + return head; + } + ListNode current = head; + while (current.next != null) { + if (current.next.val == current.val) { + current.next = current.next.next; + } else { + current = current.next; + } + + } + + return head; + } + + public static void main(String[] args) { + int[] inputArray1 = {1, 1, 2}; + ListNode inputListNode1 = buildListNode(inputArray1); + System.out.println("input: " + inputListNode1.toString()); + System.out.println("output: " + deleteDuplicates(inputListNode1).toString()); + + int[] inputArray2 = {1, 1, 2, 3, 3}; + ListNode inputListNode2 = buildListNode(inputArray2); + System.out.println("input: " + inputListNode2.toString()); + System.out.println("output: " + deleteDuplicates(inputListNode2).toString()); + } + + public static ListNode buildListNode(int[] intArray) { + ListNode headL1 = new ListNode(0); + ListNode l1 = headL1; + for (int i = 0; i < intArray.length; i++) { + ListNode newNode = new ListNode(intArray[i]); + l1.next = newNode; + l1 = l1.next; + } + + return headL1.next; + } + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/RemoveElement.java b/code/LeetCode/src/RemoveElement.java new file mode 100644 index 00000000..4cc37db2 --- /dev/null +++ b/code/LeetCode/src/RemoveElement.java @@ -0,0 +1,96 @@ +public class RemoveElement { + /* + Remove Element + Description + Given an array nums and a value val, remove all instances of that value in-place and return the new length. + + Do not allocate extra space for another array, you must do this by **modifying the input array in-place ** with O(1) extra memory. + + The order of elements can be changed. It doesn't matter what you leave beyond the new length. + + Example 1: + + Given nums = [3,2,2,3], val = 3, + + Your function should return length = 2, with the first two elements of nums being 2. + + It doesn't matter what you leave beyond the returned length. + Example 2: + + Given nums = [0,1,2,2,3,0,4,2], val = 2, + + Your function should return length = 5, with the first five elements of nums containing 0, 1, 3, 0, and 4. + + Note that the order of those five elements can be arbitrary. + + It doesn't matter what values are set beyond the returned length. + Clarification: + + Confused why the returned value is an integer but your answer is an array? + + Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well. + + Internally you can think of this: + + // nums is passed in by reference. (i.e., without making a copy) + int len = removeElement(nums, val); + + // any modification to nums in your function would be known by the caller. + // using the length returned by your function, it prints the first len elements. + for (int i = 0; i < len; i++) { + print(nums[i]); + } + Tags: Array, Two Pointers + */ + + /* + 思路 + 题意是移除数组中值等于 val 的元素,并返回之后数组的长度,并且题目中指定空间复杂度为 O(1),我的思路是用 tail 标记尾部, + 遍历该数组时当索引元素不等于 val 时,tail 加一,尾部指向当前元素,最后返回 tail 即可。 + */ + + public static int removeElement(int[] nums, int val) { + int last = 0; + for (int item: nums) { + if (item != val) { + nums[last++] = item; + } + } + + return last; + } + + public static void main(String[] args) { + int[] input1 = {3,2,2,3}; + int val1 = 3; + System.out.println("input: " + input1.toString() + " val:" + val1 + + " result: " + removeElement(input1, val1)); + + int[] input2 = {0,1,2,2,3,0,4,2}; + int val2 = 2; + System.out.println("input: " + input2.toString() + " val:" + val2 + + " result: " + removeElement(input2, val2)); + } + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/RemoveNthNodeFromEndOfList.java b/code/LeetCode/src/RemoveNthNodeFromEndOfList.java new file mode 100644 index 00000000..f7c5757c --- /dev/null +++ b/code/LeetCode/src/RemoveNthNodeFromEndOfList.java @@ -0,0 +1,94 @@ +import java.lang.reflect.Method; + +public class RemoveNthNodeFromEndOfList { + /* + Remove Nth Node From End of List + Description + Given a linked list, remove the n-th node from the end of list and return its head. + + Example: + + Given linked list: 1->2->3->4->5, and n = 2. + + After removing the second node from the end, the linked list becomes 1->2->3->5. + Note: + + Given n will always be valid. + + Follow up: + + Could you do this in one pass? + + Tags: Linked List, Two Pointers + */ + + /* + 思路 + 题意是让你删除链表中的倒数第 n 个数,我的解法是利用双指针,这两个指针相差 n 个元素,当后面的指针扫到链表末尾的时候, + 自然它前面的那个指针所指向的下一个元素就是要删除的元素,即 pre.next = pre.next.next;, + 但是如果一开始后面的指针指向的为空,此时代表的意思就是要删除第一个元素,即 head = head.next;。 + */ + public ListNode removeNthFromEnd(ListNode head, int n) { + ListNode previousNode = head; + ListNode afterNode = head; + while (n-- != 0 && afterNode != null) { + afterNode = afterNode.next; + } + if (afterNode != null) { + while (afterNode.next != null) { + previousNode = previousNode.next; + afterNode = afterNode.next; + } + previousNode.next = previousNode.next.next; + } else { + head = head.next; + } + + return head; + } + +// public static void target(int i) { +// +// } +// +// public static void main(String[] args) { +// Class klass = Class.forName("RemoveNthNodeFromEndOfList"); +// Method method = klass.getMethod("target", int.class); +// method.equals() +// } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/ReverseNodesInKGroup.java b/code/LeetCode/src/ReverseNodesInKGroup.java new file mode 100644 index 00000000..87054561 --- /dev/null +++ b/code/LeetCode/src/ReverseNodesInKGroup.java @@ -0,0 +1,128 @@ +public class ReverseNodesInKGroup { + /* + Reverse Nodes in k-Group + Description + Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. + + k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is. + + Example: + + Given this linked list: 1->2->3->4->5 + + For k = 2, you should return: 2->1->4->3->5 + + For k = 3, you should return: 3->2->1->4->5 + + Note: + + Only constant extra memory is allowed. + You may not alter the values in the list's nodes, only nodes itself may be changed. + Tags: Linked List + */ + + /* + 思路 + 题意是让你以 k 个元素为一组来翻转链表,最后不足 k 个的话不需要翻转,最传统的思路就是每遇到 k 个元素, + 对其 k 个元素进行翻转,而难点就是在此,下面介绍其原理,我们以例子中的 k = 3 为例,其 pre 和 next 如下所示。 + + 0->1->2->3->4->5 + | | + pre next + 我们要做的就是把 pre 和 next 之间的元素逆序,思想是依次从第二个元素到第 k 个元素,依次把它插入到 pre 后面,过程如下。 + + head move + | | + 0->1->2->3->4->5 + | | + pre next + + head move + | | + 0->2->1->3->4->5 + | | + pre next + + head move + | | + 0->3->2->1->4->5 + | | + pre next + 好了,根据原理,那写出代码就不难了。 + */ + + public ListNode reverseKGroup(ListNode head, int k) { + if (head == null || k == 1) { + return head; + } + ListNode node = new ListNode(0); + ListNode pre = node; + pre.next = head; + for (int i = 1; head != null ; i++) { + if (i % k == 0) { + pre = reverse(pre, head.next); + head = pre.next; + } else { + head = head.next; + } + } + + return node.next; + } + + private ListNode reverse(ListNode pre, ListNode next) { + ListNode head = pre.next; + ListNode move = head.next; + while (move != next) { + head.next = move.next; + move.next = pre.next; + pre.next = move; + move = head.next; + } + + return head; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/RomanToInt.java b/code/LeetCode/src/RomanToInt.java new file mode 100644 index 00000000..78cd9264 --- /dev/null +++ b/code/LeetCode/src/RomanToInt.java @@ -0,0 +1,41 @@ +import java.util.HashMap; +import java.util.Map; + +public class RomanToInt { + + public static int romanToInt(String s) { + Map map = new HashMap(); + map.put('I', 1); + map.put('V', 5); + map.put('X', 10); + map.put('L', 50); + map.put('C', 100); + map.put('D', 500); + map.put('M', 1000); + int len = s.length(); + System.out.println("len: " + len); + int sum = map.get(s.charAt(len - 1)); + for (int i = len - 2; i >= 0; --i) { + if (map.get(s.charAt(i)) < map.get(s.charAt(i + 1))) { + sum -= map.get(s.charAt(i)); + } else { + sum += map.get(s.charAt(i)); + } + } + return sum; + } + + public static void main(String[] args) { + String input1 = "III"; + String input2 = "IV"; + String input3 = "IX"; + String input4 = "LVIII"; + String input5 = "MCMXCIV"; + + System.out.println("input: " +input1+ " output:" + romanToInt(input1)); + System.out.println("input: " +input2+ " output:" + romanToInt(input2)); + System.out.println("input: " +input3+ " output:" + romanToInt(input3)); + System.out.println("input: " +input4+ " output:" + romanToInt(input4)); + System.out.println("input: " +input5+ " output:" + romanToInt(input5)); + } +} diff --git a/code/LeetCode/src/SameTree.java b/code/LeetCode/src/SameTree.java new file mode 100644 index 00000000..b064fdf5 --- /dev/null +++ b/code/LeetCode/src/SameTree.java @@ -0,0 +1,112 @@ +public class SameTree { + /* + Same Tree + Description + Given two binary trees, write a function to check if they are the same or not. + + Two binary trees are considered the same if they are structurally identical and the nodes have the same value. + + Example 1: + + Input: 1 1 + / \ / \ + 2 3 2 3 + + [1,2,3], [1,2,3] + + Output: true + Example 2: + + Input: 1 1 + / \ + 2 2 + + [1,2], [1,null,2] + + Output: false + Example 3: + + Input: 1 1 + / \ / \ + 2 1 1 2 + + [1,2,1], [1,1,2] + + Output: false + Tags: Tree, Depth-first Search + */ + + /* + 思路 + 题意是比较两棵二叉树是否相同,那么我们就深搜比较各个节点即可。 + */ + + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { + val = x; + } + } + + public static boolean isSameTree(TreeNode p, TreeNode q) { + if (p == null && q == null) { + return true; + } + if (p == null || q == null) { + return false; + } + if (p.val == q.val) { + return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); + } + + return false; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/SearchInRotatedSortedArray.java b/code/LeetCode/src/SearchInRotatedSortedArray.java new file mode 100644 index 00000000..c840eef4 --- /dev/null +++ b/code/LeetCode/src/SearchInRotatedSortedArray.java @@ -0,0 +1,120 @@ +public class SearchInRotatedSortedArray { + /* + Search in Rotated Sorted Array + Description + Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. + + (i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]). + + You are given a target value to search. If found in the array return its index, otherwise return -1. + + You may assume no duplicate exists in the array. + + Your algorithm's runtime complexity must be in the order of O(log n). + + Example 1: + + Input: nums = [4,5,6,7,0,1,2], target = 0 + Output: 4 + Example 2: + + Input: nums = [4,5,6,7,0,1,2], target = 3 + Output: -1 + Tags: Arrays, Binary Search + */ + + /* + 思路 + 题意是让你从一个旋转过后的递增序列中寻找给定值,找到返回索引,找不到返回-1,我们在下面这组数据中寻找规律。 + + 1 2 4 5 6 7 0 + 2 4 5 6 7 0 1 + 4 5 6 7 0 1 2 + 5 6 7 0 1 2 4 + 6 7 0 1 2 4 5 + 7 0 1 2 4 5 6 + 由于是旋转一次,所以肯定有一半及以上的序列仍然是具有递增性质的,我们观察到如果中间的数比左面的数大的话, + 那么左半部分序列是递增的,否则右半部分就是递增的,那么我们就可以确定给定值是否在递增序列中,从而决定取舍哪半边。 + */ + + public int search(int[] nums, int target) { + int left = 0; + int right = nums.length - 1; + while (left <= right) { + int mid = (left + right) >>> 1; + if (nums[mid] == target) { + return mid; + } 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 -1; + } + + public static void main(String[] args) { + SearchInRotatedSortedArray obj = new SearchInRotatedSortedArray(); + int[] nums1 = {4,5,6,7,0,1,2}; + int target1 = 0; + System.out.println("nums: " + nums1 + " ;target: " + target1 + " result: " + obj.search(nums1, target1)); + + int[] nums2 = {4,5,6,7,0,1,2}; + int target2 = 3; + System.out.println("nums: " + nums2 + " ;target: " + target2 + " result: " + obj.search(nums2, target2)); + + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/SearchInsertPosition.java b/code/LeetCode/src/SearchInsertPosition.java new file mode 100644 index 00000000..83c9ac6f --- /dev/null +++ b/code/LeetCode/src/SearchInsertPosition.java @@ -0,0 +1,77 @@ +public class SearchInsertPosition { + /* + Search Insert Position + Description + Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. + + You may assume no duplicates in the array. + + Example 1: + + Input: [1,3,5,6], 5 + Output: 2 + Example 2: + + Input: [1,3,5,6], 2 + Output: 1 + Example 3: + + Input: [1,3,5,6], 7 + Output: 4 + Example 1: + + Input: [1,3,5,6], 0 + Output: 0 + Tags: Array, Binary Search + */ + + /* + 思路 + 题意是让你从一个没有重复元素的已排序数组中找到插入位置的索引。 + 因为数组已排序,所以我们可以想到二分查找法,因为查找到的条件是找到第一个等于或者大于 target 的元素的位置,所以二分法略作变动即可。 + */ + + public static int searchInsert(int[] nums, int target) { + int left = 0; + int right = nums.length - 1; + int middle = (left + right) >> 1; + while (left <= right) { + if (target > nums[middle]) { + left = middle + 1; + } else { + right = middle - 1; + } + middle = (left + right) >> 1; + } + + return left; + } + + public static void main(String[] args) { + int[] nums1 = {1,3,5,6}; + int target1 = 5; + System.out.println("nums: " + nums1 + " target: " + target1 + " result: " + searchInsert(nums1, target1)); + + int[] nums2 = {1,3,5,6}; + int target2 = 2; + System.out.println("nums: " + nums2 + " target: " + target2 + " result: " + searchInsert(nums2, target2)); + + int[] nums3 = {1,3,5,6}; + int target3 = 7; + System.out.println("nums: " + nums3 + " target: " + target3 + " result: " + searchInsert(nums3, target3)); + + int[] nums4 = {1,3,5,6}; + int target4 = 0; + System.out.println("nums: " + nums4 + " target: " + target4 + " result: " + searchInsert(nums4, target4)); + } + + + + + + + + + + +} diff --git a/code/LeetCode/src/Sqrt.java b/code/LeetCode/src/Sqrt.java new file mode 100644 index 00000000..7adb157a --- /dev/null +++ b/code/LeetCode/src/Sqrt.java @@ -0,0 +1,49 @@ +public class Sqrt { + /* + Sqrt(x) + Description + Implement int sqrt(int x). + + Compute and return the square root of x, where x is guaranteed to be a non-negative integer. + + Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned. + + Example 1: + + Input: 4 + Output: 2 + Example 2: + + Input: 8 + Output: 2 + Explanation: The square root of 8 is 2.82842..., and since + the decimal part is truncated, 2 is returned. + Tags: Binary Search, Math + */ + + /* + 思路 + 题意是求平方根,参考 牛顿迭代法求平方根,然后再参考维基百科的 Integer square root 即可。 + */ + + public static int mySqrt(int x) { + if (x <= 0) { + return 0; + } + + long y = x; + while (y * y > x) { + y = (long)(0.5 * (y + x / y)); + } + + return (int)y; + } + + public static void main(String[] args) { + int input1 = 4; + System.out.println("input: " +input1+ " sqrt: " + mySqrt(input1)); + + int input2 = 8; + System.out.println("input: " +input2+ " sqrt: " + mySqrt(input2)); + } +} diff --git a/code/LeetCode/src/StringToIntegerAtoi.java b/code/LeetCode/src/StringToIntegerAtoi.java new file mode 100644 index 00000000..78eae6a3 --- /dev/null +++ b/code/LeetCode/src/StringToIntegerAtoi.java @@ -0,0 +1,148 @@ +public class StringToIntegerAtoi { + /* + String to Integer (atoi) + Description + Implement atoi which converts a string to an integer. + + The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value. + + The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function. + + If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed. + + If no valid conversion could be performed, a zero value is returned. + + Note: + + Only the space character ' ' is considered as whitespace character. + Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231, 231 − 1]. If the numerical value is out of the range of representable values, INT_MAX (231 − 1) or INT_MIN (−231) is returned. + Example 1: + + Input: "42" + Output: 42 + Example 2: + + Input: " -42" + Output: -42 + Explanation: The first non-whitespace character is '-', which is the minus sign. + Then take as many numerical digits as possible, which gets 42. + Example 3: + + Input: "4193 with words" + Output: 4193 + Explanation: Conversion stops at digit '3' as the next character is not a numerical digit. + Example 4: + + Input: "words and 987" + Output: 0 + Explanation: The first non-whitespace character is 'w', which is not a numerical + digit or a +/- sign. Therefore no valid conversion could be performed. + Example 5: + + Input: "-91283472332" + Output: -2147483648 + Explanation: The number "-91283472332" is out of the range of a 32-bit signed integer. + Thefore INT_MIN (−2^31) is returned. + Tags: Math, String + */ + + /* + 思路 + 题意是把一个字符串转为整型,但要注意所给的要求,先去除最前面的空格,然后判断正负数,注意正数可能包含 +, + 如果之后存在非数字或全为空则返回 0,而如果合法的值超过 int 表示的最大范围,则根据正负号返回 INT_MAX 或 INT_MIN。 + */ + + public int myAtoni(String str) { + int sign = 1; + int number = 0; + int length = str.length(); + int i = 0; + char[] chars = str.toCharArray(); + while (i < length && chars[i] == ' ') { + i++; + } + if (i < length && (chars[i] == '+' || chars[i] == '-')) { + sign = chars[i] == '+' ? 1 : -1; + i++; + } + for (; i < length; i++) { + int temp = chars[i] - '0'; + if (temp < 0 || temp > 9) { + break; + } + if (number > Integer.MAX_VALUE / 10 || (number == Integer.MAX_VALUE / 10 && ((sign == 1 && temp > 7) || (sign == -1 && temp > 8)))) { + return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE; + } + + number = number * 10 + temp; + } + + return sign * number; + } + + public static void main(String[] args) { + StringToIntegerAtoi obj = new StringToIntegerAtoi(); +// String input = "42"; +// int output = obj.myAtoni(input); +// String input1 = " -42"; +// int output1 = obj.myAtoni(input1); +// String input2 = "4193 with words"; +// int output2 = obj.myAtoni(input2); +// String input3 = "words and 987"; +// int output3 = obj.myAtoni(input3); +// String input4 = "-91283472332"; +// int output4 = obj.myAtoni(input4); + String input5 = "-3924x8fc"; + int output5 = obj.myAtoni(input5); +// String input6 = "42"; +// int output6 = obj.myAtoni(input); +// String input7 = "42"; +// int output7 = obj.myAtoni(input); +// System.out.println("input: " + input + " output: " + output); +// System.out.println("input: " + input1 + " output: " + output1); +// System.out.println("input: " + input2 + " output: " + output2); +// System.out.println("input: " + input3 + " output: " + output3); +// System.out.println("input: " + input4 + " output: " + output4); + System.out.println("input: " + input5 + " output: " + output5); +// System.out.println("input: " + input6 + " output: " + output6); +// System.out.println("input: " + input7 + " output: " + output7); + + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/SubstringWithConcatenationOfAllWords.java b/code/LeetCode/src/SubstringWithConcatenationOfAllWords.java new file mode 100644 index 00000000..8dacedf8 --- /dev/null +++ b/code/LeetCode/src/SubstringWithConcatenationOfAllWords.java @@ -0,0 +1,228 @@ +import java.util.*; + +public class SubstringWithConcatenationOfAllWords { + /* + Substring with Concatenation of All Words + Description + You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters. + + Example 1: + + Input: + s = "barfoothefoobarman", + words = ["foo","bar"] + Output: [0,9] + Explanation: Substrings starting at index 0 and 9 are "barfoor" and "foobar" respectively. + The output order does not matter, returning [9,0] is fine too. + Example 2: + + Input: + s = "wordgoodstudentgoodword", + words = ["word","student"] + Output: [] + Tags: Hash Table, Two Pointers, String + */ + + /* + 思路 + 使用HashMap来保存L中所有的字串。 + + 暴力破解之。使用i记录我们的查找结果字符串的位置,j记录单个单词的查找位置。j每次移动一个L中单词的位置。 + + 注意各种越界条件:i查到离结束还有L*N(L中所有单词总长)的时候,即需要停止。 + + j 也要考虑每一次查找的单词的长度。 + + 使用第二个HashMap来记录我们查到的单词。如果所有的单词都查到了,即可记录一个解。 + */ + + public List findSubstring(String s, String[] words) { + List resultList = new ArrayList(); + if (s == null || s.length() == 0 || words == null || words.length == 0) { + return resultList; + } + Map wordMap = new HashMap(); + Map foundMap = new HashMap(); + for (String word: words) { + if (wordMap.containsKey(word)) { + wordMap.put(word, (wordMap.get(word) + 1)); + } else { + wordMap.put(word, 1); + } + } + int wordCount = words.length; + int wordLen = words[0].length(); + int allLen = wordLen * wordCount; + + for (int i = 0; i <= s.length() - allLen; i++) { + foundMap.clear(); + int foundCount = 0; + for (int j = 0; j < wordCount; j++) { + String tempWord = s.substring(i + j * wordLen, i + (j + 1) * wordLen); + if (wordMap.containsKey(tempWord)) { + if (foundMap.containsKey(tempWord)) { + foundMap.put(tempWord, (foundMap.get(tempWord) + 1)); + } else { + foundMap.put(tempWord, 1); + } + + if (foundMap.get(tempWord) > wordMap.get(tempWord)) { + break; + } + foundCount++; + } else { + break; + } + } + + if (foundCount == wordCount) { + resultList.add(i); + } + } + + return resultList; + } + + /* + 通过滑动窗口的思维,窗口大小为words数组的1个单位。 + + An O(N) solution with detailed explanation + + travel all the words combinations to maintain a window + + there are wl(word len) times travel + + each time, n/wl words, mostly 2 times travel for each word + + one left side of the window, the other right side of the window + + so, time complexity O(wl * 2 * N/wl) = O(2N) + */ + public List findSubstringByWindowSlide(String s, String[] words) { + List resultList = new ArrayList(); + if (s == null || s.length() == 0 || words == null || words.length == 0) { + return resultList; + } + Map wordMap = new HashMap(); + + int distinguishCount = 0; + for (String word : words) { + wordMap.put(word, wordMap.getOrDefault(word, 0) + 1); + if (wordMap.get(word) == 1) { + distinguishCount += 1; + } + } + int wordLen = words[0].length(); + int wordCount = words.length; + for (int k = 0; k < wordLen; k++) { + Map foundMap = new HashMap(); + int foundCount = 0; + for (int i = k, j = k; j <= s.length() - wordLen; j = j + wordLen) { + + if (j - i >= wordLen * wordCount) { + String firstWord = s.substring(i, i + wordLen); + if (wordMap.containsKey(firstWord)) { + foundMap.put(firstWord, foundMap.get(firstWord) - 1); + if (foundMap.get(firstWord) == wordMap.get(firstWord) - 1) { + foundCount -= 1; + } + } + + i += wordLen; + } + + String nextWord = s.substring(j, j + wordLen); + if (wordMap.containsKey(nextWord)) { + foundMap.put(nextWord, foundMap.getOrDefault(nextWord, 0) + 1); + if (wordMap.get(nextWord) == foundMap.get(nextWord)) { + foundCount += 1; + } + } + + if (foundCount == distinguishCount) { + resultList.add(i); + } + } + + } + + return resultList; + } + + public static void main(String[] args) { + SubstringWithConcatenationOfAllWords obj = new SubstringWithConcatenationOfAllWords(); + String s = "wordgoodgoodgoodbestword"; + String[] words = {"word","good","best","good"}; +// System.out.println("s: " +s+ " \n word: " + Arrays.toString(words) + " \n result: " + Arrays.toString(obj.findSubstring(s, words).toArray())); + System.out.println("s: " +s+ " \n word: " + Arrays.toString(words) + " \n result: " + Arrays.toString(obj.findSubstringByWindowSlide(s, words).toArray())); + + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/SwapNodesInPairs.java b/code/LeetCode/src/SwapNodesInPairs.java new file mode 100644 index 00000000..efc68cba --- /dev/null +++ b/code/LeetCode/src/SwapNodesInPairs.java @@ -0,0 +1,99 @@ +public class SwapNodesInPairs { + /* + Swap Nodes in Pairs + Description + Given a linked list, swap every two adjacent nodes and return its head. + + Example: + + Given 1->2->3->4, you should return the list as 2->1->4->3. + Note: + + Your algorithm should use only constant extra space. + You may not modify the values in the list's nodes, only nodes itself may be changed. + Tags: Linked List + */ + + /* + 思路 0 + 题意是让你交换链表中相邻的两个节点,最终返回交换后链表的头,限定你空间复杂度为 O(1)。 + 我们可以用递归来算出子集合的结果,递归的终点就是指针指到链表末少于两个元素时,如果不是终点, + 那么我们就对其两节点进行交换,这里我们需要一个临时节点来作为交换桥梁,就不多说了。 + */ + + public ListNode swapPairs(ListNode head) { + if (head == null || head.next == null) { + return head; + } + ListNode temp = head.next; + head.next = swapPairs(temp.next); + temp.next = head; + + return temp; + } + + /* + 思路 1 + 另一种实现方式就是用循环来实现了,两两交换节点,也需要一个临时节点来作为交换桥梁, + 直到当前指针指到链表末少于两个元素时停止,代码很简单,如下所示。 + */ + public ListNode swapPairsByLoop(ListNode head) { + ListNode preHead = new ListNode(0); + ListNode current = preHead; + current.next = head; + while (current.next != null && current.next.next != null) { + ListNode temp = current.next.next; + current.next.next = temp.next; + temp.next = current.next; + current.next = temp; + current = temp.next; + } + + return preHead.next; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/SymmetricTree.java b/code/LeetCode/src/SymmetricTree.java new file mode 100644 index 00000000..9e6862a2 --- /dev/null +++ b/code/LeetCode/src/SymmetricTree.java @@ -0,0 +1,125 @@ +import java.util.LinkedList; + +public class SymmetricTree { + /* + Symmetric Tree + Description + Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). + + For example, this binary tree [1,2,2,3,4,4,3] is symmetric: + + 1 + / \ + 2 2 + / \ / \ + 3 4 4 3 + But the following [1,2,2,null,3,null,3] is not: + + 1 + / \ + 2 2 + \ \ + 3 3 + Note: + + Bonus points if you could solve it both recursively and iteratively. + + Tags: Tree, Depth-first Search, Breadth-first Search + */ + + /* + 思路 0 + 题意是判断一棵二叉树是否左右对称,首先想到的是深搜,比较根结点的左右两棵子树是否对称, + 如果左右子树的值相同,那么再分别对左子树的左节点和右子树的右节点,左子树的右节点和右子树的左节点做比较即可。 + */ + public boolean isSymmetric(TreeNode root) { + return root == null || symmetricHelper(root.left, root.right); + } + + public boolean symmetricHelper(TreeNode leftNode, TreeNode rightNode) { + if (leftNode == null || rightNode == null) { + return leftNode == rightNode; + } + if (leftNode.val != rightNode.val) { + return false; + } + return symmetricHelper(leftNode.left, rightNode.right) && symmetricHelper(leftNode.right, rightNode.left); + + } + + /* + 思路 1 + 第二种思路就是宽搜了,宽搜肯定要用到队列,Java 中可用 LinkedList 替代,也是要做到左子树的左节点和右子树的右节点, + 左子树的右节点和右子树的左节点做比较即可。 + */ + public boolean isSymmetricWithBroadSearch(TreeNode root) { + if (root == null) { + return true; + } + LinkedList list = new LinkedList(); + list.add(root.left); + list.add(root.right); + TreeNode leftNode = null; + TreeNode rightNode = null; + while (list.size() > 0) { + leftNode = list.pop(); + rightNode = list.pop(); + if (leftNode == null && rightNode == null) { + continue; + } + if (leftNode == null || rightNode == null) { + return false; + } + if (leftNode.val != rightNode.val) { + return false; + } + list.add(leftNode.left); + list.add(rightNode.right); + + list.add(leftNode.right); + list.add(rightNode.left); + } + + return true; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/TextJustification.java b/code/LeetCode/src/TextJustification.java new file mode 100644 index 00000000..84d9b0a4 --- /dev/null +++ b/code/LeetCode/src/TextJustification.java @@ -0,0 +1,212 @@ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class TextJustification { + /* + Text Justification + Description + Given an array of words and a width maxWidth, format the text such that each line has exactly maxWidth characters and is fully (left and right) justified. + + You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ' ' when necessary so that each line has exactly maxWidth characters. + + Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right. + + For the last line of text, it should be left justified and no extra space is inserted between words. + + Note: + + A word is defined as a character sequence consisting of non-space characters only. + Each word's length is guaranteed to be greater than 0 and not exceed maxWidth. + The input array words contains at least one word. + Example 1: + + Input: + words = ["This", "is", "an", "example", "of", "text", "justification."] + maxWidth = 16 + Output: + [ + "This is an", + "example of text", + "justification. " + ] + Example 2: + + Input: + words = ["What","must","be","acknowledgment","shall","be"] + maxWidth = 16 + Output: + [ + "What must be", + "acknowledgment ", + "shall be " + ] + Explanation: Note that the last line is "shall be " instead of "shall be", + because the last line must be left-justified instead of fully-justified. + Note that the second line is also left-justified becase it contains only one word. + Example 3: + + Input: + words = ["Science","is","what","we","understand","well","enough","to","explain", + "to","a","computer.","Art","is","everything","else","we","do"] + maxWidth = 20 + Output: + [ + "Science is what we", + "understand well", + "enough to explain to", + "a computer. Art is", + "everything else we", + "do " + ] + Tags: String + */ + + /* + 思路 + 题意是给你一组单词和最大行宽,让你对齐他们,对齐的规则就是尽可能一行可以放下足够多的单词,如果最后有多余的空格, + 那就把空格均匀地插入到单词之间,如果不能平分的话,那就从左开始依次多插一个空格,最后一行单词之间就正常地一个空格即可, + 如果凑不到最大行宽,那就在末尾补充空格即可,描述地比较差,不懂的话其实看看 demo 也就懂了哈。 + 题还是比较坑的,毕竟踩的比赞的人多,我也是靠模拟老老实实做出来的,求出可以最多插入空格数,然后用它除以可以插入的槽数 + 获取每个单词之间的空格,它两取余的话就是最面需要多插入一个空格的个数,最后一行的话就单独处理即可。 + */ + + public List fullJustify(String[] words, int maxWidth) { + int minBlank = 1; + List resultList = new ArrayList(); + int wordsLen = words.length; + int startIndex = 0; + int currentLineLength = -1; + StringBuilder blankBuilder = new StringBuilder(); + for (int i = 0; i < maxWidth; i++) { + blankBuilder.append(" "); + } + + //not the last line + for (int i = 0; i < wordsLen; i++) { + //line length <= max + if (currentLineLength + words[i].length() + minBlank <= maxWidth) { + currentLineLength += words[i].length() + minBlank; + } else { + int restBlank = maxWidth - currentLineLength; + int holeNumbers = i - 1 - startIndex; //i is exclude + + StringBuilder subBuilder = new StringBuilder(); + subBuilder.append(words[startIndex]); + + //one word + if (holeNumbers <= 0) { + subBuilder.append(blankBuilder.substring(0, restBlank)); + } else { + //more than one word + int blankPerHole = (restBlank / holeNumbers) + minBlank; + int remainderBlank = restBlank % holeNumbers; + for (int j = startIndex + 1; j < i; j++) { + if (remainderBlank-- > 0) { + //left add more one blank first + subBuilder.append(blankBuilder.substring(0, blankPerHole + 1)).append(words[j]); + } else { + subBuilder.append(blankBuilder.substring(0, blankPerHole)).append(words[j]); + } + } + + } + //append new line string + resultList.add(subBuilder.toString()); + + //update data + startIndex = i; + currentLineLength = words[i].length(); + } + } + + System.currentTimeMillis(); + + //the last line + StringBuilder lastLineBuilder = new StringBuilder(); + lastLineBuilder.append(words[startIndex]); + for (int i = startIndex + 1; i < wordsLen; i++) { + lastLineBuilder.append(" ").append(words[i]); + } + //fill tail blank + int currentSubBuilderLen = lastLineBuilder.toString().length(); + if (currentSubBuilderLen < maxWidth) { + lastLineBuilder.append(blankBuilder.substring(0, maxWidth - currentSubBuilderLen)); + } + resultList.add(lastLineBuilder.toString()); + + return resultList; + } + + public static void main(String[] args) { + TextJustification obj = new TextJustification(); + String[] words = {"What","must","be","acknowledgment","shall","be"}; + int maxWidth = 16; + List resultList = obj.fullJustify(words, maxWidth); + System.out.println(Arrays.toString(resultList.toArray())); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/ThreeSum.java b/code/LeetCode/src/ThreeSum.java new file mode 100644 index 00000000..385bbfd3 --- /dev/null +++ b/code/LeetCode/src/ThreeSum.java @@ -0,0 +1,148 @@ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ThreeSum { + /* + 3Sum + Description + Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. + + Note: + + The solution set must not contain duplicate triplets. + + Example: + + Given array nums = [-1, 0, 1, 2, -1, -4], + + A solution set is: + [ + [-1, 0, 1], + [-1, -1, 2] + ] + Tags: Array, Two Pointers + */ + + /* + 思路 + 题意是让你从数组中找出所有三个和为 0 的元素构成的非重复序列,这样的话我们可以把数组先做下排序, + 然后遍历这个排序数组,用两个指针分别指向当前元素的下一个和数组尾部,判断三者的和与 0 的大小来移动两个指针, + 其中细节操作就是优化和去重。 + */ + + public static void main(String[] args) { + ThreeSum object = new ThreeSum(); + int[] nums = {-1, 0, 1, 2, -1, -4}; + List> resultList = object.threeSum(nums); + System.out.println("resultList: " + resultList); + } + + + + public List> threeSum(int[] nums) { + List> resultList = new ArrayList>(); + int sumTarget = 0; + int length = nums.length; + // 1. delete impossible edge: nums < 3 + if (length < 3) { + return resultList; + } + + // 2. order nums + Arrays.sort(nums); + + + // 3. delete impossible edge: biggest * 3 < 0 + if (nums[length - 1] + nums[length - 2] + nums[length -3] < sumTarget) { + return resultList; + } + + + // 4. delete impossible edge: smallist * 3 > 0 + if (nums[0] + nums[1] + nums[2] > sumTarget) { + return resultList; + } + + + // for loop + for (int i = 0; i < length - 2; ) { + // smallest > 0, break + if (nums[i] > 0) { + break; + } + + // 5. otherwise, smallest + 2 * biggis < 0, smallest ++ + while (nums[i] + nums[length -1] * 2 < sumTarget && i < length - 2) { + i++; + } + // 6. otherwise, smallest * 2 + biggis > 0, smallest -- + while (nums[i] * 2 + nums[length - 1] > sumTarget && i < length - 2) { + length--; + } + + int left = i + 1; + int right = length - 1; + //i 与两头缩放 + while (left < right) { + // 7. find the meet target, + if (nums[i] + nums[left] + nums[right] == sumTarget) { + resultList.add(Arrays.asList(nums[i], nums[left], nums[right])); + + // then skip while(nums[left] == nums[++left], and left < right) , + while (nums[left] == nums[++left] && left < right) { } + // then skip while(nums[right] == nums[--right], and left < right) + while (nums[right] == nums[--right] && left < right) { } + } else if (nums[i] + nums[left] + nums[right] < 0) { + // 8. else if, nums[left] + nums[left + 1] + nums[right] < 0, + // while(nums[left] == nums[++left], and left < right) + while (nums[left] == nums[++left] && left < right) { } + } else { + // 9. else if, nums[i] + nums[left] + nums[right] > 0, + // while(nums[right] == nums[--right], and left < right) + while (nums[right] == nums[--right] && left < right) { } + } + } + + while (nums[i] == nums[++i] && i < length - 2) { } + + + } + + + return resultList; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/ThreeSumClosest.java b/code/LeetCode/src/ThreeSumClosest.java new file mode 100644 index 00000000..6afe5772 --- /dev/null +++ b/code/LeetCode/src/ThreeSumClosest.java @@ -0,0 +1,99 @@ +import java.util.Arrays; + +public class ThreeSumClosest { + /* + 3Sum Closest + Description + Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution. + + Example: + + Given array nums = [-1, 2, 1, -4], and target = 1. + + The sum that is closest to the target is 2. (-1 + 2 + 1 = 2). + Tags: Array, Two Pointers + */ + + /* + 思路 + 题意是让你从数组中找出最接近 target 的三个数的和,该题和 3Sum 的思路基本一样,先对数组进行排序, + 然后遍历这个排序数组,用两个指针分别指向当前元素的下一个和数组尾部,判断三者的和与 target 的差值来移动两个指针, + 并更新其结果,当然,如果三者的和直接与 target 值相同,那么返回 target 结果即可。 + */ + + public int threeSumClosest(int[] nums, int target) { + int gapMin = Integer.MAX_VALUE; + int closestTarget = 0; + int len = nums.length; + Arrays.sort(nums); + for (int i = 0; i < len - 2; i++) { + int left = i + 1; + int right = len - 1; + while (left < right && left < len) { + int sum = nums[i] + nums[left] + nums[right]; + int currentGap = Math.abs(sum - target); + if (currentGap == 0) { + return sum; + } + if (currentGap < gapMin) { + gapMin = currentGap; + closestTarget = sum; + } + + if (sum > target) { + right--; + } else { + left++; + } + } + } + + return closestTarget; + } + + public static void main(String[] args) { + ThreeSumClosest object = new ThreeSumClosest(); + int[] input = {-1, 2, 1, -4}; + int target = 1; + System.out.println("input: {-1, 2, 1, -4}, target: " +target+ ", ouput: " + object.threeSumClosest(input, target)); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/TreeNode.java b/code/LeetCode/src/TreeNode.java new file mode 100644 index 00000000..c45eedeb --- /dev/null +++ b/code/LeetCode/src/TreeNode.java @@ -0,0 +1,8 @@ +public class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { + val = x; + } +} diff --git a/code/LeetCode/src/ValidParentheses.java b/code/LeetCode/src/ValidParentheses.java new file mode 100644 index 00000000..57fc6d82 --- /dev/null +++ b/code/LeetCode/src/ValidParentheses.java @@ -0,0 +1,74 @@ +public class ValidParentheses { + /* + Valid Parentheses + Description + Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. + + An input string is valid if: + + Open brackets must be closed by the same type of brackets. + Open brackets must be closed in the correct order. + Note that an empty string is also considered valid. + + Example 1: + + Input: "()" + Output: true + Example 2: + + Input: "()[]{}" + Output: true + Example 3: + + Input: "(]" + Output: false + Example 4: + + Input: "([)]" + Output: false + Example 5: + + Input: "{[]}" + Output: true + Tags: Stack, String + */ + + /* + 思路 + 题意是判断括号匹配是否正确,很明显,我们可以用栈来解决这个问题,当出现左括号的时候入栈,当遇到右括号时, + 判断栈顶的左括号是否何其匹配,不匹配的话直接返回 false 即可,最终判断是否空栈即可,这里我们可以 + 用数组模拟栈的操作使其操作更快,有个细节注意下 top = 1;,从而省去了之后判空的操作和 top - 1 导致数组越界的错误。 + */ + + public static boolean isValid(String s) { + char stack[] = new char[s.length() + 1]; + int top = 1; + for (char charItem: s.toCharArray()) { + if (charItem == '(' || charItem == '[' || charItem == '{') { + stack[top++] = charItem; + } else if (charItem == ')' && stack[--top] != '(') { + return false; + } else if (charItem == ']' && stack[--top] != '[') { + return false; + } else if (charItem == '}' && stack[--top] != '{') { + return false; + } + } + + + return top == 1; + } + + public static void main(String[] args) { + String input1 = "()"; + System.out.println("input: " + input1 + " result: " + isValid(input1)); + String input2 = "()[]{}"; + System.out.println("input: " + input2 + " result: " + isValid(input2)); + String input3 = "(]"; + System.out.println("input: " + input3 + " result: " + isValid(input3)); + String input4 = "([)]"; + System.out.println("input: " + input4 + " result: " + isValid(input4)); + String input5 = "{[]}"; + System.out.println("input: " + input5 + " result: " + isValid(input5)); + } +} diff --git a/code/LeetCode/src/WildcardMatching.java b/code/LeetCode/src/WildcardMatching.java new file mode 100644 index 00000000..a6493513 --- /dev/null +++ b/code/LeetCode/src/WildcardMatching.java @@ -0,0 +1,203 @@ +import java.util.Arrays; + +public class WildcardMatching { + /* + Wildcard Matching + Description + Given an input string (s) and a pattern (p), implement wildcard pattern matching with support for '?' and '*'. + + '?' Matches any single character. + '*' Matches any sequence of characters (including the empty sequence). + The matching should cover the entire input string (not partial). + + Note: + + s could be empty and contains only lowercase letters a-z. + p could be empty and contains only lowercase letters a-z, and characters like ? or *. + Example 1: + + Input: + s = "aa" + p = "a" + Output: false + Explanation: "a" does not match the entire string "aa". + Example 2: + + Input: + s = "aa" + p = "*" + Output: true + Explanation: '*' matches any sequence. + Example 3: + + Input: + s = "cb" + p = "?a" + Output: false + Explanation: '?' matches 'c', but the second letter is 'a', which does not match 'b'. + Example 4: + + Input: + s = "adceb" + p = "*a*b" + Output: true + Explanation: The first '*' matches the empty sequence, while the second '*' matches the substring "dce". + Example 5: + + Input: + s = "acdcb" + p = "a*c?b" + Output: false + Tags: String, Dynamic Programming, Backtracking, Greedy + */ + + /* + 思路 0 + 题意是让让你从判断 s 字符串是否通配符匹配于 p,这道题和Regular Expression Matching很是相似, + 区别在于 *,正则匹配的 * 不能单独存在,前面必须具有一个字符,其意义是表明前面的这个字符个数可以是任意个数,包括 0 个; + 而通配符的 * 是可以随意出现的,跟前面字符没有任何关系,其作用是可以表示任意字符串。 + 在此我们可以利用 贪心算法 来解决这个问题,需要两个额外指针 p 和 match 来分别记录最后一个 * 的位置和 * 匹配到 s 字符串的位置, + 其贪心体现在如果遇到 *,那就尽可能取匹配后方的内容,如果匹配失败,那就回到上一个遇到 * 的位置来继续贪心。 + */ + + public boolean isMatchByGreedy(String s, String p) { + if (p.isEmpty()) { + return s.isEmpty(); + } + int sindex = 0; + int pindex = 0; + int smatch = 0; + int pstar = -1; + int slen = s.isEmpty() ? 0 : s.length(); + int plen = p.isEmpty() ? 0 : p.length(); + char[] schars = s.isEmpty() ? null : s.toCharArray(); + char[] pchars = p.isEmpty() ? null : p.toCharArray(); + while (sindex < slen) { + if (pindex < plen && (schars[sindex] == pchars[pindex] || pchars[pindex] == '?')) { + sindex++; + pindex++; + } else if (pindex < plen && pchars[pindex] == '*') { + smatch = sindex; + pstar = pindex++; + } else if (pstar != -1) { + sindex = ++smatch; + pindex = pstar + 1; + } else { + return false; + } + } + + while (pindex < plen && pchars[pindex] == '*') { + pindex++; + } + + return pindex == plen; + } + + /* + 思路 1 + 另一种思路就是动态规划了,我们定义 dp[i][j] 的真假来表示 s[0..i) 是否匹配 p[0..j),其状态转移方程如下所示: + + 如果 p[j - 1] != '*',P[i][j] = P[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '?'); + + 如果 p[j - 1] == '*',P[i][j] = P[i][j - 1] || P[i - 1][j] + */ + public boolean isMatchByDynamic(String s, String p) { + if (p.isEmpty()) { + return s.isEmpty(); + } + int slen = s.isEmpty() ? 0 : s.length(); + int plen = p.isEmpty() ? 0 : p.length(); + char[] schars = s.isEmpty() ? null : s.toCharArray(); + char[] pchars = p.isEmpty() ? null : p.toCharArray(); + boolean[][] spFlag = new boolean[slen + 1][plen + 1]; + spFlag[0][0] = true; + + for (int i = 1; i <= plen; i++) { + if (pchars[i - 1] == '*') { + spFlag[0][i] = spFlag[0][i - 1]; + } + } + for (int i = 1; i <= slen; i++) { + for (int j = 1; j <= plen; j++) { + if (pchars[j - 1] != '*') { + spFlag[i][j] = spFlag[i - 1][j - 1] && (pchars[j - 1] == schars[i - 1] || pchars[j - 1] == '?'); + } else { + spFlag[i][j] = spFlag[i][j - 1] || spFlag[i - 1][j]; + } + } + } + + return spFlag[slen][plen]; + } + + public static void main(String[] args) { + WildcardMatching obj = new WildcardMatching(); + String s0 = "aab"; + String p0 = "c*a*b"; + System.out.println("s: " +s0+ " ,p: " +p0+ " , result: " +obj.isMatchByDynamic(s0, p0)); + +// String s1 = "aa"; +// String p1 = "a"; +// System.out.println("s: " +s1+ " ,p: " +p1+ " , result: " +obj.isMatchByDynamic(s1, p1)); +// +// String s2 = "aa"; +// String p2 = "*"; +// System.out.println("s: " +s2+ " ,p: " +p2+ " , result: " +obj.isMatchByDynamic(s2, p2)); +// +// String s3 = "cb"; +// String p3 = "*a"; +// System.out.println("s: " +s3+ " ,p: " +p3+ " , result: " +obj.isMatchByDynamic(s3, p3)); +// +// String s4 = "adceb"; +// String p4 = "*a*b"; +// System.out.println("s: " +s4+ " ,p: " +p4+ " , result: " +obj.isMatchByDynamic(s4, p4)); +// +// String s5 = "acdcb"; +// String p5 = "a*c?b"; +// System.out.println("s: " +s5+ " ,p: " +p5+ " , result: " +obj.isMatchByDynamic(s5, p5)); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/code/LeetCode/src/ZigzagConversion.java b/code/LeetCode/src/ZigzagConversion.java new file mode 100644 index 00000000..ddf8795e --- /dev/null +++ b/code/LeetCode/src/ZigzagConversion.java @@ -0,0 +1,163 @@ +public class ZigzagConversion { + /* + ZigZag Conversion + Description + The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) + + P A H N + A P L S I I G + Y I R + And then read line by line: "PAHNAPLSIIGYIR" + + Write the code that will take a string and make this conversion given a number of rows: + + string convert(string s, int numRows); + Example 1: + + Input: s = "PAYPALISHIRING", numRows = 3 + Output: "PAHNAPLSIIGYIR" + Example 2: + + Input: s = "PAYPALISHIRING", numRows = 4 + Output: "PINALSIGYAHRPI" + Explanation: + + P I N + A L S I G + Y A H R + P I + Tags: String + */ + + /* + 思路 0 + 题意是让你把字符串按波浪形排好,然后返回横向读取的字符串。 + + 听不懂的话,看下面的表示应该就明白了: + + 0 2n-2 4n-4 + 1 2n-3 2n-1 4n-5 4n-3 + 2 2n-4 2n 4n-6 . + . . . . . + . n+1 . 3n-1 . + n-2 n 3n-4 3n-2 5n-6 + n-1 3n-3 5n-5 + 那么我们可以根据上面找规律,可以看到波峰和波谷是单顶点的,它们周期是 2 * (n - 1),单独处理即可; + 中间的部分每个周期会出现两次,规律很好找,留给读者自己想象,不懂的可以结合以下代码。 + */ + + public String convert(String s, int numRows) { + if (numRows <= 1) { + return s; + } + int length = s.length(); + char[] chars = s.toCharArray(); + int cycleInt = 2 * (numRows - 1); + StringBuilder sb = new StringBuilder(); + //first row + for (int i = 0; i < length; i += cycleInt) { + sb.append(chars[i]); + } + + //middle rows + for (int i = 1; i < numRows - 1; i++) { + int step = i * 2; + for (int j = i; j < length; j += step) { + sb.append(chars[j]); + step = cycleInt - step; + } + } + + //last row + for (int i = numRows - 1; i < length; i += cycleInt) { + sb.append(chars[i]); + } + + return sb.toString(); + } + + /* + 思路 1 + 另外一种思路就是开辟相应行数的 StringBuilder 对象, + 然后模拟波浪生成的样子分别插入到相应的 StringBuilder 对象,比较直白简单,具体代码如下。 + */ + public String convertWithRowSubBuilder(String s, int numRows) { + if (numRows <= 1) { + return s; + } + int length = s.length(); + int cycle = 2 * (numRows - 1); + char[] chars = s.toCharArray(); + StringBuilder[] rowSb = new StringBuilder[numRows]; + for (int i = 0; i < numRows; i++) { + rowSb[i] = new StringBuilder(); + } + int i = 0; + while (i < length) { + for (int j = 0; j < numRows && i < length; ++j) { + rowSb[j].append(chars[i++]); + } + for (int j = numRows - 2; j >= 1 && i < length; --j) { + rowSb[j].append(chars[i++]); + } + + } + for (int j = 1; j < numRows; j++) { + rowSb[0].append(rowSb[j]); + } + + return rowSb[0].toString(); + } + + public static void main(String[] args) { + String input = "PAYPALISHIRING"; + int row = 3; + ZigzagConversion obj = new ZigzagConversion(); + //PAHNAPLSIIGYIR +// String output = obj.convert(input, row); + String output = obj.convertWithRowSubBuilder(input, row); + + System.out.println("input: " + input + " , output: " + output); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} From c2f2cddd28ae04f967862815cc3bd8ddf66c6b0d Mon Sep 17 00:00:00 2001 From: zgpeace Date: Thu, 21 Feb 2019 10:19:42 +0800 Subject: [PATCH 010/162] Majority Element --- code/LeetCode/src/MajorityElement.java | 34 ++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 code/LeetCode/src/MajorityElement.java diff --git a/code/LeetCode/src/MajorityElement.java b/code/LeetCode/src/MajorityElement.java new file mode 100644 index 00000000..918a0b93 --- /dev/null +++ b/code/LeetCode/src/MajorityElement.java @@ -0,0 +1,34 @@ +import java.util.HashMap; +import java.util.Map; + +public class MajorityElement { + + public int majorityElement(int[] nums) { + if (nums.length == 1) { + return nums[0]; + } + + int majorityKey = 0; + int majorityCount = 0; + + Map numCountMap = new HashMap<>(); + for (int num: nums) { + if (numCountMap.containsKey(num)) { + numCountMap.put(num, numCountMap.get(num) + 1); + if (numCountMap.get(num) > majorityCount) { + majorityCount = numCountMap.get(num); + majorityKey = num; + } + } else { + numCountMap.put(num, 1); + } + } + + return majorityKey; + } + + public static void main(String[] args) { + int[] inputNums = {2,2,1,1,1,2,2}; + System.out.println("Output: " + new MajorityElement().majorityElement(inputNums)); + } +} From d6fc0af781c66b406f91222403d7040be0e9c458 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 22 Feb 2019 10:17:18 +0800 Subject: [PATCH 011/162] FirstMissingPositive --- code/LeetCode/src/FirstMissingPositive.java | 58 +++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 code/LeetCode/src/FirstMissingPositive.java diff --git a/code/LeetCode/src/FirstMissingPositive.java b/code/LeetCode/src/FirstMissingPositive.java new file mode 100644 index 00000000..82cd3f61 --- /dev/null +++ b/code/LeetCode/src/FirstMissingPositive.java @@ -0,0 +1,58 @@ +public class FirstMissingPositive { + + /** + * + * Given an unsorted integer array, find the smallest missing positive integer. + * + * Example 1: + * + * Input: [1,2,0] + * Output: 3 + * Example 2: + * + * Input: [3,4,-1,1] + * Output: 2 + * Example 3: + * + * Input: [7,8,9,11,12] + * Output: 1 + * Note: + * + * Your algorithm should run in O(n) time and uses constant extra space. + */ + + + public int firstMissingPositive(int[] nums) { + int len = nums.length; + if (len == 0) { + return 1; + } + boolean[] orderBools = new boolean[len + 2]; + for (int num: nums) { + if (num < 0 || num > len + 1) { + continue; + } + orderBools[num] = true; + } + + for (int i = 1; i < len + 2 ; i++) { + if (!orderBools[i]) { + return i; + } + } + + return 1; + } + + public static void main(String[] args) { + FirstMissingPositive obj = new FirstMissingPositive(); + int[] nums = {1}; + System.out.println("expect 2, Output: " + obj.firstMissingPositive(nums)); + + nums = new int[]{}; + System.out.println("expect 1, Output: " + obj.firstMissingPositive(nums)); + + nums = new int[]{7,8,9,11,12}; + System.out.println("expect 1, Output: " + obj.firstMissingPositive(nums)); + } +} From 1ab5e14c469c24e1354b453640fde9dca4a7bb60 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Sat, 23 Feb 2019 12:28:20 +0800 Subject: [PATCH 012/162] LinkedListCycle --- .../LeetCode/src/popular/LinkedListCycle.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 code/LeetCode/src/popular/LinkedListCycle.java diff --git a/code/LeetCode/src/popular/LinkedListCycle.java b/code/LeetCode/src/popular/LinkedListCycle.java new file mode 100644 index 00000000..e3aaee12 --- /dev/null +++ b/code/LeetCode/src/popular/LinkedListCycle.java @@ -0,0 +1,49 @@ +package popular; + +import java.util.HashSet; +import java.util.Set; + +class ListNode { + int val; + ListNode next; + ListNode(int x) { + val = x; + next = null; + } + +} + +public class LinkedListCycle { + public boolean hasCycle(ListNode head) { + Set pastSet = new HashSet<>(); + while (head != null) { + if (pastSet.contains(head.val)) { + return true; + } else { + pastSet.add(head.val); + head = head.next; + } + } + + return false; + } + + public boolean hasCycleWithTwoPoint(ListNode head) { + if (head == null || head.next == null) { + return false; + } + ListNode slowNode = head; + ListNode fastNode = head.next; + while (slowNode != fastNode) { + if (slowNode == null || fastNode == null || fastNode.next == null) { + return false; + } + slowNode = slowNode.next; + fastNode = fastNode.next.next; + } + + return true; + } + + +} From 6649edb61d13ea45d1462657e2189796a1f57338 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Wed, 27 Feb 2019 10:51:03 +0800 Subject: [PATCH 013/162] LongestValidParentheses --- .../src/popular/LongestValidParentheses.java | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 code/LeetCode/src/popular/LongestValidParentheses.java diff --git a/code/LeetCode/src/popular/LongestValidParentheses.java b/code/LeetCode/src/popular/LongestValidParentheses.java new file mode 100644 index 00000000..48bde804 --- /dev/null +++ b/code/LeetCode/src/popular/LongestValidParentheses.java @@ -0,0 +1,82 @@ +package popular; + +import java.util.Stack; + +public class LongestValidParentheses { + + /** + * 用Stack存储开始匹配的上一个位置,那么当前的位置减去上个位置,就是最长的匹配, + * 时间复杂度为O(n), 空间复杂度为O(n) + * @param s + * @return + */ + public int longestValidParentheses(String s) { + int len = s.length(); + Stack stack = new Stack<>(); + stack.push(-1); + int maxLen = 0; + for (int i = 0; i < len; i++) { + if (s.charAt(i) == '(') { + stack.push(i); + } else { + stack.pop(); + if (stack.isEmpty()) { + stack.push(i); + } else { + maxLen = Math.max(maxLen, i - stack.peek()); + } + } + } + + return maxLen; + } + + + /** + * 从左到右,又从右到左,两个方向找最长的匹配。 + * 时间复杂度为O(n), 空间复杂度为O(1) + * @param s + * @return + */ + public int longestValidParenthesesWithoutStack(String s) { + int left = 0; + int right = 0; + int maxLen = 0; + int len = s.length(); + for (char c: s.toCharArray()) { + if (c == '(') { + left++; + } else { + right++; + } + if (left == right) { + maxLen = Math.max(maxLen, right * 2); + } else if (right > left) { + left = right = 0; + } + } + + left = right = 0; + for (int i = len - 1; i >= 0; i--) { + if (s.charAt(i) == '(') { + left++; + } else { + right++; + } + if (left == right) { + maxLen = Math.max(maxLen, left * 2); + } else if (left > right) { + left = right = 0; + } + } + + return maxLen; + } + + public static void main(String[] args) { + String input = "((())"; + LongestValidParentheses obj = new LongestValidParentheses(); + //System.out.println("input: ((()), Output -> " + obj.longestValidParentheses(input)); + System.out.println("input: ((()), Output -> " + obj.longestValidParenthesesWithoutStack(input)); + } +} From be047586474d4caa364c0a4bc3650dc4aa7e4f7b Mon Sep 17 00:00:00 2001 From: zgpeace Date: Thu, 28 Feb 2019 09:57:21 +0800 Subject: [PATCH 014/162] EvaluateReversePolishNotation --- .../EvaluateReversePolishNotation.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 code/LeetCode/src/popular/EvaluateReversePolishNotation.java diff --git a/code/LeetCode/src/popular/EvaluateReversePolishNotation.java b/code/LeetCode/src/popular/EvaluateReversePolishNotation.java new file mode 100644 index 00000000..2b04ee7d --- /dev/null +++ b/code/LeetCode/src/popular/EvaluateReversePolishNotation.java @@ -0,0 +1,37 @@ +package popular; + +import java.util.Stack; + +public class EvaluateReversePolishNotation { + + public int evalRPN(String[] tokens) { + Stack stack = new Stack<>(); + int temp = 0; + for (String s: tokens) { + if (s.equals("+")) { + temp = stack.pop() + stack.pop(); + } else if (s.equals("-")) { + int right = stack.pop(); + int left = stack.pop(); + temp = left - right; + } else if (s.equals("*")) { + temp = stack.pop() * stack.pop(); + } else if (s.equals("/")) { + int right = stack.pop(); + int left = stack.pop(); + temp = left / right; + } else { + temp = Integer.parseInt(s); + } + stack.push(temp); + } + + return temp; + } + + public static void main(String[] args) { + EvaluateReversePolishNotation obj = new EvaluateReversePolishNotation(); + String[] input = {"2", "1", "+", "3", "*"}; + System.out.println("ouput: " + obj.evalRPN(input)); + } +} From 4068229483d83083ddcabc1707a3866120e80f70 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 8 Mar 2019 10:22:18 +0800 Subject: [PATCH 015/162] MyCircularDeque --- .../LeetCode/src/popular/MyCircularDeque.java | 171 ++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 code/LeetCode/src/popular/MyCircularDeque.java diff --git a/code/LeetCode/src/popular/MyCircularDeque.java b/code/LeetCode/src/popular/MyCircularDeque.java new file mode 100644 index 00000000..482fb626 --- /dev/null +++ b/code/LeetCode/src/popular/MyCircularDeque.java @@ -0,0 +1,171 @@ +package popular; + + +class DoubleLinkNode { + public DoubleLinkNode pre; + public DoubleLinkNode next; + public int val; + public DoubleLinkNode(int val) { + this.val = val; + } + +} + +public class MyCircularDeque { + int size; + int capacity; + DoubleLinkNode head; + DoubleLinkNode tail; + + /** Initialize your data structure here. Set the size the deque to be k. */ + public MyCircularDeque(int k) { + head = new DoubleLinkNode(-1); + tail = new DoubleLinkNode(-1); + head.next = tail; + tail.pre = head; + + //head.next = tail; + //tail.pre = head; + + size = 0; + capacity = k; + } + + /** Adds an item at the front of Deque. Return true if the operation is successful. */ + public boolean insertFront(int value) { + if (isFull()) { + return false; + } + + DoubleLinkNode node = new DoubleLinkNode(value); + node.next = head.next; + node.pre = head; + head.next.pre = node; + head.next = node; + + size++; + + return true; + } + + /** Adds an item at the rear of Deque. Return true if the operation is successful. */ + public boolean insertLast(int value) { + if (isFull()) { + return false; + } + + DoubleLinkNode node = new DoubleLinkNode(value); + node.pre = tail.pre; + node.next = tail; + tail.pre.next = node; + tail.pre = node; + + size++; + + return true; + } + + /** Deletes an item from the front of Deque. Return true if the operation is successful. */ + public boolean deleteFront() { + if (isEmpty()) { + return false; + } + + head.next.next.pre = head; + head.next = head.next.next; + + size--; + + return true; + } + + /** Deletes an item from the rear of Deque. Return true if the operation is successful. */ + public boolean deleteLast() { + if (isEmpty()) { + return false; + } + + tail.pre.pre.next = tail; + tail.pre = tail.pre.pre; + + size--; + + return true; + } + + /** Get the front item from the deque. */ + public int getFront() { + return head.next.val; + } + + /** Get the last item from the deque */ + public int getRear() { + + return tail.pre.val; + } + + /** Checks whether the circular deque is empty or not. */ + public boolean isEmpty() { + return size == 0; + } + + /** Checks whether the circular deque is full or not. */ + public boolean isFull() { + return size == capacity; + } + + public static void main(String[] args) { + /** Your MyCircularDeque object will be instantiated and called as such: */ + //["MyCircularDeque","insertFront","deleteLast","getRear","getFront","getFront","deleteFront","insertFront","insertLast","insertFront","getFront","insertFront"] + //[[4],[9],[],[],[],[],[],[6],[5],[9],[],[6]] + int k = 1000; + MyCircularDeque obj = new MyCircularDeque(k); + boolean param_1 = obj.insertFront(1); + boolean param_2 = obj.insertLast(20); + int param_5 = obj.getFront(); + int param_6 = obj.getRear(); + boolean param_3 = obj.deleteFront(); + boolean param_4 = obj.deleteLast(); + boolean param_7 = obj.isEmpty(); + boolean param_8 = obj.isFull(); + + } + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 1a44e95bff831b606e316fd7e859f14f8776a37b Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 8 Mar 2019 10:27:27 +0800 Subject: [PATCH 016/162] =?UTF-8?q?=20=20=20=20=20=20=20=20//=20=E4=B8=8B?= =?UTF-8?q?=E9=9D=A2=E4=B8=A4=E5=8F=A5=E4=BB=A3=E7=A0=81=EF=BC=8C=E5=AE=9E?= =?UTF-8?q?=E9=99=85=E6=98=AF=E6=9E=84=E6=88=90=E5=BE=AA=E7=8E=AF=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E3=80=82=E4=BD=86=E6=98=AF=E5=8A=A0=E4=B8=8D=E5=8A=A0?= =?UTF-8?q?=EF=BC=8CLeetCode=E9=83=BD=E5=8F=AF=E4=BB=A5=E9=80=9A=E8=BF=87?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/LeetCode/src/popular/MyCircularDeque.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/LeetCode/src/popular/MyCircularDeque.java b/code/LeetCode/src/popular/MyCircularDeque.java index 482fb626..b9f8831d 100644 --- a/code/LeetCode/src/popular/MyCircularDeque.java +++ b/code/LeetCode/src/popular/MyCircularDeque.java @@ -24,8 +24,9 @@ public MyCircularDeque(int k) { head.next = tail; tail.pre = head; - //head.next = tail; - //tail.pre = head; + // 下面两句代码,实际是构成循环列表。但是加不加,LeetCode都可以通过。 + head.pre = tail; + tail.next = head; size = 0; capacity = k; From 845064711ef53373de1b1fb05fa197a454b9a260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BF=9D=E7=8A=B6?= Date: Fri, 8 Mar 2019 10:35:18 +0800 Subject: [PATCH 017/162] Create README.md --- code/LeetCode/src/popular/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 code/LeetCode/src/popular/README.md diff --git a/code/LeetCode/src/popular/README.md b/code/LeetCode/src/popular/README.md new file mode 100644 index 00000000..8656fe66 --- /dev/null +++ b/code/LeetCode/src/popular/README.md @@ -0,0 +1,10 @@ + + +| # | Title | Tag | +| :--- | :--------------------------------------- | :--------------------------------------- | +| 1 | [算法:Design Circular Deque(设计一个双端队列)][641] | queue | + + + + +[641]:https://blog.csdn.net/zgpeace/article/details/88340806 From fe81a54975cf953198302ba8e251bc00dd7db54f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BF=9D=E7=8A=B6?= Date: Fri, 8 Mar 2019 10:36:55 +0800 Subject: [PATCH 018/162] Update README.md --- code/LeetCode/src/popular/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/LeetCode/src/popular/README.md b/code/LeetCode/src/popular/README.md index 8656fe66..fdbd8df5 100644 --- a/code/LeetCode/src/popular/README.md +++ b/code/LeetCode/src/popular/README.md @@ -1,8 +1,8 @@ -| # | Title | Tag | -| :--- | :--------------------------------------- | :--------------------------------------- | -| 1 | [算法:Design Circular Deque(设计一个双端队列)][641] | queue | +| # | Title | Tag |code| +| :--- | :--------------------------------------- | :--------------------------------------- | :---| +| 1 | [算法:Design Circular Deque(设计一个双端队列)][641] | queue | MyCircularDeque.java | From 9ec7d13b3981f1522df13987858e62fe347023fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BF=9D=E7=8A=B6?= Date: Fri, 8 Mar 2019 10:37:32 +0800 Subject: [PATCH 019/162] Update README.md --- code/LeetCode/src/popular/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/LeetCode/src/popular/README.md b/code/LeetCode/src/popular/README.md index fdbd8df5..2ba64295 100644 --- a/code/LeetCode/src/popular/README.md +++ b/code/LeetCode/src/popular/README.md @@ -2,7 +2,7 @@ | # | Title | Tag |code| | :--- | :--------------------------------------- | :--------------------------------------- | :---| -| 1 | [算法:Design Circular Deque(设计一个双端队列)][641] | queue | MyCircularDeque.java | +| 1 | [Design Circular Deque(设计一个双端队列)][641] | queue | MyCircularDeque.java | From 93ae54c1c23e9b660964d4e7835a31d4c00c8896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BF=9D=E7=8A=B6?= Date: Fri, 8 Mar 2019 10:46:49 +0800 Subject: [PATCH 020/162] Update README.md --- code/LeetCode/src/popular/README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/code/LeetCode/src/popular/README.md b/code/LeetCode/src/popular/README.md index 2ba64295..082a1cd7 100644 --- a/code/LeetCode/src/popular/README.md +++ b/code/LeetCode/src/popular/README.md @@ -2,9 +2,15 @@ | # | Title | Tag |code| | :--- | :--------------------------------------- | :--------------------------------------- | :---| -| 1 | [Design Circular Deque(设计一个双端队列)][641] | queue | MyCircularDeque.java | +| 641 | [Design Circular Deque(设计一个双端队列)][641] | queue | MyCircularDeque | +| 32 | [Longest Valid Parentheses(最长有效的括号)][32] | stack | LongestValidParentheses | +| 150 | [Evaluate Reverse Polish Notation(逆波兰表达式求值)][150] | stack | EvaluateReversePolishNotation | +| 141 | [Linked List Cycle(环形链表)][141] | List | LinkedListCycle | [641]:https://blog.csdn.net/zgpeace/article/details/88340806 +[32]:https://blog.csdn.net/zgpeace/article/details/87968737 +[150]:https://blog.csdn.net/zgpeace/article/details/88014930 +[141]:https://blog.csdn.net/zgpeace/article/details/87890399 From 88611d4980ecd4e59ea2ee01e9f4baee13091d70 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Sat, 9 Mar 2019 22:57:03 +0800 Subject: [PATCH 021/162] SlidingWindowMaximum --- .../src/popular/SlidingWindowMaximum.java | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 code/LeetCode/src/popular/SlidingWindowMaximum.java diff --git a/code/LeetCode/src/popular/SlidingWindowMaximum.java b/code/LeetCode/src/popular/SlidingWindowMaximum.java new file mode 100644 index 00000000..e7ababf1 --- /dev/null +++ b/code/LeetCode/src/popular/SlidingWindowMaximum.java @@ -0,0 +1,72 @@ +package popular; + +import java.util.ArrayDeque; +import java.util.Arrays; +import java.util.Deque; + +public class SlidingWindowMaximum { + + public int[] maxSlidingWindow(int[] nums, int k) { + if (nums == null || nums.length == 0 || k <= 0) { + return new int[0]; + } + int len = nums.length; + int[] windowMaxArray = new int[len - k + 1]; + int[] leftMaxArray = new int[len]; + int[] rightMaxArray = new int[len]; + + int rightIndex; + for (int i = 0; i < len; i++) { + leftMaxArray[i] = i % k == 0 ? nums[i] : Math.max(leftMaxArray[i - 1], nums[i]); + rightIndex = len - i - 1; + rightMaxArray[rightIndex] = (i == 0 || (rightIndex + 1) % k == 0) ? nums[rightIndex] : Math.max(rightMaxArray[rightIndex + 1], nums[rightIndex]); + } + + for (int j = 0; j <= len - k; j++) { + windowMaxArray[j] = Math.max(leftMaxArray[j + k - 1], rightMaxArray[j]); + } + + return windowMaxArray; + } + + public int[] maxSlidingWindowWithDeque(int[] nums, int k) { + if (nums == null || nums.length == 0 || k <= 0) { + return new int[0]; + } + int len = nums.length; + int[] windowMax = new int[len - k + 1]; + int windowIndex = 0; + // store index + Deque deque = new ArrayDeque<>(); + for (int i = 0; i < len; i++) { + // remove numbers out of range k + while (!deque.isEmpty() && deque.peek() < i - k + 1) { + deque.poll(); + } + // remove smaller numbers in k range as they are useless + while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) { + deque.poll(); + } + // deque contains index... r contains content + deque.offer(i); + + if (i + 1 >= k) { + windowMax[windowIndex++] = nums[deque.peek()]; + } + } + + return windowMax; + } + + public static void main(String[] args) { + int[] nums = {1,3,-1,-3,5,3,6,7}; + int k = 3; + SlidingWindowMaximum obj = new SlidingWindowMaximum(); + //int[] windowMax = obj.maxSlidingWindow(nums, k); + int[] windowMax = obj.maxSlidingWindowWithDeque(nums, k); + System.out.println("Output: " + Arrays.toString(windowMax)); + } + + + +} From b63fbf834b881999249bf903df9afc190d4b6b30 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Sun, 10 Mar 2019 17:17:46 +0800 Subject: [PATCH 022/162] update deque.pollLast --- code/LeetCode/src/popular/SlidingWindowMaximum.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/LeetCode/src/popular/SlidingWindowMaximum.java b/code/LeetCode/src/popular/SlidingWindowMaximum.java index e7ababf1..abc39cee 100644 --- a/code/LeetCode/src/popular/SlidingWindowMaximum.java +++ b/code/LeetCode/src/popular/SlidingWindowMaximum.java @@ -45,7 +45,7 @@ public int[] maxSlidingWindowWithDeque(int[] nums, int k) { } // remove smaller numbers in k range as they are useless while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) { - deque.poll(); + deque.pollLast(); } // deque contains index... r contains content deque.offer(i); @@ -59,7 +59,8 @@ public int[] maxSlidingWindowWithDeque(int[] nums, int k) { } public static void main(String[] args) { - int[] nums = {1,3,-1,-3,5,3,6,7}; + //int[] nums = {1,3,-1,-3,5,3,6,7}; + int[] nums = {1,3,1,2,0,5}; int k = 3; SlidingWindowMaximum obj = new SlidingWindowMaximum(); //int[] windowMax = obj.maxSlidingWindow(nums, k); From 017fd8d5974eab1c230a14fb968f6d022cc7931c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BF=9D=E7=8A=B6?= Date: Sun, 10 Mar 2019 17:36:58 +0800 Subject: [PATCH 023/162] Update README.md --- code/LeetCode/src/popular/README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/code/LeetCode/src/popular/README.md b/code/LeetCode/src/popular/README.md index 082a1cd7..5fc33778 100644 --- a/code/LeetCode/src/popular/README.md +++ b/code/LeetCode/src/popular/README.md @@ -2,10 +2,11 @@ | # | Title | Tag |code| | :--- | :--------------------------------------- | :--------------------------------------- | :---| -| 641 | [Design Circular Deque(设计一个双端队列)][641] | queue | MyCircularDeque | -| 32 | [Longest Valid Parentheses(最长有效的括号)][32] | stack | LongestValidParentheses | -| 150 | [Evaluate Reverse Polish Notation(逆波兰表达式求值)][150] | stack | EvaluateReversePolishNotation | -| 141 | [Linked List Cycle(环形链表)][141] | List | LinkedListCycle | +| 641 | [Design Circular Deque(设计一个双端队列)][641] | queue | MyCircularDeque | +| 32 | [Longest Valid Parentheses(最长有效的括号)][32] | stack | LongestValidParentheses | +| 150 | [Evaluate Reverse Polish Notation(逆波兰表达式求值)][150]| stack | EvaluateReversePolishNotation | +| 141 | [Linked List Cycle(环形链表)][141] | List | LinkedListCycle | +|239 | [Sliding Window Maximum(滑动窗口最大值)][239] | Deque, LinkedList| SlidingWindowMaximum | @@ -14,3 +15,4 @@ [32]:https://blog.csdn.net/zgpeace/article/details/87968737 [150]:https://blog.csdn.net/zgpeace/article/details/88014930 [141]:https://blog.csdn.net/zgpeace/article/details/87890399 +[239]:https://blog.csdn.net/zgpeace/article/details/88372784 From fa60958b742083122c3f8bc7bde82f0edaa441a7 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Sun, 10 Mar 2019 19:30:53 +0800 Subject: [PATCH 024/162] update multiple solution --- code/LeetCode/src/ClimbingStairs.java | 74 +++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/code/LeetCode/src/ClimbingStairs.java b/code/LeetCode/src/ClimbingStairs.java index 30516387..3e6b6a1e 100644 --- a/code/LeetCode/src/ClimbingStairs.java +++ b/code/LeetCode/src/ClimbingStairs.java @@ -51,6 +51,75 @@ public static int climbStairs(int n) { return b; } + public static int climbStairsWithRecursion(int n) { + if (n == 1) { + return 1; + } else if (n == 2) { + return 2; + } else { + return climbStairsWithRecursion(n - 1) + climbStairsWithRecursion(n - 2); + } + } + + + public static int climbStairsWithRecursionMemory(int n) { + int[] memoryArray = new int[n + 1]; + return subClimbStairsWithRecursionMemory(n - 1, memoryArray) + subClimbStairsWithRecursionMemory(n - 2, memoryArray); + + } + + public static int subClimbStairsWithRecursionMemory(int n, int[] memoryArray) { + if (n == 1) { + return 1; + } else if (n == 2) { + return 2; + } else { + if (memoryArray[n] > 0) { + return memoryArray[n]; + } + memoryArray[n] = subClimbStairsWithRecursionMemory(n - 1, memoryArray) + subClimbStairsWithRecursionMemory(n - 2, memoryArray); + + return memoryArray[n]; + } + } + + public static int climbStairsWithDynamic(int n) { + if (n == 1) { + return 1; + } + int dynamicArray[] = new int[n + 1]; + dynamicArray[1] = 1; + dynamicArray[2] = 2; + for (int i = 3; i <= n; i++) { + dynamicArray[i] = dynamicArray[i - 1] + dynamicArray[i - 2]; + } + + return dynamicArray[n]; + } + + public static int climbStairsWithFibonacci(int n) { + if (n == 1) { + return 1; + } + int first = 1; + int second = 2; + for (int i = 3; i <= n; i++) { + int third = first + second; + first = second; + second =third; + } + + return second; + } + + + public static int climbStairsWithFibonacciFormula(int n) { + double sqrt5= Math.sqrt(5); + double fibn = Math.pow((1 + sqrt5) / 2, n + 1) - Math.pow((1 - sqrt5) / 2, n + 1); + return (int)(fibn / sqrt5); + } + + public static void main(String[] args) { int n1 = 2; System.out.println("input: " + n1 + " climbStairs: " + climbStairs(n1)); @@ -58,6 +127,11 @@ public static void main(String[] args) { System.out.println("input: " + n2 + " climbStairs: " + climbStairs(n2)); int n3 = 20; System.out.println("input: " + n3 + " climbStairs: " + climbStairs(n3)); + System.out.println("input: " + n3 + " climbStairsWithRecursion: " + climbStairsWithRecursion(n3)); + System.out.println("input: " + n3 + " climbStairsWithRecursionMemory: " + climbStairsWithRecursionMemory(n3)); + System.out.println("input: " + n3 + " climbStairsWithDynamic: " + climbStairsWithDynamic(n3)); + System.out.println("input: " + n3 + " climbStairsWithFibonacci: " + climbStairsWithFibonacci(n3)); + System.out.println("input: " + n3 + " climbStairsWithFibonacciFormula: " + climbStairsWithFibonacciFormula(n3)); } From bcb6eca37b0cbd9a92c78c6494e433f51521e2fe Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 11 Mar 2019 10:36:43 +0800 Subject: [PATCH 025/162] =?UTF-8?q?=E4=BA=8C=E5=88=86=E6=B3=95=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/LeetCode/src/Sqrt.java | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/code/LeetCode/src/Sqrt.java b/code/LeetCode/src/Sqrt.java index 7adb157a..462f1328 100644 --- a/code/LeetCode/src/Sqrt.java +++ b/code/LeetCode/src/Sqrt.java @@ -39,11 +39,36 @@ public static int mySqrt(int x) { return (int)y; } + public static int mySqrtWithMid(int x) { + if(x < 1) { + return 0; + } + int left = 0; + int right = x; + while(true) { + int mid = left + ((right - left) >> 1); + if (mid < 1) { + return 1; + } + if (mid > x / mid) { + right = mid; + } else { + if (mid + 1 > x/(mid + 1)) { + return mid; + } + + left = mid + 1; + } + } + } + public static void main(String[] args) { int input1 = 4; System.out.println("input: " +input1+ " sqrt: " + mySqrt(input1)); + System.out.println("input: " +input1+ " mySqrtWithMid: " + mySqrtWithMid(input1)); int input2 = 8; System.out.println("input: " +input2+ " sqrt: " + mySqrt(input2)); + System.out.println("input: " +input2+ " mySqrtWithMid: " + mySqrtWithMid(input2)); } } From 2b0d93b36c5c28a8ce4543c6d911d24f538788ff Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 11 Mar 2019 11:06:52 +0800 Subject: [PATCH 026/162] update condition --- code/LeetCode/src/Sqrt.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/LeetCode/src/Sqrt.java b/code/LeetCode/src/Sqrt.java index 462f1328..f30d45d5 100644 --- a/code/LeetCode/src/Sqrt.java +++ b/code/LeetCode/src/Sqrt.java @@ -27,7 +27,7 @@ Implement int sqrt(int x). */ public static int mySqrt(int x) { - if (x <= 0) { + if (x < 1) { return 0; } From 616e00d7061d8ec76108ef42f6a831878d2b6b29 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 12 Mar 2019 09:37:57 +0800 Subject: [PATCH 027/162] Reverse string --- code/LeetCode/src/popular/ReverseString.java | 26 ++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 code/LeetCode/src/popular/ReverseString.java diff --git a/code/LeetCode/src/popular/ReverseString.java b/code/LeetCode/src/popular/ReverseString.java new file mode 100644 index 00000000..d2c70f96 --- /dev/null +++ b/code/LeetCode/src/popular/ReverseString.java @@ -0,0 +1,26 @@ +package popular; + +import java.util.Arrays; + +public class ReverseString { + + public void reverseString(char[] s) { + int left = 0; + int right = s.length - 1; + while (left < right) { + char temp = s[left]; + s[left] = s[right]; + s[right] = temp; + left++; + right--; + } + } + + public static void main(String[] args) { + char[] s = {'h','e','l','l','o'}; + System.out.println("Input: " + Arrays.toString(s)); + new ReverseString().reverseString(s); + System.out.println("Output: " + Arrays.toString(s)); + + } +} From 8ce69b5f7a64e8d124096e5dda7924a2178f786a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BF=9D=E7=8A=B6?= Date: Tue, 12 Mar 2019 09:47:44 +0800 Subject: [PATCH 028/162] Update README.md --- code/LeetCode/src/popular/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/LeetCode/src/popular/README.md b/code/LeetCode/src/popular/README.md index 5fc33778..ef91ed94 100644 --- a/code/LeetCode/src/popular/README.md +++ b/code/LeetCode/src/popular/README.md @@ -6,7 +6,8 @@ | 32 | [Longest Valid Parentheses(最长有效的括号)][32] | stack | LongestValidParentheses | | 150 | [Evaluate Reverse Polish Notation(逆波兰表达式求值)][150]| stack | EvaluateReversePolishNotation | | 141 | [Linked List Cycle(环形链表)][141] | List | LinkedListCycle | -|239 | [Sliding Window Maximum(滑动窗口最大值)][239] | Deque, LinkedList| SlidingWindowMaximum | +| 239 | [Sliding Window Maximum(滑动窗口最大值)][239] | Deque, LinkedList| SlidingWindowMaximum | +| 344 | [Reverse String(反转字符串)][344] | String| ReverseString | @@ -16,3 +17,4 @@ [150]:https://blog.csdn.net/zgpeace/article/details/88014930 [141]:https://blog.csdn.net/zgpeace/article/details/87890399 [239]:https://blog.csdn.net/zgpeace/article/details/88372784 +[344]:https://blog.csdn.net/zgpeace/article/details/88414332 From 5a3da63e4708e8c9e8d7be7bdd9931434d5a2d82 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Wed, 13 Mar 2019 11:01:03 +0800 Subject: [PATCH 029/162] Reverse words in a string --- .../src/popular/ReverseWordsInAString.java | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 code/LeetCode/src/popular/ReverseWordsInAString.java diff --git a/code/LeetCode/src/popular/ReverseWordsInAString.java b/code/LeetCode/src/popular/ReverseWordsInAString.java new file mode 100644 index 00000000..08734b8e --- /dev/null +++ b/code/LeetCode/src/popular/ReverseWordsInAString.java @@ -0,0 +1,95 @@ +package popular; + +public class ReverseWordsInAString { + + public String reverseWords(String s) { + s = s.trim(); + if (s.length() == 0) { + return s; + } + String blankString = " "; + String[] wordsArray = s.split(blankString); + StringBuilder sb = new StringBuilder(); + + for (int i = wordsArray.length - 1; i >= 0; i--) { + String word = wordsArray[i]; + word = word.trim(); + if (word.length() > 0) { + sb.append(word).append(blankString); + } + } + + return sb.toString().trim(); + } + + public String reverseWordsWithLessSpace(String s) { + char[] chars = s.toCharArray(); + int len = chars.length; + subReverse(chars, 0, len - 1); + subReverseWords(chars, len); + + return subCleanBlankChar(chars, len); + } + + public String subCleanBlankChar(char[] chars, int len) { + int i = 0, j = 0; + char blankChar = ' '; + while (j < len) { + while (j < len && chars[j] == blankChar) { + j++; + } + while (j < len && chars[j] != blankChar) { + chars[i++] = chars[j++]; + } + while (j < len && chars[j] == blankChar) { + j++; + } + if (j < len) { + chars[i++] = blankChar; + } + } + + return new String(chars).substring(0, i); + } + + public void subReverseWords(char[] chars, int len) { + char blankChar = ' '; + int i = 0, j = 0; + while (j < len) { + while (j < len && chars[j] == blankChar) { + j++; + } + i = j; + while (j < len && chars[j] != blankChar) { + j++; + } + subReverse(chars, i, j - 1); + } + } + + public void subReverse(char[] chars, int startIndex, int endIndex) { + while (startIndex < endIndex) { + char temp = chars[startIndex]; + chars[startIndex] = chars[endIndex]; + chars[endIndex] = temp; + + startIndex++; + endIndex--; + } + } + + public static void main(String[] args) { + String input = "the sky is blue"; + ReverseWordsInAString obj = new ReverseWordsInAString(); + //System.out.println("Input: \"" + input + "\"\n" + "Output: \"" + obj.reverseWords(input) + "\"") ; + System.out.println("Input: \"" + input + "\"\n" + "Output: \"" + obj.reverseWordsWithLessSpace(input) + "\"") ; + + String input1 = " hello world! "; + //System.out.println("Input: \"" + input1 + "\"\n" + "Output: \"" + obj.reverseWords(input1) + "\"") ; + System.out.println("Input: \"" + input1 + "\"\n" + "Output: \"" + obj.reverseWordsWithLessSpace(input1) + "\"") ; + + String input2 = "a good example"; + //System.out.println("Input: \"" + input2 + "\"\n" + "Output: \"" + obj.reverseWords(input2) + "\"") ; + System.out.println("Input: \"" + input2 + "\"\n" + "Output: \"" + obj.reverseWordsWithLessSpace(input2) + "\"") ; + } +} From 722fefc8a99d263259fffe849c0d2d6903e7b7ee Mon Sep 17 00:00:00 2001 From: zgpeace Date: Wed, 13 Mar 2019 11:07:39 +0800 Subject: [PATCH 030/162] add comment --- .../LeetCode/src/popular/ReverseWordsInAString.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/code/LeetCode/src/popular/ReverseWordsInAString.java b/code/LeetCode/src/popular/ReverseWordsInAString.java index 08734b8e..09bab8ab 100644 --- a/code/LeetCode/src/popular/ReverseWordsInAString.java +++ b/code/LeetCode/src/popular/ReverseWordsInAString.java @@ -25,25 +25,32 @@ public String reverseWords(String s) { public String reverseWordsWithLessSpace(String s) { char[] chars = s.toCharArray(); int len = chars.length; + // step 1. reverse the whole string subReverse(chars, 0, len - 1); + // step 2. reverse each word subReverseWords(chars, len); - + // step 3. clean up spaces return subCleanBlankChar(chars, len); } + // trim leading, trailing and multiple spaces public String subCleanBlankChar(char[] chars, int len) { int i = 0, j = 0; char blankChar = ' '; while (j < len) { + // skip spaces while (j < len && chars[j] == blankChar) { j++; } + // keep non spaces while (j < len && chars[j] != blankChar) { chars[i++] = chars[j++]; } + // skip spaces while (j < len && chars[j] == blankChar) { j++; } + // keep only one space if (j < len) { chars[i++] = blankChar; } @@ -56,17 +63,21 @@ public void subReverseWords(char[] chars, int len) { char blankChar = ' '; int i = 0, j = 0; while (j < len) { + // skip spaces while (j < len && chars[j] == blankChar) { j++; } i = j; + // skip non spaces while (j < len && chars[j] != blankChar) { j++; } + // reverse the word subReverse(chars, i, j - 1); } } + // reverse a[] from a[i] to a[j] public void subReverse(char[] chars, int startIndex, int endIndex) { while (startIndex < endIndex) { char temp = chars[startIndex]; From ba53a90c30b9c525a90d91815c3a815def6699cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BF=9D=E7=8A=B6?= Date: Wed, 13 Mar 2019 11:10:34 +0800 Subject: [PATCH 031/162] Update README.md --- code/LeetCode/src/popular/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/LeetCode/src/popular/README.md b/code/LeetCode/src/popular/README.md index ef91ed94..88f1e39d 100644 --- a/code/LeetCode/src/popular/README.md +++ b/code/LeetCode/src/popular/README.md @@ -8,6 +8,7 @@ | 141 | [Linked List Cycle(环形链表)][141] | List | LinkedListCycle | | 239 | [Sliding Window Maximum(滑动窗口最大值)][239] | Deque, LinkedList| SlidingWindowMaximum | | 344 | [Reverse String(反转字符串)][344] | String| ReverseString | +| 151 | [Reverse Words in a String(翻转字符串里的单词)][151] | String| ReverseWordsInAString | @@ -18,3 +19,4 @@ [141]:https://blog.csdn.net/zgpeace/article/details/87890399 [239]:https://blog.csdn.net/zgpeace/article/details/88372784 [344]:https://blog.csdn.net/zgpeace/article/details/88414332 +[151]:https://blog.csdn.net/zgpeace/article/details/88528127 From 217c077a01eaeb4c7e2be203edb5b2272e420883 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 15 Mar 2019 10:28:40 +0800 Subject: [PATCH 032/162] delete useless test --- code/LeetCode/src/StringToIntegerAtoi.java | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/code/LeetCode/src/StringToIntegerAtoi.java b/code/LeetCode/src/StringToIntegerAtoi.java index 78eae6a3..3217ca2b 100644 --- a/code/LeetCode/src/StringToIntegerAtoi.java +++ b/code/LeetCode/src/StringToIntegerAtoi.java @@ -82,30 +82,9 @@ public int myAtoni(String str) { public static void main(String[] args) { StringToIntegerAtoi obj = new StringToIntegerAtoi(); -// String input = "42"; -// int output = obj.myAtoni(input); -// String input1 = " -42"; -// int output1 = obj.myAtoni(input1); -// String input2 = "4193 with words"; -// int output2 = obj.myAtoni(input2); -// String input3 = "words and 987"; -// int output3 = obj.myAtoni(input3); -// String input4 = "-91283472332"; -// int output4 = obj.myAtoni(input4); String input5 = "-3924x8fc"; int output5 = obj.myAtoni(input5); -// String input6 = "42"; -// int output6 = obj.myAtoni(input); -// String input7 = "42"; -// int output7 = obj.myAtoni(input); -// System.out.println("input: " + input + " output: " + output); -// System.out.println("input: " + input1 + " output: " + output1); -// System.out.println("input: " + input2 + " output: " + output2); -// System.out.println("input: " + input3 + " output: " + output3); -// System.out.println("input: " + input4 + " output: " + output4); System.out.println("input: " + input5 + " output: " + output5); -// System.out.println("input: " + input6 + " output: " + output6); -// System.out.println("input: " + input7 + " output: " + output7); } From c118b4788bc50239d19cd8aa98e4baf57ebb9e60 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 15 Mar 2019 16:32:02 +0800 Subject: [PATCH 033/162] Invert Binary Tree --- .../src/popular/InvertBinaryTree.java | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 code/LeetCode/src/popular/InvertBinaryTree.java diff --git a/code/LeetCode/src/popular/InvertBinaryTree.java b/code/LeetCode/src/popular/InvertBinaryTree.java new file mode 100644 index 00000000..bafef23e --- /dev/null +++ b/code/LeetCode/src/popular/InvertBinaryTree.java @@ -0,0 +1,96 @@ +package popular; + +import java.util.LinkedList; +import java.util.Queue; + +class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) {val = x; } + + @Override + public String toString() { + Queue queue = new LinkedList<>(); + queue.add(this); + StringBuilder sb = new StringBuilder(); + sb.append("["); + while (!queue.isEmpty()) { + TreeNode current = queue.poll(); + sb.append(current.val).append(", "); + if (current.left != null) queue.add(current.left); + if (current.right != null) queue.add(current.right); + } + sb.append("]"); + + return sb.toString(); + } +} + +public class InvertBinaryTree { + + public TreeNode invertTree(TreeNode root) { + if (root == null) { + return root; + } + + TreeNode left = invertTree(root.left); + TreeNode right = invertTree(root.right); + root.left = right; + root.right = left; + + return root; + } + + public TreeNode invertTreeWithBreadthSearchFirst(TreeNode root) { + if (root == null) { + return root; + } + + Queue queue = new LinkedList<>(); + queue.add(root); + while (!queue.isEmpty()) { + TreeNode current = queue.poll(); + TreeNode temp =current.left; + current.left = current.right; + current.right = temp; + + if (current.left != null) queue.add(current.left); + if (current.right != null) queue.add(current.right); + } + + return root; + } + + public static TreeNode initData() { + int[] data = {4, 2, 7, 1, 3, 6, 9}; + TreeNode root = new TreeNode(4); + Queue queue = new LinkedList<>(); + queue.add(root); + for (int i = 1; i < data.length; ) { + TreeNode currentRoot = queue.poll(); + TreeNode left = new TreeNode(data[i]); + currentRoot.left = left; + queue.add(currentRoot.left); + if (i + 1 < data.length) { + TreeNode right = new TreeNode(data[++i]); + currentRoot.right = right; + queue.add(currentRoot.right); + } + i++; + } + + return root; + } + + public static void main(String[] args) { + TreeNode root = initData(); + System.out.println("Input: " + root.toString()); + InvertBinaryTree obj = new InvertBinaryTree(); + obj.invertTree(root); + System.out.println("Output: " + root.toString()); + obj.invertTreeWithBreadthSearchFirst(root); + System.out.println("Output back: " + root.toString()); + } + +} From cbdb32cd613bb10b2be62ceded37f2ff6c341152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BF=9D=E7=8A=B6?= Date: Fri, 15 Mar 2019 16:45:38 +0800 Subject: [PATCH 034/162] Update README.md --- code/LeetCode/src/popular/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/LeetCode/src/popular/README.md b/code/LeetCode/src/popular/README.md index 88f1e39d..00f9b05c 100644 --- a/code/LeetCode/src/popular/README.md +++ b/code/LeetCode/src/popular/README.md @@ -9,6 +9,7 @@ | 239 | [Sliding Window Maximum(滑动窗口最大值)][239] | Deque, LinkedList| SlidingWindowMaximum | | 344 | [Reverse String(反转字符串)][344] | String| ReverseString | | 151 | [Reverse Words in a String(翻转字符串里的单词)][151] | String| ReverseWordsInAString | +| 226 | [Invert Binary Tree(翻转二叉树)][226] | String| InvertBinaryTree | @@ -20,3 +21,4 @@ [239]:https://blog.csdn.net/zgpeace/article/details/88372784 [344]:https://blog.csdn.net/zgpeace/article/details/88414332 [151]:https://blog.csdn.net/zgpeace/article/details/88528127 +[226]:https://blog.csdn.net/zgpeace/article/details/88578011 From 0349b34371635b687b642d67884379038564dd96 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Sat, 16 Mar 2019 22:27:51 +0800 Subject: [PATCH 035/162] Validate Binary search tree --- .../src/popular/ValidateBinarySearchTree.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 code/LeetCode/src/popular/ValidateBinarySearchTree.java diff --git a/code/LeetCode/src/popular/ValidateBinarySearchTree.java b/code/LeetCode/src/popular/ValidateBinarySearchTree.java new file mode 100644 index 00000000..56bdffe2 --- /dev/null +++ b/code/LeetCode/src/popular/ValidateBinarySearchTree.java @@ -0,0 +1,25 @@ +package popular; + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ + +public class ValidateBinarySearchTree { + public boolean isValidBST(TreeNode root) { + return subIsValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE); + } + + public boolean subIsValidBST(TreeNode root, long minValue, long maxValue) { + if (root == null) { + return true; + } + if (root.val >= maxValue || root.val <= minValue) return false; + return subIsValidBST(root.left, minValue, root.val) && subIsValidBST(root.right, root.val, maxValue); + } +} From 7f9b834b55c87f2cba509e4ea656520cec929e16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BF=9D=E7=8A=B6?= Date: Sat, 16 Mar 2019 22:40:51 +0800 Subject: [PATCH 036/162] Update README.md --- code/LeetCode/src/popular/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/LeetCode/src/popular/README.md b/code/LeetCode/src/popular/README.md index 00f9b05c..7a5c463a 100644 --- a/code/LeetCode/src/popular/README.md +++ b/code/LeetCode/src/popular/README.md @@ -9,7 +9,8 @@ | 239 | [Sliding Window Maximum(滑动窗口最大值)][239] | Deque, LinkedList| SlidingWindowMaximum | | 344 | [Reverse String(反转字符串)][344] | String| ReverseString | | 151 | [Reverse Words in a String(翻转字符串里的单词)][151] | String| ReverseWordsInAString | -| 226 | [Invert Binary Tree(翻转二叉树)][226] | String| InvertBinaryTree | +| 226 | [Invert Binary Tree(翻转二叉树)][226] | BinaryTree| InvertBinaryTree | +| 98 | [Validate Binary Search Tree(验证二叉查找树)][98] | BinaryTree| ValidateBinarySearchTree | @@ -22,3 +23,4 @@ [344]:https://blog.csdn.net/zgpeace/article/details/88414332 [151]:https://blog.csdn.net/zgpeace/article/details/88528127 [226]:https://blog.csdn.net/zgpeace/article/details/88578011 +[98]:https://blog.csdn.net/zgpeace/article/details/88607678 From db3e6d2ccd2dbfba8b65141ffaf8244adc9a0869 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 19 Mar 2019 11:23:19 +0800 Subject: [PATCH 037/162] number of islands --- .../LeetCode/src/popular/NumberOfIslands.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 code/LeetCode/src/popular/NumberOfIslands.java diff --git a/code/LeetCode/src/popular/NumberOfIslands.java b/code/LeetCode/src/popular/NumberOfIslands.java new file mode 100644 index 00000000..35f686a0 --- /dev/null +++ b/code/LeetCode/src/popular/NumberOfIslands.java @@ -0,0 +1,57 @@ +package popular; + +import java.util.Arrays; + +public class NumberOfIslands { + + public int numIslands(char[][] grid) { + if (grid == null || grid.length == 0 || grid[0].length == 0) { + return 0; + } + int count = 0; + int rowLen = grid.length; + int columnLen = grid[0].length; + boolean[][] visitArray = new boolean[rowLen][columnLen]; + for (int row = 0; row < rowLen; row++) { + for (int column = 0; column < columnLen; column++) { + if (grid[row][column] == '1' && visitArray[row][column] == false) { + markConnectIsland(grid, visitArray, row, column); + count++; + } + } + } + + return count; + } + + private void markConnectIsland(char[][] grid, boolean[][] visitArray, int row, int column) { + if (row < 0 || row >= grid.length) return; + if (column < 0 || column >= grid[0].length) return; + if (grid[row][column] != '1' || visitArray[row][column]) return; + + visitArray[row][column] = true; + + markConnectIsland(grid, visitArray, row + 1, column); + markConnectIsland(grid, visitArray, row - 1, column); + markConnectIsland(grid, visitArray, row, column + 1); + markConnectIsland(grid, visitArray, row, column - 1); + } + + public static void main(String[] args) { + //char[][] grid = { + // {'1', '1', '1', '1', '0'}, + // {'1', '1', '0', '1', '0'}, + // {'1', '1', '0', '0', '0'}, + // {'0', '0', '0', '0', '0'} + // }; + + char[][] grid = { + {'1', '1', '0', '0', '0'}, + {'1', '1', '0', '0', '0'}, + {'0', '0', '1', '0', '0'}, + {'0', '0', '0', '1', '1'} + }; + int count = new NumberOfIslands().numIslands(grid); + System.out.println("input: " + Arrays.toString(grid) + "\nOutput:" + count ); + } +} From 44a415d784cde641ba6cc9d3238ae2b3739b0d81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BF=9D=E7=8A=B6?= Date: Tue, 19 Mar 2019 11:39:11 +0800 Subject: [PATCH 038/162] Update README.md --- code/LeetCode/src/popular/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/LeetCode/src/popular/README.md b/code/LeetCode/src/popular/README.md index 7a5c463a..8d45bf6f 100644 --- a/code/LeetCode/src/popular/README.md +++ b/code/LeetCode/src/popular/README.md @@ -10,7 +10,8 @@ | 344 | [Reverse String(反转字符串)][344] | String| ReverseString | | 151 | [Reverse Words in a String(翻转字符串里的单词)][151] | String| ReverseWordsInAString | | 226 | [Invert Binary Tree(翻转二叉树)][226] | BinaryTree| InvertBinaryTree | -| 98 | [Validate Binary Search Tree(验证二叉查找树)][98] | BinaryTree| ValidateBinarySearchTree | +| 98 | [Validate Binary Search Tree(验证二叉查找树)][98] | BinaryTree| ValidateBinarySearchTree | +| 200 | [Number of Islands(岛屿的个数)][200] | Map| NumberOfIslands | @@ -24,3 +25,4 @@ [151]:https://blog.csdn.net/zgpeace/article/details/88528127 [226]:https://blog.csdn.net/zgpeace/article/details/88578011 [98]:https://blog.csdn.net/zgpeace/article/details/88607678 +[200]:https://blog.csdn.net/zgpeace/article/details/88658439 From 646ee2bf74d84ac5015985ade0e7eff392acc2bc Mon Sep 17 00:00:00 2001 From: zgpeace Date: Wed, 20 Mar 2019 16:59:12 +0800 Subject: [PATCH 039/162] valid sudoku --- code/LeetCode/src/popular/ValidSudoku.java | 60 ++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 code/LeetCode/src/popular/ValidSudoku.java diff --git a/code/LeetCode/src/popular/ValidSudoku.java b/code/LeetCode/src/popular/ValidSudoku.java new file mode 100644 index 00000000..bc92ad3c --- /dev/null +++ b/code/LeetCode/src/popular/ValidSudoku.java @@ -0,0 +1,60 @@ +package popular; + +import java.util.HashSet; +import java.util.Set; + +public class ValidSudoku { + + public boolean isValidSudoku(char[][] board) { + Set visitSet = new HashSet<>(81); + for (int row = 0; row < 9; row++) { + for (int column = 0; column < 9; column++) { + char data = board[row][column]; + if (data == '.') { + continue; + } + if (!visitSet.add(data + " row " + row)) { + System.out.println("duplicate board[" + row + "][" + column + "]" + " ;data: " + data+ " row " + row); + return false; + } + if (!visitSet.add(data + " column " + column)) { + System.out.println("duplicate board[" + row + "][" + column + "]" + " ;data: " + data+ " column " + column); + return false; + } + if (!visitSet.add(data + " cube " + row/3 + '-' + column/3) ) { + System.out.println("duplicate board[" + row + "][" + column + "]" + " ;data: " + data+ " cube " + row/3 + '-' + column/3); + return false; + } + } + } + + return true; + } + + public static void main(String[] args) { + char[][] board1 = { + {'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'}}; + char[][] board2 = { + {'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'}}; + ValidSudoku obj = new ValidSudoku(); + System.out.println("Output 1: " + obj.isValidSudoku(board1)); + System.out.println("Output 2: " + obj.isValidSudoku(board2)); + + } +} From e6748b9f3b6e16244a57f831a0053e232a3f2bd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BF=9D=E7=8A=B6?= Date: Wed, 20 Mar 2019 17:13:40 +0800 Subject: [PATCH 040/162] Update README.md --- code/LeetCode/src/popular/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/LeetCode/src/popular/README.md b/code/LeetCode/src/popular/README.md index 8d45bf6f..e5e4a3d4 100644 --- a/code/LeetCode/src/popular/README.md +++ b/code/LeetCode/src/popular/README.md @@ -11,7 +11,8 @@ | 151 | [Reverse Words in a String(翻转字符串里的单词)][151] | String| ReverseWordsInAString | | 226 | [Invert Binary Tree(翻转二叉树)][226] | BinaryTree| InvertBinaryTree | | 98 | [Validate Binary Search Tree(验证二叉查找树)][98] | BinaryTree| ValidateBinarySearchTree | -| 200 | [Number of Islands(岛屿的个数)][200] | Map| NumberOfIslands | +| 200 | [Number of Islands(岛屿的个数)][200] | Graph| NumberOfIslands | +| 36 | [Valid Sudoku(有效的数独)][36] | Grap| ValidSudoku | @@ -26,3 +27,4 @@ [226]:https://blog.csdn.net/zgpeace/article/details/88578011 [98]:https://blog.csdn.net/zgpeace/article/details/88607678 [200]:https://blog.csdn.net/zgpeace/article/details/88658439 +[36]:https://blog.csdn.net/zgpeace/article/details/88693835 From e31e6b29b4158089a013f8f3c95e3095c39b908a Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 22 Mar 2019 15:38:16 +0800 Subject: [PATCH 041/162] regular expression matching --- .../popular/RegularExpressionMatching.java | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 code/LeetCode/src/popular/RegularExpressionMatching.java diff --git a/code/LeetCode/src/popular/RegularExpressionMatching.java b/code/LeetCode/src/popular/RegularExpressionMatching.java new file mode 100644 index 00000000..f776290b --- /dev/null +++ b/code/LeetCode/src/popular/RegularExpressionMatching.java @@ -0,0 +1,84 @@ +package popular; + +enum Result { + TRUE, FALSE; +} + +public class RegularExpressionMatching { + + public boolean isMatch(String s, String p) { + // p is empty + if (p.isEmpty()) { + return s.isEmpty(); + } + // first char firstCharMatch : 1. string first char is == , 2. or p first string == '.' + boolean firstCharMatch = s.length() >= 1 && (s.charAt(0) == p.charAt(0) || p.charAt(0) == '.'); + // p second char == '*', 1. then isMatch(s, p.substring(2)), 2. firstCharMatch && isMatch(s.substring(1), p) + if (p.length() >= 2 && p.charAt(1) == '*') { + return isMatch(s, p.substring(2)) || (firstCharMatch && isMatch(s.substring(1), p)); + } else { + // p second char != '*', then firstCharMatch && isMatch(s.substring(1), p.substring(1)) + return firstCharMatch && isMatch(s.substring(1), p.substring(1)); + } + } + + Result[][] memo; + + public boolean isMatchWithMemory(String s, String p) { + if (p.isEmpty()) { + return s.isEmpty(); + } + + memo = new Result[s.length() + 1][p.length() + 1]; + return subMatch(0, 0, s, p); + } + + public boolean subMatch(int textIndex, int patternIndex, String text, String pattern) { + if (memo[textIndex][patternIndex] != null) { + return memo[textIndex][patternIndex] == Result.TRUE; + } + boolean result = false; + if (patternIndex == pattern.length()) { + result = textIndex == text.length(); + } else { + boolean firstCharMatch = text.length() > textIndex && + (text.charAt(textIndex) == pattern.charAt(patternIndex) || pattern.charAt(patternIndex) == '.'); + if (patternIndex + 1 < pattern.length() && pattern.charAt(patternIndex + 1) == '*') { + result = subMatch(textIndex, patternIndex + 2, text, pattern) || + (firstCharMatch && subMatch(textIndex + 1, patternIndex, text, pattern)); + } else { + result = firstCharMatch && subMatch(textIndex + 1, patternIndex + 1, text, pattern); + } + } + + memo[textIndex][patternIndex] = result ? Result.TRUE : Result.FALSE; + + return result; + } + + + public static void main(String[] args) { + RegularExpressionMatching obj = new RegularExpressionMatching(); + String s = "aa"; + String p = "a"; + System.out.println("Output: " + obj.isMatch(s, p)); + System.out.println("isMatchWithMemory Output: " + obj.isMatchWithMemory(s, p)); + String s1 = "aa"; + String p1 = "a*"; + System.out.println("Output1: " + obj.isMatch(s1, p1)); + System.out.println("isMatchWithMemory Output1: " + obj.isMatchWithMemory(s1, p1)); + String s2 = "ab"; + String p2 = ".*"; + System.out.println("Output2: " + obj.isMatch(s2, p2)); + System.out.println("isMatchWithMemory Output2: " + obj.isMatchWithMemory(s2, p2)); + String s3 = "aab"; + String p3 = "c*a*b"; + System.out.println("Output3: " + obj.isMatch(s3, p3)); + System.out.println("isMatchWithMemory Output3: " + obj.isMatchWithMemory(s3, p3)); + String s4 = "mississippi"; + String p4 = "mis*is*p*."; + System.out.println("Output4: " + obj.isMatch(s4, p4)); + System.out.println("isMatchWithMemory Output4: " + obj.isMatchWithMemory(s4, p4)); + + } +} From f1ce86143796472fc318829618ace4b7d1b4521b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BF=9D=E7=8A=B6?= Date: Fri, 22 Mar 2019 16:20:10 +0800 Subject: [PATCH 042/162] Update README.md --- code/LeetCode/src/popular/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/LeetCode/src/popular/README.md b/code/LeetCode/src/popular/README.md index e5e4a3d4..7478a60d 100644 --- a/code/LeetCode/src/popular/README.md +++ b/code/LeetCode/src/popular/README.md @@ -13,6 +13,7 @@ | 98 | [Validate Binary Search Tree(验证二叉查找树)][98] | BinaryTree| ValidateBinarySearchTree | | 200 | [Number of Islands(岛屿的个数)][200] | Graph| NumberOfIslands | | 36 | [Valid Sudoku(有效的数独)][36] | Grap| ValidSudoku | +| 10 | [Regular Expression Matching(正则表达式匹配)][10] | Recursive | RegularExpressionMatching | @@ -28,3 +29,4 @@ [98]:https://blog.csdn.net/zgpeace/article/details/88607678 [200]:https://blog.csdn.net/zgpeace/article/details/88658439 [36]:https://blog.csdn.net/zgpeace/article/details/88693835 +[10]:https://blog.csdn.net/zgpeace/article/details/88742935 From 2d6a782cc92b1601026f1010c92a6b7af75e3464 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 26 Mar 2019 11:41:11 +0800 Subject: [PATCH 043/162] minimum path sum --- code/LeetCode/src/popular/MinimumPathSum.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 code/LeetCode/src/popular/MinimumPathSum.java diff --git a/code/LeetCode/src/popular/MinimumPathSum.java b/code/LeetCode/src/popular/MinimumPathSum.java new file mode 100644 index 00000000..03fa4fc7 --- /dev/null +++ b/code/LeetCode/src/popular/MinimumPathSum.java @@ -0,0 +1,37 @@ +package popular; + +public class MinimumPathSum { + + public int minPathSum(int[][] grid) { + int rowLen = grid.length; + int columnLen = grid[0].length; + int[][] sumGrid = new int[rowLen][columnLen]; + + for (int row = 0; row < rowLen; row++) { + for (int column = 0; column < columnLen; column++) { + if (row == 0 && column == 0) { + // init first sum + sumGrid[0][0] = grid[0][0]; + } else if (row == 0 && column != 0) { + sumGrid[row][column] = grid[row][column] + sumGrid[row][column - 1]; + } else if (column == 0 && row != 0) { + sumGrid[row][column] = grid[row][column] + sumGrid[row - 1][column]; + } else { + sumGrid[row][column] = grid[row][column] + Math.min(sumGrid[row][column - 1], sumGrid[row - 1][column]); + } + } + } + + return sumGrid[rowLen - 1][columnLen - 1]; + } + + public static void main(String[] args) { + int[][] grid = { + {1,3,1}, + {1,5,1}, + {4,2,1} + }; + MinimumPathSum obj = new MinimumPathSum(); + System.out.println("Output: " + obj.minPathSum(grid)); + } +} From 9580f473f1eb748ef6891372097f417089e4282c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BF=9D=E7=8A=B6?= Date: Tue, 26 Mar 2019 11:56:37 +0800 Subject: [PATCH 044/162] Update README.md --- code/LeetCode/src/popular/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/LeetCode/src/popular/README.md b/code/LeetCode/src/popular/README.md index 7478a60d..d9218e48 100644 --- a/code/LeetCode/src/popular/README.md +++ b/code/LeetCode/src/popular/README.md @@ -13,7 +13,8 @@ | 98 | [Validate Binary Search Tree(验证二叉查找树)][98] | BinaryTree| ValidateBinarySearchTree | | 200 | [Number of Islands(岛屿的个数)][200] | Graph| NumberOfIslands | | 36 | [Valid Sudoku(有效的数独)][36] | Grap| ValidSudoku | -| 10 | [Regular Expression Matching(正则表达式匹配)][10] | Recursive | RegularExpressionMatching | +| 10 | [Regular Expression Matching(正则表达式匹配)][10] | Recursive, dynamic | RegularExpressionMatching | +| 64 | [Minimum Path Sum(最小路径和)][64] | Recursive, dynamic | MinimumPathSum | @@ -30,3 +31,4 @@ [200]:https://blog.csdn.net/zgpeace/article/details/88658439 [36]:https://blog.csdn.net/zgpeace/article/details/88693835 [10]:https://blog.csdn.net/zgpeace/article/details/88742935 +[64]:https://blog.csdn.net/zgpeace/article/details/88816726 From a5b4b139d59228aa05e036c98e4ae20fd595933f Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 26 Mar 2019 17:11:45 +0800 Subject: [PATCH 045/162] refactor common file ListNode --- code/LeetCode/src/AddTwoNumbers.java | 2 ++ code/LeetCode/src/ListNode.java | 7 ---- code/LeetCode/src/MergeKSortedLists.java | 2 ++ .../src/RemoveNthNodeFromEndOfList.java | 2 +- code/LeetCode/src/ReverseNodesInKGroup.java | 2 ++ code/LeetCode/src/SwapNodesInPairs.java | 2 ++ code/LeetCode/src/common/ListNode.java | 33 +++++++++++++++++++ .../LeetCode/src/popular/LinkedListCycle.java | 1 + 8 files changed, 43 insertions(+), 8 deletions(-) delete mode 100644 code/LeetCode/src/ListNode.java create mode 100644 code/LeetCode/src/common/ListNode.java diff --git a/code/LeetCode/src/AddTwoNumbers.java b/code/LeetCode/src/AddTwoNumbers.java index 3177ecde..e155f0f0 100644 --- a/code/LeetCode/src/AddTwoNumbers.java +++ b/code/LeetCode/src/AddTwoNumbers.java @@ -1,3 +1,5 @@ +import common.ListNode; + public class AddTwoNumbers { /* Add Two Numbers diff --git a/code/LeetCode/src/ListNode.java b/code/LeetCode/src/ListNode.java deleted file mode 100644 index a6eb17f1..00000000 --- a/code/LeetCode/src/ListNode.java +++ /dev/null @@ -1,7 +0,0 @@ -public class ListNode { - int val; - ListNode next; - ListNode(int x) { - val = x; - } -} diff --git a/code/LeetCode/src/MergeKSortedLists.java b/code/LeetCode/src/MergeKSortedLists.java index 56b74bcd..aa4f8a94 100644 --- a/code/LeetCode/src/MergeKSortedLists.java +++ b/code/LeetCode/src/MergeKSortedLists.java @@ -1,3 +1,5 @@ +import common.ListNode; + import java.util.Comparator; import java.util.PriorityQueue; diff --git a/code/LeetCode/src/RemoveNthNodeFromEndOfList.java b/code/LeetCode/src/RemoveNthNodeFromEndOfList.java index f7c5757c..799a126c 100644 --- a/code/LeetCode/src/RemoveNthNodeFromEndOfList.java +++ b/code/LeetCode/src/RemoveNthNodeFromEndOfList.java @@ -1,4 +1,4 @@ -import java.lang.reflect.Method; +import common.ListNode; public class RemoveNthNodeFromEndOfList { /* diff --git a/code/LeetCode/src/ReverseNodesInKGroup.java b/code/LeetCode/src/ReverseNodesInKGroup.java index 87054561..b8714359 100644 --- a/code/LeetCode/src/ReverseNodesInKGroup.java +++ b/code/LeetCode/src/ReverseNodesInKGroup.java @@ -1,3 +1,5 @@ +import common.ListNode; + public class ReverseNodesInKGroup { /* Reverse Nodes in k-Group diff --git a/code/LeetCode/src/SwapNodesInPairs.java b/code/LeetCode/src/SwapNodesInPairs.java index efc68cba..30f9afd3 100644 --- a/code/LeetCode/src/SwapNodesInPairs.java +++ b/code/LeetCode/src/SwapNodesInPairs.java @@ -1,3 +1,5 @@ +import common.ListNode; + public class SwapNodesInPairs { /* Swap Nodes in Pairs diff --git a/code/LeetCode/src/common/ListNode.java b/code/LeetCode/src/common/ListNode.java new file mode 100644 index 00000000..7b0a7003 --- /dev/null +++ b/code/LeetCode/src/common/ListNode.java @@ -0,0 +1,33 @@ +package common; + +public class ListNode { + public int val; + public ListNode next; + public ListNode(int x) { + val = x; + } + + static public ListNode listNodeWithIntArray(int[] input) { + ListNode head = new ListNode(0); + ListNode node = head; + + for (int i: input) { + ListNode newNode = new ListNode(i); + node.next = newNode; + node = node.next; + } + + return head.next; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + ListNode node = this; + while (node != null) { + sb.append(node.val).append("-->"); + node = node.next; + } + return sb.append("Null").toString(); + } +} diff --git a/code/LeetCode/src/popular/LinkedListCycle.java b/code/LeetCode/src/popular/LinkedListCycle.java index e3aaee12..5c5b91a1 100644 --- a/code/LeetCode/src/popular/LinkedListCycle.java +++ b/code/LeetCode/src/popular/LinkedListCycle.java @@ -1,5 +1,6 @@ package popular; + import java.util.HashSet; import java.util.Set; From c9366370fbc7ada0c7e69a6f7132894c9e272990 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 26 Mar 2019 17:12:48 +0800 Subject: [PATCH 046/162] Reverse Linked List --- .../src/popular/ReverseLinkedList.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 code/LeetCode/src/popular/ReverseLinkedList.java diff --git a/code/LeetCode/src/popular/ReverseLinkedList.java b/code/LeetCode/src/popular/ReverseLinkedList.java new file mode 100644 index 00000000..f0b7d77a --- /dev/null +++ b/code/LeetCode/src/popular/ReverseLinkedList.java @@ -0,0 +1,55 @@ +package popular; + +import common.ListNode; + + +public class ReverseLinkedList { + public ListNode reverseList(ListNode head) { + ListNode current = null; + ListNode previous = null; + while (head != null) { + previous = current; + current = new ListNode(head.val); + current.next = previous; + head = head.next; + } + + return current; + } + + public ListNode reverseListWithoutChangeHead(ListNode head) { + ListNode current = head; + ListNode previous = null; + while (current != null) { + ListNode nextNode = current.next; + current.next = previous; + previous = current; + current = nextNode; + } + + return previous; + } + + public ListNode reverseListWithRecursive(ListNode head) { + while (head == null || head.next == null) { + return head; + } + ListNode p = reverseListWithRecursive(head.next); + head.next.next = head; + head.next = null; + + return p; + } + + public static void main(String[] args) { + int[] input = {1, 2, 3, 4, 5}; + ListNode head = ListNode.listNodeWithIntArray(input); + System.out.println("Input: " + head.toString()); + ReverseLinkedList obj = new ReverseLinkedList(); + //ListNode result = obj.reverseList(head); + //ListNode result = obj.reverseListWithoutChangeHead(head); + ListNode result = obj.reverseListWithRecursive(head); + System.out.println("Output: " + result.toString()); + } + +} From 31326f8e944bf44a96a44a98e28b4abe175ed234 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 26 Mar 2019 17:55:11 +0800 Subject: [PATCH 047/162] reuse the same memory --- code/LeetCode/src/popular/ReverseLinkedList.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/LeetCode/src/popular/ReverseLinkedList.java b/code/LeetCode/src/popular/ReverseLinkedList.java index f0b7d77a..db87eae2 100644 --- a/code/LeetCode/src/popular/ReverseLinkedList.java +++ b/code/LeetCode/src/popular/ReverseLinkedList.java @@ -20,8 +20,9 @@ public ListNode reverseList(ListNode head) { public ListNode reverseListWithoutChangeHead(ListNode head) { ListNode current = head; ListNode previous = null; + ListNode nextNode; while (current != null) { - ListNode nextNode = current.next; + nextNode = current.next; current.next = previous; previous = current; current = nextNode; From 3186a87fe1a2f8582faf24c83c3a08a6b5dd9b40 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Wed, 27 Mar 2019 18:23:08 +0800 Subject: [PATCH 048/162] HeapSort, InsertionSort, MergeSort, QuickSort --- .../src/popular/Sorting/HeapSort.java | 53 +++++++++++ .../src/popular/Sorting/InsertionSort.java | 26 ++++++ .../src/popular/Sorting/MergeSort.java | 58 ++++++++++++ .../src/popular/Sorting/QuickSort.java | 88 +++++++++++++++++++ 4 files changed, 225 insertions(+) create mode 100644 code/LeetCode/src/popular/Sorting/HeapSort.java create mode 100644 code/LeetCode/src/popular/Sorting/InsertionSort.java create mode 100644 code/LeetCode/src/popular/Sorting/MergeSort.java create mode 100644 code/LeetCode/src/popular/Sorting/QuickSort.java diff --git a/code/LeetCode/src/popular/Sorting/HeapSort.java b/code/LeetCode/src/popular/Sorting/HeapSort.java new file mode 100644 index 00000000..89b63e54 --- /dev/null +++ b/code/LeetCode/src/popular/Sorting/HeapSort.java @@ -0,0 +1,53 @@ +package popular.Sorting; + +import java.util.Arrays; + +public class HeapSort { + + public static void heapSort(int[] data) { + // build top big heap + for (int i = data.length/2 -1; i >= 0; i--) { + // build heap + buildHeap(data, i, data.length); + } + + // change seat between the first and the last, length-- + for (int k = data.length - 1; k >=0; k--) { + // change seat between first and last one + swap(data, 0, k); + // build heap + buildHeap(data, 0, k); + } + } + + public static void buildHeap(int[] data, int nodeIndex, int length) { + int temp = data[nodeIndex]; + for (int k = nodeIndex * 2 + 1; k < length; k = k * 2 + 1) { + if (k + 1 < length && data[k] < data[k + 1]) { + k = k + 1; + } + if (data[k] > temp) { + data[nodeIndex] = data[k]; + nodeIndex = k; + } else { + break; + } + } + + data[nodeIndex] = temp; + } + + + public static void swap(int[] data, int i, int j) { + int temp = data[i]; + data[i] = data[j]; + data[j] = temp; + } + + public static void main(String[] args) { + int[] data = new int[]{4, 6, 5, 3, 7, 1, 2}; + System.out.println(Arrays.toString(data)); + heapSort(data); + System.out.println(Arrays.toString(data)); + } +} diff --git a/code/LeetCode/src/popular/Sorting/InsertionSort.java b/code/LeetCode/src/popular/Sorting/InsertionSort.java new file mode 100644 index 00000000..4f3af785 --- /dev/null +++ b/code/LeetCode/src/popular/Sorting/InsertionSort.java @@ -0,0 +1,26 @@ +package popular.Sorting; + +import java.util.Arrays; + +public class InsertionSort { + + public void insertSort(int[] data) { + for (int i = 1; i < data.length; i++) { + int currentNumber = data[i]; + int j = i - 1; + while (j >= 0 && data[j] > currentNumber) { + data[j + 1] = data[j]; + j--; + } + data[j+1] = currentNumber; + } + } + + public static void main(String[] args) { + int[] data = new int[]{4, 6, 5, 3, 7, 1, 2}; + System.out.println(Arrays.toString(data)); + InsertionSort obj = new InsertionSort(); + obj.insertSort(data); + System.out.println(Arrays.toString(data)); + } +} diff --git a/code/LeetCode/src/popular/Sorting/MergeSort.java b/code/LeetCode/src/popular/Sorting/MergeSort.java new file mode 100644 index 00000000..cc8ad79d --- /dev/null +++ b/code/LeetCode/src/popular/Sorting/MergeSort.java @@ -0,0 +1,58 @@ +package popular.Sorting; + +import java.util.Arrays; + +public class MergeSort { + + public void mergeSort(int[] data) { + int[] temp = new int[data.length]; + subMergeSort(data, 0, data.length - 1, temp); + } + + + public void subMergeSort(int[] data, int left, int right, int[] temp) { + if (left < right) { + int mid = left + (right - left) / 2; + subMergeSort(data, left, mid, temp); + subMergeSort(data, mid + 1, right, temp); + merge(data, left, mid, right, temp); + } + } + + public void merge(int[] data, int left, int mid, int right, int[] temp) { + int i = left; + int k = mid + 1; + int t = 0; + while (i <= mid && k <= right) { + if (data[i] < data[k]) { + temp[t++] = data[i++]; + } else { + temp[t++] = data[k++]; + } + } + + while (i <= mid) { + temp[t++] = data[i++]; + } + + while (k <= right) { + temp[t++] = data[k++]; + } + + t = 0; + while (left <= right) { + data[left++] = temp[t++]; + } + + } + + public static void main(String[] args) { + int[] data = new int[]{4, 6, 5, 3, 7, 1, 2}; + System.out.println(Arrays.toString(data)); + MergeSort obj = new MergeSort(); + obj.mergeSort(data); + System.out.println(Arrays.toString(data)); + } + + +} diff --git a/code/LeetCode/src/popular/Sorting/QuickSort.java b/code/LeetCode/src/popular/Sorting/QuickSort.java new file mode 100644 index 00000000..fd18015f --- /dev/null +++ b/code/LeetCode/src/popular/Sorting/QuickSort.java @@ -0,0 +1,88 @@ +package popular.Sorting; + +import java.util.Arrays; + +public class QuickSort { + + public static void quickSort(int[] data) { + // divide to left, right index + subQuickSort(data, 0, data.length - 1); + } + + public static void subQuickSort(int[] data, int leftIndex, int rightIndex) { + if (leftIndex >= rightIndex) { + return; + } + + // pivot data: mid of the three number, and swap to right -1 + buildPivotCloseToRight(data, leftIndex, rightIndex); + + int i = leftIndex; + int k = rightIndex - 1; + int pivot = data[k]; + // two point from two side, ++left, --right + while (true) { + + // while ++left > pivot + while ((i+1) < rightIndex && data[++i] < pivot) { + + } + + // while --right < pivot + while ((k - 1) > leftIndex && data[--k] > pivot) { + + } + + // left < right, then swap + if (i < k) { + swap(data, i, k); + } else { + break; + } + } + + // if left < pivotIndex ,swap + if (i < rightIndex - 1) { + swap(data, i, rightIndex - 1); + } + + // divide two sub quick sort + subQuickSort(data, leftIndex, i); + subQuickSort(data, i + 1, rightIndex); + + } + + public static void buildPivotCloseToRight(int[] data, int leftIndex, int rightIndex) { + int midIndex = leftIndex + (rightIndex - leftIndex) / 2; + // swap small in left, between left, mid + if (data[leftIndex] > data[midIndex]) { + swap(data, leftIndex, midIndex); + } + + // swap small in left, between left, right + if (data[leftIndex] > data[rightIndex]) { + swap(data, leftIndex, rightIndex); + } + + // swap big in right, between mid, right + if (data[midIndex] > data[rightIndex]) { + swap(data, midIndex, rightIndex); + } + + // swap pivot int right -1 + swap(data, midIndex, rightIndex - 1); + } + + public static void swap(int[] data, int i, int k) { + int temp = data[i]; + data[i] = data[k]; + data[k] = temp; + } + + public static void main(String[] args) { + int[] data = new int[]{4, 6, 5, 3, 7, 1, 2}; + System.out.println(Arrays.toString(data)); + quickSort(data); + System.out.println(Arrays.toString(data)); + } +} From e70bdee18327d96b3c3675c8de75e9920030f321 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Thu, 28 Mar 2019 18:28:59 +0800 Subject: [PATCH 049/162] eight queen --- code/LeetCode/src/popular/EightQueen.java | 66 +++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 code/LeetCode/src/popular/EightQueen.java diff --git a/code/LeetCode/src/popular/EightQueen.java b/code/LeetCode/src/popular/EightQueen.java new file mode 100644 index 00000000..e2f544c7 --- /dev/null +++ b/code/LeetCode/src/popular/EightQueen.java @@ -0,0 +1,66 @@ +package popular; + +public class EightQueen { + + static int[] result = new int[8]; + static int count = 1; + public static void eightQueen(int row) { + // row == 8, print & return + if (row == 8) { + //print + printQueens(result); + System.out.println("------"+ count++ +"------"); + return; + } + + // for each column + for (int column = 0; column < 8; column++) { + if (isOK(row, column)) { + result[row] = column; + eightQueen(row + 1); + } + } + + } + + public static boolean isOK(int row, int column) { + int leftUp = column - 1; + int rightUp = column + 1; + while (--row >= 0) { + // vertical direction duplicate + if (result[row] == column) { + return false; + } + // left diagonal duplicate + if (leftUp >= 0 && result[row] == leftUp) { + return false; + } + // right diagonal duplicate + if (rightUp < 8 && result[row] == rightUp) { + return false; + } + leftUp--; + rightUp++; + } + + return true; + } + + public static void printQueens(int[] result) { + for (int row = 0; row < 8; row++) { + for (int column = 0; column < 8; column++) { + if (result[row] == column) { + System.out.print("Q "); + } else { + System.out.print("* "); + } + } + System.out.println(); + } + System.out.println(); + } + + public static void main(String[] args) { + eightQueen(0); + } +} From 14b38364007d9c0a51b93f287d020525e87e5109 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 1 Apr 2019 11:59:12 +0800 Subject: [PATCH 050/162] JumpGame --- code/LeetCode/src/popular/CoinChange.java | 24 ++++++ code/LeetCode/src/popular/EightQueen.java | 12 ++- code/LeetCode/src/popular/JumpGame.java | 70 ++++++++++++++++ .../src/popular/LongestValidParentheses.java | 1 + code/LeetCode/src/popular/NQueens.java | 82 +++++++++++++++++++ 5 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 code/LeetCode/src/popular/CoinChange.java create mode 100644 code/LeetCode/src/popular/JumpGame.java create mode 100644 code/LeetCode/src/popular/NQueens.java diff --git a/code/LeetCode/src/popular/CoinChange.java b/code/LeetCode/src/popular/CoinChange.java new file mode 100644 index 00000000..983e0cb1 --- /dev/null +++ b/code/LeetCode/src/popular/CoinChange.java @@ -0,0 +1,24 @@ +package popular; + +import java.util.Arrays; + +public class CoinChange { + + public static int coinChange(int[] coins, int amount) { + if (amount == 0) { + return 0; + } + int count = Integer.MAX_VALUE; + + if (count == Integer.MAX_VALUE) { + count = -1; + } + return count; + } + + public static void main(String[] args) { + int[] coins = new int[]{186, 419, 83, 408}; + int amount = 6249; + System.out.println("Output: " + coinChange(coins, amount)); + } +} diff --git a/code/LeetCode/src/popular/EightQueen.java b/code/LeetCode/src/popular/EightQueen.java index e2f544c7..80a407d9 100644 --- a/code/LeetCode/src/popular/EightQueen.java +++ b/code/LeetCode/src/popular/EightQueen.java @@ -1,9 +1,13 @@ package popular; +import java.util.Arrays; +import java.util.List; + public class EightQueen { static int[] result = new int[8]; static int count = 1; + static int step = 1; public static void eightQueen(int row) { // row == 8, print & return if (row == 8) { @@ -15,8 +19,10 @@ public static void eightQueen(int row) { // for each column for (int column = 0; column < 8; column++) { + if (isOK(row, column)) { result[row] = column; + System.out.println("result[" + row + "] = " + column); eightQueen(row + 1); } } @@ -26,7 +32,9 @@ public static void eightQueen(int row) { public static boolean isOK(int row, int column) { int leftUp = column - 1; int rightUp = column + 1; + while (--row >= 0) { + System.out.println("---step---" + step++); // vertical direction duplicate if (result[row] == column) { return false; @@ -42,6 +50,7 @@ public static boolean isOK(int row, int column) { leftUp--; rightUp++; } + System.out.println("---step---" + step++); return true; } @@ -61,6 +70,7 @@ public static void printQueens(int[] result) { } public static void main(String[] args) { - eightQueen(0); + //eightQueen(0); + int[] arr = {1, 2, 3, 5}; } } diff --git a/code/LeetCode/src/popular/JumpGame.java b/code/LeetCode/src/popular/JumpGame.java new file mode 100644 index 00000000..ad337fce --- /dev/null +++ b/code/LeetCode/src/popular/JumpGame.java @@ -0,0 +1,70 @@ +package popular; + +import java.util.Arrays; + +public class JumpGame { + + public static boolean canJump(int[] nums) { + // result memory, 1 is true; -1 is false; + int[] memo = new int[nums.length + 1]; + return helper(0, nums, memo); + } + + public static boolean helper(int position, int[] nums, int[] memo) { + if (memo[position] == 1 || position == nums.length - 1) { + return true; + } else if (memo[position] == -1) { + return false; + } + int maxPosition = Math.min(position + nums[position], nums.length - 1) ; + for(int i = maxPosition; i > position; i--) { + memo[i] = helper(i, nums, memo) ? 1 : -1; + if(memo[i] == 1) { + return true; + } + } + + return false; + } + + public static boolean canJumpWithBottomUp(int[] nums) { + // result memory, 1 is true; -1 is false; + int[] memo = new int[nums.length]; + // check if the length == 1 + memo[nums.length - 1] = 1; + + for(int i = nums.length -2; i >= 0; i--) { + int maxPosition = Math.min(i + nums[i], nums.length - 1); + for(int k = i + 1; k <= maxPosition; k++) { + if (k == nums.length - 1 || memo[k] == 1) { + memo[i] = 1; + break; + } + } + } + + return memo[0] == 1; + } + + public static boolean canJumpWithGreedy(int[] nums) { + int lastIndex = nums.length - 1; + for (int i = lastIndex - 1; i >=0 ; i--) { + if (i + nums[i] >= lastIndex) { + lastIndex = i; + } + } + + return lastIndex == 0; + } + + public static void main(String[] args) { + int[] input = {2,3,1,1,4}; + int[] input1 = {3,2,1,0,4}; + //System.out.println("intput: " + Arrays.toString(input) + '\n' + "output: " + canJump(input)); + //System.out.println("input1: " + Arrays.toString(input1) + '\n' + "output: " + canJump(input1)); + //System.out.println("intput: " + Arrays.toString(input) + '\n' + "output: " + canJumpWithBottomUp(input)); + //System.out.println("input1: " + Arrays.toString(input1) + '\n' + "output: " + canJumpWithBottomUp(input1)); + System.out.println("intput: " + Arrays.toString(input) + '\n' + "output: " + canJumpWithGreedy(input)); + System.out.println("input1: " + Arrays.toString(input1) + '\n' + "output: " + canJumpWithGreedy(input1)); + } +} diff --git a/code/LeetCode/src/popular/LongestValidParentheses.java b/code/LeetCode/src/popular/LongestValidParentheses.java index 48bde804..e780ce2f 100644 --- a/code/LeetCode/src/popular/LongestValidParentheses.java +++ b/code/LeetCode/src/popular/LongestValidParentheses.java @@ -1,5 +1,6 @@ package popular; +import java.util.Arrays; import java.util.Stack; public class LongestValidParentheses { diff --git a/code/LeetCode/src/popular/NQueens.java b/code/LeetCode/src/popular/NQueens.java new file mode 100644 index 00000000..150bd7b1 --- /dev/null +++ b/code/LeetCode/src/popular/NQueens.java @@ -0,0 +1,82 @@ +package popular; + +import java.util.ArrayList; +import java.util.List; + +public class NQueens { + + static int[] rowColumnArray; + + public static List> solveNQueens(int n) { + List> resultList = new ArrayList>(); + rowColumnArray = new int[n + 1]; + // from 0 to calculate + recursiveQueeen(0, n, resultList); + + return resultList; + } + + public static void recursiveQueeen(int row, int length, List> resultList) { + if (row == length) { + // print + resultList.add(addValidList(length)); + + return; + } + + for (int column = 0; column < length; column++) { + if (isOK(row, column, length)) { + rowColumnArray[row] = column; + recursiveQueeen(row + 1, length, resultList); + } + } + } + + public static boolean isOK(int row, int column, int length) { + int leftUp = column - 1; + int rightUp = column + 1; + while (--row >= 0) { + if (rowColumnArray[row] == column) { + return false; + } + if (leftUp >= 0 && rowColumnArray[row] == leftUp) { + return false; + } + if (rightUp < length && rowColumnArray[row] == rightUp) { + return false; + } + + leftUp--; + rightUp++; + } + + return true; + } + + public static List addValidList(int length) { + List list = new ArrayList<>(); + StringBuilder sb; + System.out.println(); + for (int row = 0; row < length; row++) { + sb = new StringBuilder(); + for (int column = 0; column < length; column++) { + if (rowColumnArray[row] == column) { + sb.append('Q'); + } else { + + sb.append('.'); + } + } + list.add(sb.toString()); + System.out.println(sb.toString()); + } + System.out.println(); + + return list; + } + + public static void main(String[] args) { + solveNQueens(4); + } + +} From 244ae83646fc7f3ded9ff087414cb66862e99417 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 8 Apr 2019 23:54:30 +0800 Subject: [PATCH 051/162] iterate implement same tree --- code/LeetCode/src/SameTree.java | 56 ++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/code/LeetCode/src/SameTree.java b/code/LeetCode/src/SameTree.java index b064fdf5..c201104c 100644 --- a/code/LeetCode/src/SameTree.java +++ b/code/LeetCode/src/SameTree.java @@ -1,3 +1,6 @@ +import java.util.ArrayDeque; +import java.util.Deque; + public class SameTree { /* Same Tree @@ -51,11 +54,8 @@ public static class TreeNode { } public static boolean isSameTree(TreeNode p, TreeNode q) { - if (p == null && q == null) { - return true; - } if (p == null || q == null) { - return false; + return p == q; } if (p.val == q.val) { return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); @@ -64,6 +64,54 @@ public static boolean isSameTree(TreeNode p, TreeNode q) { return false; } + public static boolean checkTreeNode(TreeNode p, TreeNode q) { + if (p == null || q == null) { + return p == q; + } + if (p.val != q.val) { + return false; + } + + return true; + } + + public static boolean isSameTreeWithIterate(TreeNode p, TreeNode q) { + if (!checkTreeNode(p, q)) { + return false; + } + Deque dequeP = new ArrayDeque<>(); + Deque dequeQ = new ArrayDeque<>(); + if (p != null) { + dequeP.push(p); + dequeQ.push(q); + } + TreeNode firstP; + TreeNode firstQ; + while (!dequeP.isEmpty()) { + firstP = dequeP.removeFirst(); + firstQ = dequeQ.removeFirst(); + if (!checkTreeNode(firstP, firstQ)) { + return false; + } + if (!checkTreeNode(firstP.left, firstQ.left)) { + return false; + } + if (firstP.left != null) { + dequeP.push(firstP.left); + dequeQ.push(firstQ.left); + } + if (!checkTreeNode(firstP.right, firstQ.right)) { + return false; + } + if (firstP.right != null) { + dequeP.push(firstP.right); + dequeQ.push(firstQ.right); + } + } + + return true; + } + From 0619a43d5f74f6697d0f2dbe79d0c33d203506ad Mon Sep 17 00:00:00 2001 From: zgpeace Date: Thu, 11 Apr 2019 15:22:58 +0800 Subject: [PATCH 052/162] update symmetric tree --- code/LeetCode/src/SymmetricTree.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/code/LeetCode/src/SymmetricTree.java b/code/LeetCode/src/SymmetricTree.java index 9e6862a2..f385abc8 100644 --- a/code/LeetCode/src/SymmetricTree.java +++ b/code/LeetCode/src/SymmetricTree.java @@ -40,10 +40,8 @@ public boolean symmetricHelper(TreeNode leftNode, TreeNode rightNode) { if (leftNode == null || rightNode == null) { return leftNode == rightNode; } - if (leftNode.val != rightNode.val) { - return false; - } - return symmetricHelper(leftNode.left, rightNode.right) && symmetricHelper(leftNode.right, rightNode.left); + + return leftNode.val == rightNode.val && symmetricHelper(leftNode.left, rightNode.right) && symmetricHelper(leftNode.right, rightNode.left); } From 91a5d6de8ccfdee52ba23cd413910da01f7e8835 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Thu, 11 Apr 2019 15:23:14 +0800 Subject: [PATCH 053/162] TreeLevelOrderBottom --- .../src/tree/TreeLevelOrderBottom.java | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 code/LeetCode/src/tree/TreeLevelOrderBottom.java diff --git a/code/LeetCode/src/tree/TreeLevelOrderBottom.java b/code/LeetCode/src/tree/TreeLevelOrderBottom.java new file mode 100644 index 00000000..92486d14 --- /dev/null +++ b/code/LeetCode/src/tree/TreeLevelOrderBottom.java @@ -0,0 +1,82 @@ +package tree; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { + val = x; + } +} + +public class TreeLevelOrderBottom { + + public List> levelOrderBottom(TreeNode root) { + // root == null + if (root == null) { + return Collections.emptyList(); + } + + List> resultList = new ArrayList<>(); + // queue LinkedList for breadth search + LinkedList queue = new LinkedList<>(); + queue.add(root); + TreeNode currentNode; + while (!queue.isEmpty()) { + // current length + int length = queue.size(); + List list = new ArrayList<>(); + // iterate each depth + for (int i = 0; i < length; i++) { + currentNode = queue.pop(); + list.add(currentNode.val); + + // add tail data in queue + if (currentNode.left != null) { + queue.add(currentNode.left); + } + if (currentNode.right != null) { + queue.add(currentNode.right); + } + } + + // insert data in 0 position + resultList.add(0, list); + } + + // return result list + return resultList; + } + + public List> levelOrderBottomWithRecursive(TreeNode root) { + List> resultList = new ArrayList<>(); + depthSearchFirst(0, root, resultList); + + return resultList; + } + + public void depthSearchFirst(int level, TreeNode node, List> resultList) { + // null + if (node == null) { + return; + } + // create item List when size <= level + if (resultList.size() <= level) { + // warning: must add new item at first place. Because the left node will execute first. + resultList.add(0, new ArrayList()); + } + // left node + depthSearchFirst(level + 1, node.left, resultList); + // right node + depthSearchFirst( level + 1, node.right, resultList); + // add item Integer + resultList.get(resultList.size() - level - 1).add(node.val); + } + + +} From 4339438878c6dc8c5134084ba6ae2403266b4e42 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 16 Apr 2019 08:23:16 +0800 Subject: [PATCH 054/162] convert sorted array to binary search tree --- code/LeetCode/src/common/TreeNode.java | 11 +++ .../ConvertSortedArrayToBinarySearchTree.java | 92 +++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 code/LeetCode/src/common/TreeNode.java create mode 100644 code/LeetCode/src/tree/ConvertSortedArrayToBinarySearchTree.java diff --git a/code/LeetCode/src/common/TreeNode.java b/code/LeetCode/src/common/TreeNode.java new file mode 100644 index 00000000..5686ec4c --- /dev/null +++ b/code/LeetCode/src/common/TreeNode.java @@ -0,0 +1,11 @@ +package common; + +public class TreeNode { + public int val; + public TreeNode left; + public TreeNode right; + public TreeNode(int x) { + val = x; + } + +} diff --git a/code/LeetCode/src/tree/ConvertSortedArrayToBinarySearchTree.java b/code/LeetCode/src/tree/ConvertSortedArrayToBinarySearchTree.java new file mode 100644 index 00000000..6843187c --- /dev/null +++ b/code/LeetCode/src/tree/ConvertSortedArrayToBinarySearchTree.java @@ -0,0 +1,92 @@ +package tree; + +import common.TreeNode; + +import java.util.LinkedList; + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ + +public class ConvertSortedArrayToBinarySearchTree { + // method 1: Recursive + public TreeNode sortedArrayToBST(int[] nums) { + // root == null + if (nums == null || nums.length <= 0) { + return null; + } + // recurcive select middle + return selectMiddle(0, nums.length - 1, nums); + } + + public TreeNode selectMiddle(int leftIndex, int rightIndex, int[] nums) { + // leftIndex > rightIndex, break + if (leftIndex > rightIndex) { + return null; + } + int midIndex = leftIndex + ((rightIndex - leftIndex) >> 1); + TreeNode node = new TreeNode(nums[midIndex]); + node.left = selectMiddle(leftIndex, midIndex - 1, nums); + node.right = selectMiddle(midIndex + 1, rightIndex, nums); + + return node; + } + + // method 2: Iterate + public TreeNode sortedArrayToBSTWithIterate(int[] nums) { + // root null + if (nums == null || nums.length <= 0) { + return null; + } + + // queue for: root, left, right node + LinkedList nodeList = new LinkedList<>(); + // root node + TreeNode root = new TreeNode(0); + nodeList.add(root); + // queue for: leftIndex + LinkedList leftIndexList = new LinkedList<>(); + leftIndexList.add(0); + // queue for: rightIndex + LinkedList rightIndexList = new LinkedList<>(); + rightIndexList.add(nums.length - 1); + TreeNode node; + + // Iterate nodeLisk + while (!nodeList.isEmpty()) { + node = nodeList.removeFirst(); + // mid Index + int leftIndex = leftIndexList.removeFirst(); + int rightIndex = rightIndexList.removeFirst(); + int midIndex = leftIndex + ((rightIndex - leftIndex) >> 1); + node.val = nums[midIndex]; + + // left node + if (leftIndex < midIndex) { + node.left = new TreeNode(0); + nodeList.add(node.left); + leftIndexList.add(leftIndex); + rightIndexList.add(midIndex - 1); + } + + // right node + if (rightIndex > midIndex) { + node.right = new TreeNode(0); + nodeList.add(node.right); + leftIndexList.add(midIndex + 1); + rightIndexList.add(rightIndex); + } + } + + + return root; + } + + +} From 1fd7d6f65ea87564a60436a72090ca905b3a3c91 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Thu, 25 Apr 2019 12:40:29 +0800 Subject: [PATCH 055/162] Balance Binary tree --- .../LeetCode/src/tree/BalancedBinaryTree.java | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 code/LeetCode/src/tree/BalancedBinaryTree.java diff --git a/code/LeetCode/src/tree/BalancedBinaryTree.java b/code/LeetCode/src/tree/BalancedBinaryTree.java new file mode 100644 index 00000000..498608b6 --- /dev/null +++ b/code/LeetCode/src/tree/BalancedBinaryTree.java @@ -0,0 +1,53 @@ +package tree; + +import common.TreeNode; +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ +public class BalancedBinaryTree { + + public boolean isBalanced(TreeNode root) { + if (root == null) { + return true; + } + + return Math.abs(depth(root.left) - depth(root.right)) <= 1 && isBalanced(root.left) && isBalanced(root.right); + } + + public int depth(TreeNode node) { + if (node == null) { + return 0; + } + + return Math.max(depth(node.left), depth(node.right)) + 1; + } + + + public boolean isBalancedWithDfsDepth(TreeNode root) { + return dfsDepth(root) != -1; + } + + public int dfsDepth(TreeNode node) { + if (node == null) { + return 0; + } + int leftDepth = dfsDepth(node.left); + if (leftDepth == -1) { + return -1; + } + int rightDepth = dfsDepth(node.right); + if (rightDepth == -1) { + return -1; + } + if (Math.abs(leftDepth - rightDepth) > 1) { + return -1; + } + return Math.max(leftDepth, rightDepth) + 1; + } +} From b32143f80e8a48e65cfaee9079b592e28329d2d5 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Wed, 8 May 2019 15:20:34 +0800 Subject: [PATCH 056/162] update tree algorithm, both with breadth search first and depth search first --- .../LeetCode/src/tree/BalancedBinaryTree.java | 2 + .../ConvertSortedArrayToBinarySearchTree.java | 1 + code/LeetCode/src/tree/InvertBinaryTree.java | 52 ++++++++++++++ .../src/tree/MinimumDepthOfBinaryTree.java | 68 +++++++++++++++++++ code/LeetCode/src/tree/PathSum.java | 19 ++++++ .../src/tree/TreeLevelOrderBottom.java | 19 +++--- 6 files changed, 153 insertions(+), 8 deletions(-) create mode 100644 code/LeetCode/src/tree/InvertBinaryTree.java create mode 100644 code/LeetCode/src/tree/MinimumDepthOfBinaryTree.java create mode 100644 code/LeetCode/src/tree/PathSum.java diff --git a/code/LeetCode/src/tree/BalancedBinaryTree.java b/code/LeetCode/src/tree/BalancedBinaryTree.java index 498608b6..3724f76a 100644 --- a/code/LeetCode/src/tree/BalancedBinaryTree.java +++ b/code/LeetCode/src/tree/BalancedBinaryTree.java @@ -10,6 +10,8 @@ * TreeNode(int x) { val = x; } * } */ + +// https://leetcode.com/problems/balanced-binary-tree/ public class BalancedBinaryTree { public boolean isBalanced(TreeNode root) { diff --git a/code/LeetCode/src/tree/ConvertSortedArrayToBinarySearchTree.java b/code/LeetCode/src/tree/ConvertSortedArrayToBinarySearchTree.java index 6843187c..c7b718ad 100644 --- a/code/LeetCode/src/tree/ConvertSortedArrayToBinarySearchTree.java +++ b/code/LeetCode/src/tree/ConvertSortedArrayToBinarySearchTree.java @@ -14,6 +14,7 @@ * } */ +// https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/ public class ConvertSortedArrayToBinarySearchTree { // method 1: Recursive public TreeNode sortedArrayToBST(int[] nums) { diff --git a/code/LeetCode/src/tree/InvertBinaryTree.java b/code/LeetCode/src/tree/InvertBinaryTree.java new file mode 100644 index 00000000..63b23857 --- /dev/null +++ b/code/LeetCode/src/tree/InvertBinaryTree.java @@ -0,0 +1,52 @@ +package tree; + +import common.TreeNode; + +import java.util.LinkedList; +import java.util.Queue; + +// https://leetcode.com/problems/invert-binary-tree/ +public class InvertBinaryTree { + + public TreeNode invertTree(TreeNode root) { + if (root == null) { + return null; + } + + TreeNode leftNode = invertTree(root.left); + TreeNode rightNode = invertTree(root.right); + + root.left = rightNode; + root.right = leftNode; + + return root; + } + + public TreeNode invertTreeWithBFS(TreeNode root) { + if (root == null) { + return null; + } + + Queue queue = new LinkedList<>(); + queue.add(root); + TreeNode leftNode; + TreeNode currentNode; + while (!queue.isEmpty()) { + currentNode = queue.poll(); + leftNode = currentNode.left; + currentNode.left = currentNode.right; + currentNode.right = leftNode; + + if (currentNode.left != null) { + queue.add(currentNode.left); + } + if (currentNode.right != null) { + queue.add(currentNode.right); + } + + } + + return root; + } + +} diff --git a/code/LeetCode/src/tree/MinimumDepthOfBinaryTree.java b/code/LeetCode/src/tree/MinimumDepthOfBinaryTree.java new file mode 100644 index 00000000..c3b1119e --- /dev/null +++ b/code/LeetCode/src/tree/MinimumDepthOfBinaryTree.java @@ -0,0 +1,68 @@ +package tree; + +import common.TreeNode; + +import java.util.LinkedList; +import java.util.Queue; + +// https://leetcode.com/problems/minimum-depth-of-binary-tree/ +public class MinimumDepthOfBinaryTree { + + // Breath First Search by iterate + public int minDepth(TreeNode root) { + if (root == null) { + return 0; + } + + Queue queue = new LinkedList<>(); + queue.add(root); + int result = 0; + int currentLength; + boolean breakFlag; + TreeNode currentNode; + while (!queue.isEmpty()) { + result++; + currentLength = queue.size(); + breakFlag = false; + for (int i = 0; i < currentLength; i++) { + currentNode = queue.poll(); + if (currentNode.left == null && currentNode.right == null) { + breakFlag = true; + break; + } + if (currentNode.left != null) { + queue.add(currentNode.left); + } + if (currentNode.right != null) { + queue.add(currentNode.right); + } + } + if (breakFlag) { + break; + } + } + + return result; + } + + // Depth First Search + public int minDepthDSF(TreeNode root) { + if (root == null) { + return 0; + } + int leftDepth = minDepth(root.left); + if (root.right == null) { + return leftDepth + 1; + } + int rightDepth = minDepth(root.right); + if (root.left == null) { + return rightDepth + 1; + } + + return Math.min(leftDepth, rightDepth) + 1; + + } + + + +} diff --git a/code/LeetCode/src/tree/PathSum.java b/code/LeetCode/src/tree/PathSum.java new file mode 100644 index 00000000..787da43e --- /dev/null +++ b/code/LeetCode/src/tree/PathSum.java @@ -0,0 +1,19 @@ +package tree; + +import common.TreeNode; + +// https://leetcode.com/problems/path-sum/ +public class PathSum { + + public boolean hasPathSum(TreeNode root, int sum) { + if (root == null) { + return false; + } + // valid root is leaf + if (root.left == null && root.right == null && root.val == sum) { + return true; + } + sum -= root.val; + return hasPathSum(root.left, sum) || hasPathSum(root.right, sum); + } +} diff --git a/code/LeetCode/src/tree/TreeLevelOrderBottom.java b/code/LeetCode/src/tree/TreeLevelOrderBottom.java index 92486d14..01794f51 100644 --- a/code/LeetCode/src/tree/TreeLevelOrderBottom.java +++ b/code/LeetCode/src/tree/TreeLevelOrderBottom.java @@ -1,19 +1,22 @@ package tree; +import common.TreeNode; + import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; -class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { - val = x; - } -} +//class TreeNode { +// int val; +// TreeNode left; +// TreeNode right; +// TreeNode(int x) { +// val = x; +// } +//} +// https://leetcode.com/problems/binary-tree-level-order-traversal-ii/ public class TreeLevelOrderBottom { public List> levelOrderBottom(TreeNode root) { From 7e1d7db5eb23b299198330e758707a8c6bcf7d5f Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 13 May 2019 16:06:11 +0800 Subject: [PATCH 057/162] lowest common ancestor --- ...LowestCommonAncestorOfABinarySearchTree.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 code/LeetCode/src/tree/LowestCommonAncestorOfABinarySearchTree.java diff --git a/code/LeetCode/src/tree/LowestCommonAncestorOfABinarySearchTree.java b/code/LeetCode/src/tree/LowestCommonAncestorOfABinarySearchTree.java new file mode 100644 index 00000000..61c88266 --- /dev/null +++ b/code/LeetCode/src/tree/LowestCommonAncestorOfABinarySearchTree.java @@ -0,0 +1,17 @@ +package tree; + +import common.TreeNode; + +public class LowestCommonAncestorOfABinarySearchTree { + + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + + if (root.val > p.val && root.val > q.val) { + return lowestCommonAncestor(root.left, p, q); + } else if (root.val < p.val && root.val < q.val) { + return lowestCommonAncestor(root.right, p, q); + } else { + return root; + } + } +} From dd23344b837d017fcf8944b8976cd6764bf25f17 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Thu, 16 May 2019 12:48:24 +0800 Subject: [PATCH 058/162] binary tree paths --- code/LeetCode/src/tree/BinaryTreePaths.java | 69 +++++++++++++++++++ ...westCommonAncestorOfABinarySearchTree.java | 1 + 2 files changed, 70 insertions(+) create mode 100644 code/LeetCode/src/tree/BinaryTreePaths.java diff --git a/code/LeetCode/src/tree/BinaryTreePaths.java b/code/LeetCode/src/tree/BinaryTreePaths.java new file mode 100644 index 00000000..781e73ce --- /dev/null +++ b/code/LeetCode/src/tree/BinaryTreePaths.java @@ -0,0 +1,69 @@ +package tree; + +import common.TreeNode; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Stack; + +// https://leetcode.com/problems/binary-tree-paths/ +public class BinaryTreePaths { + + public List binaryTreePaths(TreeNode root) { + if (root == null) { + return Collections.emptyList(); + } + List list = new ArrayList<>(); + dfs("", root, list); + + return list; + } + + private void dfs(String s, TreeNode root, List list) { + s += Integer.toString(root.val); + + if (root.left == null && root.right == null) { + list.add(s); + } + s += "->"; + if (root.left != null) { + dfs(s, root.left, list); + } + if (root.right != null) { + dfs(s, root.right, list); + } + } + + public List binaryTreePathsWithStack(TreeNode root) { + if (root == null) { + return Collections.emptyList(); + } + Stack stack = new Stack<>(); + Stack pathStack = new Stack<>(); + stack.push(root); + TreeNode current; + List list = new ArrayList<>(); + String s = ""; + pathStack.push(s); + while (!stack.isEmpty()) { + current = stack.pop(); + s = pathStack.pop(); + s += Integer.toString(current.val); + if (current.left == null && current.right == null) { + list.add(s); + } + s += "->"; + if (current.left != null) { + stack.push(current.left); + pathStack.push(s); + } + if (current.right != null) { + stack.push(current.right); + pathStack.push(s); + } + } + + return list; + } +} diff --git a/code/LeetCode/src/tree/LowestCommonAncestorOfABinarySearchTree.java b/code/LeetCode/src/tree/LowestCommonAncestorOfABinarySearchTree.java index 61c88266..a3930ad0 100644 --- a/code/LeetCode/src/tree/LowestCommonAncestorOfABinarySearchTree.java +++ b/code/LeetCode/src/tree/LowestCommonAncestorOfABinarySearchTree.java @@ -2,6 +2,7 @@ import common.TreeNode; +// https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree public class LowestCommonAncestorOfABinarySearchTree { public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { From b556ae1d1f91d64d5f2736c67511d7356a25677d Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 17 May 2019 12:33:40 +0800 Subject: [PATCH 059/162] fizzbuzz --- code/LeetCode/src/loop/FizzBuzz.java | 48 ++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 code/LeetCode/src/loop/FizzBuzz.java diff --git a/code/LeetCode/src/loop/FizzBuzz.java b/code/LeetCode/src/loop/FizzBuzz.java new file mode 100644 index 00000000..15f94c74 --- /dev/null +++ b/code/LeetCode/src/loop/FizzBuzz.java @@ -0,0 +1,48 @@ +package loop; + +import java.util.ArrayList; +import java.util.List; + +public class FizzBuzz { + public List fizzBuzz(int n) { + List list = new ArrayList<>(); + for (int i = 1; i <= n; i++) { + if (i % 15 == 0) { + list.add("FizzBuzz"); + } else if (i % 5 == 0) { + list.add("Buzz"); + } else if (i % 3 == 0) { + list.add("Fizz"); + } else { + list.add(Integer.toString(i)); + } + } + + return list; + } + + public List fizzBuzzWithPlus(int n) { + List list = new ArrayList<>(); + int fizz = 0; + int buzz = 0; + for (int i = 1; i <= n; i++) { + fizz++; + buzz++; + if (fizz == 3 && buzz == 5) { + list.add("FizzBuzz"); + fizz = 0; + buzz = 0; + } else if (fizz == 3) { + list.add("Fizz"); + fizz = 0; + } else if (buzz == 5) { + list.add("Buzz"); + buzz = 0; + } else { + list.add(Integer.toString(i)); + } + } + + return list; + } +} From ac20eb172d350a98756ff577ace68acc841960f8 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Wed, 22 May 2019 12:26:07 +0800 Subject: [PATCH 060/162] first unique character in a string --- .../String/FirstUniqueCharacterInAString.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 code/LeetCode/src/String/FirstUniqueCharacterInAString.java diff --git a/code/LeetCode/src/String/FirstUniqueCharacterInAString.java b/code/LeetCode/src/String/FirstUniqueCharacterInAString.java new file mode 100644 index 00000000..077b1675 --- /dev/null +++ b/code/LeetCode/src/String/FirstUniqueCharacterInAString.java @@ -0,0 +1,30 @@ +package String; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +// https://leetcode.com/problems/first-unique-character-in-a-string/ +public class FirstUniqueCharacterInAString { + + public int firstUniqChar(String s) { + // order map + HashMap map = new HashMap<>(); + int n = s.length(); + // iterate s + for (int i = 0; i < n; i++) { + Character c = s.charAt(i); + // if no repeat is 1; else count++ + map.put(c, map.getOrDefault(c, 0) + 1); + } + + for (int j = 0; j < n; j++) { + // if no repeat is 1 + if (map.get(s.charAt(j)) == 1) { + return j; + } + } + + return -1; + } +} From ef0a7dcf6ea9343313714e582ef80ce1d85337d9 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Wed, 22 May 2019 12:26:20 +0800 Subject: [PATCH 061/162] sum of two integer --- .../src/bitwise/SumOfTwoIntegers.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 code/LeetCode/src/bitwise/SumOfTwoIntegers.java diff --git a/code/LeetCode/src/bitwise/SumOfTwoIntegers.java b/code/LeetCode/src/bitwise/SumOfTwoIntegers.java new file mode 100644 index 00000000..b8852097 --- /dev/null +++ b/code/LeetCode/src/bitwise/SumOfTwoIntegers.java @@ -0,0 +1,29 @@ +package bitwise; + +// https://leetcode.com/problems/sum-of-two-integers/ +// solution --> +// https://leetcode.com/problems/sum-of-two-integers/discuss/132479/Simple-explanation-on-how-to-arrive-at-the-solution +public class SumOfTwoIntegers { + public static int getSum(int a, int b) { + if (a == 0) { + return b; + } + if (b == 0) { + return a; + } + while (b != 0) { + int carry = a & b; + a = a ^ b; + b = carry << 1; + } + + return a; + } + + public static void main(String[] args) { + int result = getSum(1 ,2); + int result1 = getSum(-2, 3); + System.out.println("a = 1, b = 2, c = " + result); + System.out.println("a = -2, b = 3, c = " + result1); + } +} From e0893b8beb662c789425858da45053e03873207b Mon Sep 17 00:00:00 2001 From: zgpeace Date: Wed, 22 May 2019 14:17:57 +0800 Subject: [PATCH 062/162] intersection of two arrays --- .../src/array/IntersectionOfTwoArraysII.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 code/LeetCode/src/array/IntersectionOfTwoArraysII.java diff --git a/code/LeetCode/src/array/IntersectionOfTwoArraysII.java b/code/LeetCode/src/array/IntersectionOfTwoArraysII.java new file mode 100644 index 00000000..5eab8c64 --- /dev/null +++ b/code/LeetCode/src/array/IntersectionOfTwoArraysII.java @@ -0,0 +1,32 @@ +package array; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class IntersectionOfTwoArraysII { + + public int[] intersect(int[] nums1, int[] nums2) { + Map map = new HashMap<>(); + List list = new ArrayList<>(); + for (Integer i: nums1) { + map.put(i, map.getOrDefault(i, 0) + 1); + } + + for (Integer j: nums2) { + if (map.containsKey(j) && map.get(j) > 0) { + list.add(j); + map.put(j , (map.get(j) - 1)); + } + } + + + int[] result = new int[list.size()]; + for (int i = 0; i < list.size(); i++) { + result[i] = list.get(i); + } + + return result; + } +} From b8c8c3731dbd6bc83d08ce55a7e6473ff6bd508d Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 24 May 2019 12:16:01 +0800 Subject: [PATCH 063/162] power of three --- code/LeetCode/src/number/PowerOfThree.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 code/LeetCode/src/number/PowerOfThree.java diff --git a/code/LeetCode/src/number/PowerOfThree.java b/code/LeetCode/src/number/PowerOfThree.java new file mode 100644 index 00000000..6e2a0ada --- /dev/null +++ b/code/LeetCode/src/number/PowerOfThree.java @@ -0,0 +1,15 @@ +package number; + +// https://leetcode.com/problems/power-of-three/ +public class PowerOfThree { + public boolean isPowerOfThree(int n) { + if (n <= 0) { + return false; + } + while (n % 3 == 0) { + n = n / 3; + } + + return n == 1; + } +} From e6b17df7a80ba3bc30aedb56361557afe7768e29 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 24 May 2019 12:16:12 +0800 Subject: [PATCH 064/162] reverse string --- code/LeetCode/src/String/ReverseString.java | 34 +++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 code/LeetCode/src/String/ReverseString.java diff --git a/code/LeetCode/src/String/ReverseString.java b/code/LeetCode/src/String/ReverseString.java new file mode 100644 index 00000000..aa8634d6 --- /dev/null +++ b/code/LeetCode/src/String/ReverseString.java @@ -0,0 +1,34 @@ +package String; + +// https://leetcode.com/problems/reverse-string/ +public class ReverseString { + public static void reverseString(char[] s) { + char c; + int len = s.length; + for (int i = 0; i < len >> 1; i++) { + c = s[i]; + s[i] = s[len - 1 - i]; + s[len - 1 - i] = c; + } + } + + public static void reverseStringWithWhile(char[] s) { + char c; + int leftIndex = 0; + int rightIndex = s.length - 1; + while (leftIndex < rightIndex) { + c = s[leftIndex]; + s[leftIndex] = s[rightIndex]; + s[rightIndex] = c; + leftIndex++; + rightIndex--; + } + } + + public static void main(String[] args) { + char[] s = {'h','e','l','l','o'}; + System.out.println(s); + reverseString(s); + System.out.println(s); + } +} From b0be0e9d1d07600a3b75095ea18652c658b53828 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 24 May 2019 12:49:25 +0800 Subject: [PATCH 065/162] move zeroes --- code/LeetCode/src/array/MoveZeroes.java | 53 +++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 code/LeetCode/src/array/MoveZeroes.java diff --git a/code/LeetCode/src/array/MoveZeroes.java b/code/LeetCode/src/array/MoveZeroes.java new file mode 100644 index 00000000..905a77fb --- /dev/null +++ b/code/LeetCode/src/array/MoveZeroes.java @@ -0,0 +1,53 @@ +package array; + +public class MoveZeroes { + public void moveZeroes(int[] nums) { + int zeroCount = 0; + int len = nums.length; + int current; + for(int i = 0; i Date: Sat, 25 May 2019 12:56:17 +0800 Subject: [PATCH 066/162] delete node in a linked list --- code/LeetCode/src/node/DeleteNodeInALinkedList.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 code/LeetCode/src/node/DeleteNodeInALinkedList.java diff --git a/code/LeetCode/src/node/DeleteNodeInALinkedList.java b/code/LeetCode/src/node/DeleteNodeInALinkedList.java new file mode 100644 index 00000000..dc2df324 --- /dev/null +++ b/code/LeetCode/src/node/DeleteNodeInALinkedList.java @@ -0,0 +1,11 @@ +package node; + +import common.ListNode; + +// https://leetcode.com/problems/delete-node-in-a-linked-list/ +public class DeleteNodeInALinkedList { + public void deleteNode(ListNode node) { + node.val = node.next.val; + node.next = node.next.next; + } +} From ae9c8c4e6e4fb88e5b9aa6b3f718c9a091cbe8d4 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 27 May 2019 15:31:05 +0800 Subject: [PATCH 067/162] palindrome linked list --- .../src/node/PalindromeLinkedList.java | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 code/LeetCode/src/node/PalindromeLinkedList.java diff --git a/code/LeetCode/src/node/PalindromeLinkedList.java b/code/LeetCode/src/node/PalindromeLinkedList.java new file mode 100644 index 00000000..efcc8c6e --- /dev/null +++ b/code/LeetCode/src/node/PalindromeLinkedList.java @@ -0,0 +1,69 @@ +package node; + +import common.ListNode; + +import java.util.Stack; + +// https://leetcode.com/problems/palindrome-linked-list/ +public class PalindromeLinkedList { + + public boolean isPalindrome(ListNode head) { + ListNode l1 = head; + Stack stack = new Stack<>(); + while (l1 != null) { + stack.push(l1.val); + l1 = l1.next; + } + + ListNode l2 = head; + int c; + int half = stack.size() >> 1; + int count = 0; + while (l2 != null && count < half) { + c = stack.pop(); + if (c != l2.val) { + return false; + } + l2 = l2.next; + count++; + } + + return true; + } + + public boolean isPalindromeWithSlowFastStep(ListNode head) { + ListNode slow = head, fast = head; + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + } + if (fast != null) { + slow = slow.next; + } + fast = head; + slow = reverse(slow); + while (slow != null) { + if (fast.val != slow.val) { + return false; + } + slow = slow.next; + fast = fast.next; + } + + return true; + } + + private ListNode reverse(ListNode slow) { + ListNode pre = null; + ListNode next; + while (slow != null) { + next = slow.next; + slow.next = pre; + pre = slow; + slow = next; + } + + return pre; + } + +} From 8b632c8ba8c34737cdc8c05850ba488b8073778b Mon Sep 17 00:00:00 2001 From: zgpeace Date: Wed, 29 May 2019 19:10:49 +0800 Subject: [PATCH 068/162] missing number --- code/LeetCode/src/number/MissingNumber.java | 75 +++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 code/LeetCode/src/number/MissingNumber.java diff --git a/code/LeetCode/src/number/MissingNumber.java b/code/LeetCode/src/number/MissingNumber.java new file mode 100644 index 00000000..3f48fdab --- /dev/null +++ b/code/LeetCode/src/number/MissingNumber.java @@ -0,0 +1,75 @@ +package number; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +// https://leetcode.com/problems/missing-number/ +public class MissingNumber { + + public static int missingNumber(int[] nums) { + int left = 0; + int right = nums.length - 1; + Set set = new HashSet<>(); + while (left <= right) { + set.add(nums[left]); + set.add(nums[right]); + left++; + right--; + } + left = 0; + right = nums.length; + while (left <= right) { + if (!set.contains(left)) { + return left; + } + if (!set.contains(right)) { + return right; + } + left++; + right--; + } + + return nums.length; + } + + public static int missingNumberWithSum(int[] nums) { + int len = nums.length; + int result = len; + for (int i = 0; i < len; i++) { + result = result - nums[i] + i; + } + + return result; + } + + public static int missingNumberWithSort(int[] nums) { + Arrays.sort(nums); + + int len = nums.length; + // Ensure that 0 is at the first index + if (nums[0] != 0) { + return 0; + } + // Ensure that n is at the last index + if (nums[len - 1] != len) { + return len; + } + + // If we get here, then the missing number is on the range (0 , n) + for (int i = 1; i < len; i++) { + if (i != nums[i]) { + return i; + } + } + + // Array was not missing any numbers + return -1; + } + + + public static void main(String[] args) { + int[] input = new int[]{3,0,1}; + int result = missingNumber(input); + } +} From b9221f5a05c1aaef706b55e7f553c46b862a9513 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 4 Jun 2019 18:35:27 +0800 Subject: [PATCH 069/162] missing number --- code/LeetCode/src/number/MissingNumber.java | 24 +++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/code/LeetCode/src/number/MissingNumber.java b/code/LeetCode/src/number/MissingNumber.java index 3f48fdab..b97ff91c 100644 --- a/code/LeetCode/src/number/MissingNumber.java +++ b/code/LeetCode/src/number/MissingNumber.java @@ -33,6 +33,21 @@ public static int missingNumber(int[] nums) { return nums.length; } + public static int missingNumberWithSet(int[] nums) { + Set set = new HashSet<>(); + for (int i: nums) { + set.add(i); + } + + for (int i = 0; i < nums.length; i++) { + if (!set.contains(i)) { + return i; + } + } + + return nums.length; + } + public static int missingNumberWithSum(int[] nums) { int len = nums.length; int result = len; @@ -67,6 +82,15 @@ public static int missingNumberWithSort(int[] nums) { return -1; } + public static int missingNumberWithBit(int[] nums) { + int missing = nums.length; + for (int i = 0; i < nums.length; i++) { + missing ^= i ^ nums[i]; + } + + return missing; + } + public static void main(String[] args) { int[] input = new int[]{3,0,1}; From 2579b6a5fc4ad76b0abce7b5348b9f2b2b079cbc Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 4 Jun 2019 18:35:36 +0800 Subject: [PATCH 070/162] reverse linked list --- code/LeetCode/src/node/ReverseLinkedList.java | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 code/LeetCode/src/node/ReverseLinkedList.java diff --git a/code/LeetCode/src/node/ReverseLinkedList.java b/code/LeetCode/src/node/ReverseLinkedList.java new file mode 100644 index 00000000..9f6ec70e --- /dev/null +++ b/code/LeetCode/src/node/ReverseLinkedList.java @@ -0,0 +1,48 @@ +package node; + +import common.ListNode; + +// https://leetcode.com/problems/reverse-linked-list/ +public class ReverseLinkedList { + + public ListNode reverseList(ListNode head) { + ListNode node = head; + ListNode pre = null; + ListNode next; + while (node != null) { + next = node.next; + node.next = pre; + pre = node; + node = next; + } + + return pre; + } + + public ListNode reverseListWithRecursive(ListNode head) { + return helperReverseListWithRecursive(head, null); + } + + private ListNode helperReverseListWithRecursive(ListNode current, ListNode pre) { + // terminate condition + if (current == null) { + return pre; + } + ListNode next = current.next; + current.next = pre; + pre = current; + current = next; + return helperReverseListWithRecursive(current, pre); + } + + // reverse direct: node.next.next = node + public ListNode reverseListWithRecursiveTricky(ListNode head) { + if (head == null || head.next == null) { + return head; + } + ListNode p = reverseListWithRecursiveTricky(head.next); + head.next.next = head; + head.next = null; + return p; + } +} From 6e87b2641415acac40fc51e4cd328e068d1fc3d8 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 4 Jun 2019 18:35:48 +0800 Subject: [PATCH 071/162] contains duplicate --- .../src/number/ContainsDuplicate.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 code/LeetCode/src/number/ContainsDuplicate.java diff --git a/code/LeetCode/src/number/ContainsDuplicate.java b/code/LeetCode/src/number/ContainsDuplicate.java new file mode 100644 index 00000000..47269723 --- /dev/null +++ b/code/LeetCode/src/number/ContainsDuplicate.java @@ -0,0 +1,19 @@ +package number; + +import java.util.HashSet; +import java.util.Set; + +// https://leetcode.com/problems/contains-duplicate/ +public class ContainsDuplicate { + public boolean containsDuplicate(int[] nums) { + Set set = new HashSet<>(); + for (int i : nums) { + if (set.contains(i)) { + return true; + } + set.add(i); + } + + return false; + } +} From 9b4331a747f0d340a4cf0d36be17400d16c9b0d8 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 4 Jun 2019 18:35:54 +0800 Subject: [PATCH 072/162] count prime --- code/LeetCode/src/number/CountPrime.java | 67 ++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 code/LeetCode/src/number/CountPrime.java diff --git a/code/LeetCode/src/number/CountPrime.java b/code/LeetCode/src/number/CountPrime.java new file mode 100644 index 00000000..ebfa7159 --- /dev/null +++ b/code/LeetCode/src/number/CountPrime.java @@ -0,0 +1,67 @@ +package number; + +import java.util.ArrayList; +import java.util.List; + +public class CountPrime { + public static int countPrimes(int n) { + List list = new ArrayList<>(); + if (n > 2) { + list.add(2); + } + for (int i = 3; i < n; i++) { + for (int k: list) { + if (i % k == 0) { + break; + } + if (k > i / k) { + list.add(i); + break; + } + } + } + + System.out.println(list); + return list.size(); + } + + public int countPrimesWithBoolArray(int n) { + if (n < 3) { + return 0; + } + boolean[] array = new boolean[n]; + int count = 0; + for (int i = 2; i < n; i++) { + if (array[i] == false) { + count++; + for (int k = 2; i * k < n; k++) { + array[i * k] = true; + } + } + } + + return count; + } + + public int countPrimesWithReduseEven(int n){ + if (n < 3) { + return 0; + } + boolean[] evenArray = new boolean[n]; + // Arrays.fill(evenArray, true); boolean[] are initialed as false by default + int count = n / 2; + for (int i = 3; i * i < n; i += 2) { + if (evenArray[i]) { + continue; + } + for(int k = i * i; k < n; k = k + i * 2) { + if (evenArray[k] == false) { + evenArray[k] = true; + count--; + } + } + } + + return count; + } +} From accc13048df2225665ca215f662e9970772c7e90 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 4 Jun 2019 18:36:20 +0800 Subject: [PATCH 073/162] valid anagram --- code/LeetCode/src/String/ValidAnagram.java | 60 ++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 code/LeetCode/src/String/ValidAnagram.java diff --git a/code/LeetCode/src/String/ValidAnagram.java b/code/LeetCode/src/String/ValidAnagram.java new file mode 100644 index 00000000..85cb76cb --- /dev/null +++ b/code/LeetCode/src/String/ValidAnagram.java @@ -0,0 +1,60 @@ +package String; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +// https://leetcode.com/problems/valid-anagram/ +public class ValidAnagram { + public boolean isAnagram(String s, String t) { + if (s.length() != t.length()) { + return false; + } + int count = 0; + Map map = new HashMap<>(); + for (char c : s.toCharArray()) { + map.put(c, map.getOrDefault(c, 0) + 1); + count++; + } + for (char c : t.toCharArray()) { + if (map.containsKey(c) && map.get(c) > 0) { + map.put(c, map.get(c) - 1); + } else { + return false; + } + count--; + } + + return count == 0; + } + + public boolean isAnagramWithSort(String s, String t) { + if (s.length() != t.length()) { + return false; + } + char[] sChars = s.toCharArray(); + char[] tChars = t.toCharArray(); + Arrays.sort(sChars); + Arrays.sort(tChars); + + return Arrays.equals(sChars, tChars); + } + + public boolean isAnagramWithChar(String s, String t) { + if (s.length() != t.length()) { + return false; + } + int[] count = new int[26]; + for (int i = 0; i < s.length(); i++) { + count[s.charAt(i) - 'a']++; + count[t.charAt(i) - 'a']--; + } + for (int i = 0; i < 26; i++) { + if (count[i] != 0) { + return false; + } + } + + return true; + } +} From c00bec6e5544a18f1e914c3401fc9ea923846738 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Thu, 6 Jun 2019 12:30:11 +0800 Subject: [PATCH 074/162] happy number --- code/LeetCode/src/number/HappyNumber.java | 63 +++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 code/LeetCode/src/number/HappyNumber.java diff --git a/code/LeetCode/src/number/HappyNumber.java b/code/LeetCode/src/number/HappyNumber.java new file mode 100644 index 00000000..a2345abb --- /dev/null +++ b/code/LeetCode/src/number/HappyNumber.java @@ -0,0 +1,63 @@ +package number; + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Queue; +import java.util.Set; + +// https://leetcode.com/problems/happy-number/ +public class HappyNumber { + public boolean isHappy(int n) { + // record pass number, validate whether is cycle + Set set = new HashSet<>(); + // current number + Queue queue = new LinkedList<>(); + set.add(n); + queue.add(n); + // sum + int sum; + int current; + int remainder; + while (!queue.isEmpty()) { + current = queue.poll(); + sum = 0; + while (current != 0) { + remainder = current % 10; + sum += remainder * remainder; + current = current / 10; + } + if (sum == 1) { + return true; + } + if (set.contains(sum)) { + return false; + } + queue.add(sum); + set.add(sum); + } + + return false; + } + + public boolean isHappyWithSet(int n) { + // valid whether is loop + Set isLoopSet = new HashSet<>(); + int current = n; + int sum; + int remainder; + while (isLoopSet.add(current)) { + sum = 0; + while (current != 0) { + remainder = current % 10; + sum += remainder * remainder; + current = current / 10; + } + if (sum == 1) { + return true; + } + current = sum; + } + + return false; + } +} From 67810e16ad0f2e60a44d0c90bf3c1ea9d9d873ef Mon Sep 17 00:00:00 2001 From: zgpeace Date: Thu, 6 Jun 2019 12:42:26 +0800 Subject: [PATCH 075/162] slow and fast to validate is loop --- code/LeetCode/src/number/HappyNumber.java | 27 +++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/code/LeetCode/src/number/HappyNumber.java b/code/LeetCode/src/number/HappyNumber.java index a2345abb..fd641e0b 100644 --- a/code/LeetCode/src/number/HappyNumber.java +++ b/code/LeetCode/src/number/HappyNumber.java @@ -60,4 +60,31 @@ public boolean isHappyWithSet(int n) { return false; } + + public boolean isHappyWithoutSet(int n) { + int slow = n; + int fast = n; + int maxCount = Integer.MAX_VALUE; + + do { + slow = calculateHappy(slow); + fast = calculateHappy(fast); + fast = calculateHappy(fast); + maxCount--; + } while (slow != fast && maxCount > 0); + + return slow == 1; + } + + public int calculateHappy(int current) { + int sum = 0; + int remainder; + while (current != 0) { + remainder = current % 10; + sum += remainder * remainder; + current = current / 10; + } + + return sum; + } } From 031555e5ed20350769b0ca8039f77d1cf584dc0c Mon Sep 17 00:00:00 2001 From: zgpeace Date: Sun, 9 Jun 2019 10:46:12 +0800 Subject: [PATCH 076/162] house robber --- code/LeetCode/src/array/HouseRobber.java | 108 +++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 code/LeetCode/src/array/HouseRobber.java diff --git a/code/LeetCode/src/array/HouseRobber.java b/code/LeetCode/src/array/HouseRobber.java new file mode 100644 index 00000000..a128fad4 --- /dev/null +++ b/code/LeetCode/src/array/HouseRobber.java @@ -0,0 +1,108 @@ +package array; + +import java.util.Arrays; + +// https://leetcode.com/problems/house-robber/ +public class HouseRobber { + public static int rob(int[] nums) { + // back tracking + return subRob(nums, 0); + + } + + public static int subRob(int[] nums, int index) { + if (index >= nums.length) { + return 0; + } + // if select current + int sum1 = nums[index] + subRob(nums,index + 2); + // if not select current + int sum2 = subRob(nums, index + 1); + return Math.max(sum1, sum2); + } + + public static int robReverse(int[] nums) { + return subRobReverse(nums, nums.length - 1); + } + + public static int subRobReverse(int[] nums, int index) { + if (index < 0) { + return 0; + } + return Math.max(subRobReverse(nums, index - 2) + nums[index], subRobReverse(nums, index - 1)); + } + + static int[] memo; + + public static int robReverseWithMemo(int[] nums) { + memo = new int[nums.length]; + Arrays.fill(memo, -1); + + return subRobReverseWithMemo(nums, nums.length - 1); + } + + public static int subRobReverseWithMemo(int[] nums, int index) { + if (index < 0) { + return 0; + } + if (memo[index] != -1) { + return memo[index]; + } + memo[index] = Math.max(subRobReverseWithMemo(nums, index - 2) + nums[index], subRobReverseWithMemo(nums, index - 1)); + + return memo[index]; + } + + public static int robIterate(int[] nums) { + if (nums.length <= 0) { + return 0; + } + int[] memory = new int[nums.length + 1]; + memory[0] = 0; + memory[1] = nums[0]; + for (int i = 1; i < nums.length; i++) { + memory[i + 1] = Math.max(memory[i], memory[i - 1] + nums[i]); + } + + return memory[nums.length]; + } + + public static int robDP(int[] nums) { + if (nums.length <= 0) { + return 0; + } + int notRobPre = 0; + int robPre = nums[0]; + int temp; + for (int i = 1; i < nums.length; i++) { + temp = Math.max(robPre, notRobPre + nums[i]); + notRobPre = robPre; + robPre = temp; + } + + return robPre; + } + + public static int robDPStatus(int[] nums) { + int[][] dp = new int[nums.length + 1][2]; + for (int i = 1; i <= nums.length; i++) { + dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1]); + dp[i][1] = nums[i - 1] + dp[i - 1][0]; + } + + return Math.max(dp[nums.length][0], dp[nums.length][1]); + } + + public static void main(String[] args) { + int[] input = {1, 2, 3, 1}; + int result; + result = robDPStatus(input); + System.out.println("result: " + result); + input = new int[]{2, 7, 9, 3, 1}; + result = robDPStatus(input); + System.out.println("result: " + result); + input = new int[]{2, 1, 1, 2}; + result = robDPStatus(input); + System.out.println("result: " + result); + } +} From d9557eadabb51d2e3a2bf77cea4fd19284dc8bb1 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Sun, 9 Jun 2019 11:09:31 +0800 Subject: [PATCH 077/162] number of one bits --- .../LeetCode/src/bitwise/NumberOfOneBits.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 code/LeetCode/src/bitwise/NumberOfOneBits.java diff --git a/code/LeetCode/src/bitwise/NumberOfOneBits.java b/code/LeetCode/src/bitwise/NumberOfOneBits.java new file mode 100644 index 00000000..d87c3c6c --- /dev/null +++ b/code/LeetCode/src/bitwise/NumberOfOneBits.java @@ -0,0 +1,32 @@ +package bitwise; + +// https://leetcode.com/problems/number-of-1-bits/ +public class NumberOfOneBits { + // you need to treat n as an unsigned value + public static int hanmmingWeight(int n) { + int count = 0; + while (n != 0) { + n = n & (n - 1); + count++; + } + + return count; + } + + public static int hanmmingWeightVerbose(int n) { + int count = 0; + int mask = 1; + for (int i = 1; i <= 32; i++) { + if ((n & mask) != 0) { + count++; + } + mask <<= 1; + } + + return count; + } + + public static void main(String[] args) { + System.out.println(hanmmingWeightVerbose(11)); + } +} From 55f5bd0fe3f39dd5baba4cd679966da303eb02dd Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 10 Jun 2019 10:03:08 +0800 Subject: [PATCH 078/162] reverse bits --- code/LeetCode/src/bitwise/ReverseBits.java | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 code/LeetCode/src/bitwise/ReverseBits.java diff --git a/code/LeetCode/src/bitwise/ReverseBits.java b/code/LeetCode/src/bitwise/ReverseBits.java new file mode 100644 index 00000000..e7f4270e --- /dev/null +++ b/code/LeetCode/src/bitwise/ReverseBits.java @@ -0,0 +1,21 @@ +package bitwise; + +// https://leetcode.com/problems/reverse-bits/ +public class ReverseBits { + // you need treat n as an unsigned value + public int reverseBits(int n) { + int mask = 1; + int result = 0; + int appendInt; + for (int i = 1; i <= 32; i++) { + appendInt = 0; + if ((mask & n) != 0) { + appendInt = 1; + } + result = (result << 1) + appendInt; + mask <<= 1; + } + + return result; + } +} From 081f4168ede0f56f8f40d3ab9a606354882cd699 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 11 Jun 2019 12:45:53 +0800 Subject: [PATCH 079/162] rotate array --- code/LeetCode/src/array/RotateArray.java | 94 ++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 code/LeetCode/src/array/RotateArray.java diff --git a/code/LeetCode/src/array/RotateArray.java b/code/LeetCode/src/array/RotateArray.java new file mode 100644 index 00000000..ea0c797b --- /dev/null +++ b/code/LeetCode/src/array/RotateArray.java @@ -0,0 +1,94 @@ +package array; + +import java.util.Arrays; + +// https://leetcode.com/problems/rotate-array/ +public class RotateArray { + public static void rotate(int[] nums, int k) { + int first; + for (int i = 0; i < k; i++) { + if (nums.length <= 0) { + return; + } + first = nums[nums.length - 1]; + for (int n = nums.length - 1; n >= 0; n--) { + nums[n] = n == 0 ? first : nums[n - 1]; + } + } + } + + public static void rotateWithStep(int[] nums, int k) { + int len = nums.length; + if (len <= 0 || k <= 0) { + return; + } + k = k % len; + int[] tempArray = new int[k]; + for (int i = 0; i < k; i++) { + tempArray[k - 1 - i] = nums[len - 1 - i]; + } + for (int n = len - 1; n > k - 1; n--) { + nums[n] = nums[n - k]; + } + for (int n = k - 1; n >= 0; n--) { + nums[n] = tempArray[n]; + } + + } + + public static void rotateWithCyclicReplacement(int[] nums, int k) { + int count = 0; + int len = nums.length; + // edge juge + if (len <= 0 || k <= 0) { + return; + } + // reduce k bigger than len; + k = k % len; + + // start nums index + for (int i = 0; count < len; i++) { + int start = i; + int prev = nums[start]; + // while step replace cycle + do { + int current = (start + k) % len; + int next = nums[current]; + nums[current] = prev; + prev = next; + start = current; + count++; + } while (start != i); + } + } + + public static void rotateWithReverse(int[] nums, int k) { + int len = nums.length; + // edge juge + if (len <= 0 || k <= 0) { + return; + } + // reduce k bigger than len; + k = k % len; + subRotateWithReverse(nums, 0, nums.length - 1); + subRotateWithReverse(nums, 0, k - 1); + subRotateWithReverse(nums, k, nums.length - 1); + } + + public static void subRotateWithReverse(int[] nums, int begin, int end) { + while (begin < end) { + int temp = nums[begin]; + nums[begin] = nums[end]; + nums[end] = temp; + begin++; + end--; + } + } + + public static void main(String[] args) { + int[] input = new int[]{1,2,3,4,5,6,7}; + System.out.println(Arrays.toString(input)); + rotateWithReverse(input, 3); + System.out.println(Arrays.toString(input)); + } +} From 777b363c3dc30b8260fc499bc666f9fe692847df Mon Sep 17 00:00:00 2001 From: zgpeace Date: Thu, 13 Jun 2019 15:42:05 +0800 Subject: [PATCH 080/162] factorial trailing zeroes --- .../src/number/FactorialTrailingZeroes.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 code/LeetCode/src/number/FactorialTrailingZeroes.java diff --git a/code/LeetCode/src/number/FactorialTrailingZeroes.java b/code/LeetCode/src/number/FactorialTrailingZeroes.java new file mode 100644 index 00000000..35820394 --- /dev/null +++ b/code/LeetCode/src/number/FactorialTrailingZeroes.java @@ -0,0 +1,18 @@ +package number; + +// https://leetcode.com/problems/factorial-trailing-zeroes/ +public class FactorialTrailingZeroes { + public int trailingZeroes(int n) { + int count = 0; + while (n > 0) { + n = n / 5; + count += n; + } + + return count; + } + + public int trailingZeroesWithRecursive(int n) { + return n == 0 ? 0 : n / 5 + trailingZeroesWithRecursive(n / 5); + } +} From 193fcf559d055e3053e7065aca55e6ee5f4fb2b1 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Thu, 13 Jun 2019 15:42:15 +0800 Subject: [PATCH 081/162] excel sheet column number --- .../src/String/ExcelSheetColumnNumber.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 code/LeetCode/src/String/ExcelSheetColumnNumber.java diff --git a/code/LeetCode/src/String/ExcelSheetColumnNumber.java b/code/LeetCode/src/String/ExcelSheetColumnNumber.java new file mode 100644 index 00000000..18e8d3e7 --- /dev/null +++ b/code/LeetCode/src/String/ExcelSheetColumnNumber.java @@ -0,0 +1,36 @@ +package String; + +// https://leetcode.com/problems/excel-sheet-column-number/ +public class ExcelSheetColumnNumber { + + public static int titleToNumber(String s) { + int sum = 0; + char current; + int num; + int carry = 1; + int len = s.length(); + for (int i = len - 1; i >= 0; i--) { + current = s.charAt(i); + num = current - 'A' + 1; + sum = sum + num * carry; + carry *= 26; + } + + return sum; + } + + public static int titleToNumberAsc(String s) { + int result = 0; + for (int i = 0; i < s.length(); i++) { + result = result * 26 + (s.charAt(i) - 'A' + 1); + } + + return result; + } + + public static void main(String[] args) { + int sum = titleToNumberAsc("AA"); + System.out.println("sum: " + sum); + } + +} From 76c0345a0d6bf2355e99cd6f46fb7b975c62fa27 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 18 Jun 2019 11:34:23 +0800 Subject: [PATCH 082/162] majority element --- code/LeetCode/src/array/MajorityElement.java | 41 ++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 code/LeetCode/src/array/MajorityElement.java diff --git a/code/LeetCode/src/array/MajorityElement.java b/code/LeetCode/src/array/MajorityElement.java new file mode 100644 index 00000000..1b492754 --- /dev/null +++ b/code/LeetCode/src/array/MajorityElement.java @@ -0,0 +1,41 @@ +package array; + +import java.util.HashMap; +import java.util.Map; + +// https://leetcode.com/problems/majority-element/ +public class MajorityElement { + public static int majorityElement(int[] nums) { + Map map = new HashMap<>(); + int half = nums.length >> 1; + for (int n: nums) { + map.put(n, map.getOrDefault(n, 0) + 1); + if (map.get(n) > half) { + return n; + } + } + + return -1; + } + + public static int majorityElementWithBoyerMoorVoting(int[] nums) { + int count = 0; + // default is invalid + int candidate = -1; + for (int n: nums) { + if (count == 0) { + candidate = n; + } + count += (candidate == n ? 1 : -1); + } + + return candidate; + } + + + + public static void main(String[] args) { + int result = majorityElementWithBoyerMoorVoting(new int[]{6, 5, 5}); + System.out.println(result); + } +} From dbc89a55f68a3881a40692a02acb9b791f625641 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Thu, 20 Jun 2019 12:31:52 +0800 Subject: [PATCH 083/162] intersection of two linked lists --- code/LeetCode/src/common/ListNode.java | 9 ++++ .../node/IntersectionOfTwoLinkedLists.java | 54 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 code/LeetCode/src/node/IntersectionOfTwoLinkedLists.java diff --git a/code/LeetCode/src/common/ListNode.java b/code/LeetCode/src/common/ListNode.java index 7b0a7003..76bad308 100644 --- a/code/LeetCode/src/common/ListNode.java +++ b/code/LeetCode/src/common/ListNode.java @@ -30,4 +30,13 @@ public String toString() { } return sb.append("Null").toString(); } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + return false; + } } diff --git a/code/LeetCode/src/node/IntersectionOfTwoLinkedLists.java b/code/LeetCode/src/node/IntersectionOfTwoLinkedLists.java new file mode 100644 index 00000000..715f03d0 --- /dev/null +++ b/code/LeetCode/src/node/IntersectionOfTwoLinkedLists.java @@ -0,0 +1,54 @@ +package node; + +import common.ListNode; + +// https://leetcode.com/problems/intersection-of-two-linked-lists/ +public class IntersectionOfTwoLinkedLists { + + public static ListNode getIntersectionNodeWithLoopOtherHead(ListNode headA, ListNode headB) { + //boundary check + if(headA == null || headB == null) return null; + + ListNode a = headA; + ListNode b = headB; + + //if a & b have different len, then we will stop the loop after second iteration + while( a != b){ + //for the end of first iteration, we just reset the pointer to the head of another linkedlist + a = a == null? headB : a.next; + b = b == null? headA : b.next; + } + + return a; + } + + public static ListNode getIntersectionNodeWithClipToSameLength(ListNode headA, ListNode headB) { + int lenA = getNodeLength(headA); + int lenB = getNodeLength(headB); + while (lenA > lenB) { + lenA--; + headA = headA.next; + } + while (lenB > lenA) { + lenB--; + headB = headB.next; + } + while (headA != headB) { + headA = headA.next; + headB = headB.next; + } + + return headA; + } + + public static int getNodeLength(ListNode head) { + int len = 0; + while (head != null) { + len++; + head = head.next; + } + + return len; + } + +} From 20893763461cf1cccca2372f87bb181c90fe5128 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 24 Jun 2019 14:38:26 +0800 Subject: [PATCH 084/162] min stack --- code/LeetCode/src/stack/MinStack.java | 119 ++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 code/LeetCode/src/stack/MinStack.java diff --git a/code/LeetCode/src/stack/MinStack.java b/code/LeetCode/src/stack/MinStack.java new file mode 100644 index 00000000..c142f168 --- /dev/null +++ b/code/LeetCode/src/stack/MinStack.java @@ -0,0 +1,119 @@ +package stack; + +import java.util.Stack; + +class MinStackWithNode { + Node head; + + public void push(int x) { + if (head == null) { + head = new Node(x, x, null); + } else { + head = new Node(x, Math.min(x, head.min), head); + } + } + + public void pop() { + head = head.next; + } + + public int top() { + return head.val; + } + + public int getMin() { + return head.min; + } +} + +class Node { + int val; + int min = Integer.MAX_VALUE; + Node next; + + public Node(int val, int min, Node head) { + this.val = val; + this.min = min; + this.next = head; + } +} + +class MinsStackWithOneStack { + // data stack + Stack stack = new Stack<>(); + int min = Integer.MAX_VALUE; + + /* + if x <= min, then push min, and set min = x; + */ + public void push(int x) { + if (x <= min) { + stack.push(min); + min = x; + } + + stack.push(x); + } + + public void pop() { + if (stack.pop() == min) { + min = stack.pop(); + } + } + + public int top() { + return stack.peek(); + } + + public int getMin() { + return min; + } +} + +public class MinStack { + // data stack + Stack dataStack; + // min stack + Stack minStack; + + /** initialize your data structure here. */ + public MinStack() { + dataStack = new Stack<>(); + minStack = new Stack<>(); + } + + public void push(int x) { + dataStack.push(x); + if (minStack.size() == 0 || minStack.peek() >= x) { + minStack.push(x); + } + } + + public void pop() { + if (dataStack.size() > 0) { + int d = dataStack.pop(); + if (minStack.size() > 0 && minStack.peek() == d) { + minStack.pop(); + } + } + + } + + public int top() { + if (dataStack.size() > 0) { + return dataStack.peek(); + } + // data is empty + return -1; + } + + public int getMin() { + if (minStack.size() > 0) { + return minStack.peek(); + } + + // data is empty + return -1; + } +} + From 3ff5c0b89f7aa43e352aaa643176b171f57e1ae7 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 25 Jun 2019 12:47:35 +0800 Subject: [PATCH 085/162] linked list cycle --- code/LeetCode/src/node/LinkedListCycle.java | 37 +++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 code/LeetCode/src/node/LinkedListCycle.java diff --git a/code/LeetCode/src/node/LinkedListCycle.java b/code/LeetCode/src/node/LinkedListCycle.java new file mode 100644 index 00000000..aae1163e --- /dev/null +++ b/code/LeetCode/src/node/LinkedListCycle.java @@ -0,0 +1,37 @@ +package node; + +import common.ListNode; + +import java.util.HashSet; +import java.util.Set; + +// https://leetcode.com/problems/linked-list-cycle/ +public class LinkedListCycle { + + public boolean hasCycle(ListNode head) { + ListNode fast = head; + ListNode slow = head; + do { + if (fast == null || fast.next == null) { + return false; + } + fast = fast.next.next; + slow = slow.next; + } while (fast != slow); + + return true; + } + + public boolean hasCycleWithSet(ListNode head) { + Set set = new HashSet<>(); + while (head != null) { + if (set.contains(head)) { + return true; + } + set.add(head); + head = head.next; + } + + return false; + } +} From 96f1c62a76e56f6694f2bb7b4c692dbbb1d24a95 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Wed, 26 Jun 2019 12:38:16 +0800 Subject: [PATCH 086/162] single number --- code/LeetCode/src/array/SingleNumber.java | 31 +++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 code/LeetCode/src/array/SingleNumber.java diff --git a/code/LeetCode/src/array/SingleNumber.java b/code/LeetCode/src/array/SingleNumber.java new file mode 100644 index 00000000..b65ed79f --- /dev/null +++ b/code/LeetCode/src/array/SingleNumber.java @@ -0,0 +1,31 @@ +package array; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +// https://leetcode.com/problems/single-number/ +public class SingleNumber { + public int singleNumber(int[] nums) { + Set set = new HashSet<>(); + for (int n: nums) { + if (set.contains(n)) { + set.remove(n); + } else { + set.add(n); + } + } + + return (int)set.toArray()[0]; + } + + public int singleNumberWithBit(int[] nums) { + int result = 0; + for (int n: nums) { + result ^= n; + } + + return result; + } +} From 3ca1c17142d195e9c4fb8f51bf5aa6ef368db01e Mon Sep 17 00:00:00 2001 From: zgpeace Date: Thu, 27 Jun 2019 15:31:36 +0800 Subject: [PATCH 087/162] valid palindrome --- code/LeetCode/src/String/ValidPalindrome.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 code/LeetCode/src/String/ValidPalindrome.java diff --git a/code/LeetCode/src/String/ValidPalindrome.java b/code/LeetCode/src/String/ValidPalindrome.java new file mode 100644 index 00000000..51d1d13c --- /dev/null +++ b/code/LeetCode/src/String/ValidPalindrome.java @@ -0,0 +1,41 @@ +package String; + +// https://leetcode.com/problems/valid-palindrome/ +public class ValidPalindrome { + + public static boolean isPalindrome(String s) { + if (s.isEmpty()) { + return true; + } + int head = 0, tail = s.length() - 1; + char cHead, cTail; + while(head <= tail) { + cHead = s.charAt(head); + cTail = s.charAt(tail); + if (!Character.isLetterOrDigit(cHead)) { + head++; + } else if(!Character.isLetterOrDigit(cTail)) { + tail--; + } else { + if (Character.toLowerCase(cHead) != Character.toLowerCase(cTail)) { + return false; + } + head++; + tail--; + } + } + + return true; + } + + public static boolean isPalindromeWithReverse(String s) { + String lower = s.replaceAll("[^A-Za-z0-9]", "").toLowerCase(); + String reverse = new StringBuilder(lower).reverse().toString(); + return lower.equals(reverse); + } + + + public static void main(String[] args) { + System.out.println("result: " + isPalindrome("0P")); + } +} From ee9e698a24d9431b5a27e566e160f6e0cc13ead7 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 2 Jul 2019 12:34:32 +0800 Subject: [PATCH 088/162] best time to buy and sell stock ii --- .../src/dp/BestTimeToBuyAndSellStockII.java | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 code/LeetCode/src/dp/BestTimeToBuyAndSellStockII.java diff --git a/code/LeetCode/src/dp/BestTimeToBuyAndSellStockII.java b/code/LeetCode/src/dp/BestTimeToBuyAndSellStockII.java new file mode 100644 index 00000000..466e106b --- /dev/null +++ b/code/LeetCode/src/dp/BestTimeToBuyAndSellStockII.java @@ -0,0 +1,79 @@ +package dp; + +// https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ +public class BestTimeToBuyAndSellStockII { + public int maxProfit(int[] prices) { + int profit = 0; + for (int i = 1; i < prices.length; i++) { + if (prices[i] > prices[i - 1]) { + profit += prices[i] - prices[i - 1]; + } + } + + return profit; + } + + public static int maxProfitWithBruteForce(int[] prices) { + return calculate(prices, 0); + } + + public static int calculate(int[] prices, int start) { + if (start >= prices.length) { + return 0; + } + // max profit + int max = 0; + // loop from start + for (int i = start; i < prices.length; i++) { + // current max; + int maxProfit = 0; + + // loop after start + for (int k = i + 1; k < prices.length; k++) { + // current > start ,then two way: sell stock or keep + if (prices[k] > prices[i]) { + int profit = prices[k] - prices[i] + calculate(prices, k + 1); + if (profit > maxProfit) { + maxProfit = profit; + } + } + } + + if (maxProfit > max) { + max = maxProfit; + } + } + + return max; + } + + public static int maxProfitWithValleyAndPeak(int[] prices) { + if (prices.length <= 0) { + return 0; + } + int max = 0; + int valley; + int peak; + int i = 0; + while (i < prices.length - 1) { + // find the valley index + while (i < prices.length - 1 && prices[i] >= prices[i + 1]) { + i++; + } + valley = prices[i]; + // find the peak index + while (i < prices.length - 1 && prices[i] <= prices[i + 1]) { + i++; + } + peak = prices[i]; + max += peak - valley; + } + + return max; + } + + public static void main(String[] args) { + int result = maxProfitWithValleyAndPeak(new int[]{1,2,3,4,5}); + System.out.println("result: " + result); + } +} From e49749a055ab844adf9fad9c7850c02828c3e033 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Wed, 3 Jul 2019 12:51:04 +0800 Subject: [PATCH 089/162] best time to buy and sell stock --- .../src/dp/BestTimeToBuyAndSellStock.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 code/LeetCode/src/dp/BestTimeToBuyAndSellStock.java diff --git a/code/LeetCode/src/dp/BestTimeToBuyAndSellStock.java b/code/LeetCode/src/dp/BestTimeToBuyAndSellStock.java new file mode 100644 index 00000000..0569530b --- /dev/null +++ b/code/LeetCode/src/dp/BestTimeToBuyAndSellStock.java @@ -0,0 +1,39 @@ +package dp; + +// https://leetcode.com/problems/best-time-to-buy-and-sell-stock/ +public class BestTimeToBuyAndSellStock { + public int maxProfit(int[] prices) { + int max = 0; + int profit; + for (int i = 0; i < prices.length; i++) { + for (int k = i + 1; k < prices.length; k++) { + profit = prices[k] - prices[i]; + if (profit > max) { + max = profit; + } + } + } + + return max; + } + + public int maxProfitWithOnePass(int[] prices) { + if (prices.length <= 0) { + return 0; + } + int max = 0; + int valley = prices[0]; + int gap; + for (int p: prices) { + if (valley > p) { + valley = p; + } + gap = p - valley; + if (max < gap) { + max = gap; + } + } + + return max; + } +} From 827414935af62d8a484c7766f47a9ff225d369af Mon Sep 17 00:00:00 2001 From: zgpeace Date: Thu, 4 Jul 2019 12:47:34 +0800 Subject: [PATCH 090/162] pascals triangle --- code/LeetCode/src/array/PascalsTriangle.java | 30 ++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 code/LeetCode/src/array/PascalsTriangle.java diff --git a/code/LeetCode/src/array/PascalsTriangle.java b/code/LeetCode/src/array/PascalsTriangle.java new file mode 100644 index 00000000..9acba35a --- /dev/null +++ b/code/LeetCode/src/array/PascalsTriangle.java @@ -0,0 +1,30 @@ +package array; + +import java.util.ArrayList; +import java.util.List; + +// https://leetcode.com/problems/pascals-triangle/ +public class PascalsTriangle { + + public List> generate(int numRows) { + List> result = new ArrayList<>(); + for (int i = 1; i <= numRows; i++) { + // current list + List current = new ArrayList<>(); + // pre list + List pre = i == 1 ? null : result.get(i - 1 - 1); + for (int k = 0; k < i; k++) { + if (k == 0 || k == i - 1) { + current.add(1); + } else { + current.add(pre.get(k - 1) + pre.get(k)); + } + } + + // add current list to result + result.add(current); + } + + return result; + } +} From 40e49a2d003d1c85f6749f8c492354b6340cc80e Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 9 Jul 2019 12:49:38 +0800 Subject: [PATCH 091/162] convert sorted array to binary search tree --- code/LeetCode/src/tree/ConvertSortedArrayToBinarySearchTree.java | 1 + 1 file changed, 1 insertion(+) diff --git a/code/LeetCode/src/tree/ConvertSortedArrayToBinarySearchTree.java b/code/LeetCode/src/tree/ConvertSortedArrayToBinarySearchTree.java index c7b718ad..8e816927 100644 --- a/code/LeetCode/src/tree/ConvertSortedArrayToBinarySearchTree.java +++ b/code/LeetCode/src/tree/ConvertSortedArrayToBinarySearchTree.java @@ -3,6 +3,7 @@ import common.TreeNode; import java.util.LinkedList; +import java.util.Queue; /** * Definition for a binary tree node. From 5b5b9eeb540bc640a2a14129d288d88b20d6c098 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 9 Jul 2019 12:49:51 +0800 Subject: [PATCH 092/162] maximum depth of binary tree --- .../src/tree/MaximumDepthOfBinaryTree.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 code/LeetCode/src/tree/MaximumDepthOfBinaryTree.java diff --git a/code/LeetCode/src/tree/MaximumDepthOfBinaryTree.java b/code/LeetCode/src/tree/MaximumDepthOfBinaryTree.java new file mode 100644 index 00000000..9d7866a0 --- /dev/null +++ b/code/LeetCode/src/tree/MaximumDepthOfBinaryTree.java @@ -0,0 +1,43 @@ +package tree; + +import common.TreeNode; + +import java.util.LinkedList; +import java.util.Queue; + +// https://leetcode.com/problems/maximum-depth-of-binary-tree/ +public class MaximumDepthOfBinaryTree { + + public int maxDepthWithDFS(TreeNode root) { + if (root == null) { + return 0; + } + return Math.max(maxDepthWithDFS(root.left), maxDepthWithDFS(root.right)) + 1; + } + + public int maxDepthWithBFS(TreeNode root) { + int max = 0; + if (root == null) { + return max; + } + Queue queue = new LinkedList<>(); + queue.add(root); + TreeNode current; + while (!queue.isEmpty()) { + max++; + int count = queue.size(); + for (int i = 0; i < count; i++) { + current = queue.poll(); + if (current.left != null) { + queue.add(current.left); + } + + if (current.right != null) { + queue.add(current.right); + } + } + } + + return max; + } +} From 9997bece4b83da31712330a9a893010b551004af Mon Sep 17 00:00:00 2001 From: zgpeace Date: Wed, 10 Jul 2019 14:20:30 +0800 Subject: [PATCH 093/162] symmetric tree --- code/LeetCode/src/tree/SymmetricTree.java | 53 +++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 code/LeetCode/src/tree/SymmetricTree.java diff --git a/code/LeetCode/src/tree/SymmetricTree.java b/code/LeetCode/src/tree/SymmetricTree.java new file mode 100644 index 00000000..ce5d3076 --- /dev/null +++ b/code/LeetCode/src/tree/SymmetricTree.java @@ -0,0 +1,53 @@ +package tree; + +import common.TreeNode; + +import java.util.LinkedList; +import java.util.Queue; + +// https://leetcode.com/problems/symmetric-tree/ +public class SymmetricTree { + + public boolean isSymmetricWithRecursive(TreeNode root) { + return isMirror(root, root); + } + + public boolean isMirror(TreeNode leftN, TreeNode rightN) { + if (leftN == null && rightN == null) { + return true; + } + if (leftN == null || rightN == null) { + return false; + } + return leftN.val == rightN.val + && isMirror(leftN.left, rightN.right) + && isMirror(leftN.right, rightN.left); + } + + public boolean isSymmetric(TreeNode root) { + Queue queue = new LinkedList<>(); + queue.add(root); + queue.add(root); + while (!queue.isEmpty()) { + TreeNode leftN = queue.poll(); + TreeNode rightN = queue.poll(); + if (leftN == null && rightN == null) { + continue; + } + if (leftN == null || rightN == null) { + return false; + } + if(leftN.val != rightN.val) { + return false; + } + + queue.add(leftN.left); + queue.add(rightN.right); + + queue.add(leftN.right); + queue.add(rightN.left); + } + + return true; + } +} From 67dca084acd2de4ad0c8257fd6984ed66f8406b2 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Thu, 11 Jul 2019 14:48:36 +0800 Subject: [PATCH 094/162] validate binary search tree --- .../src/tree/ValidateBinarySearchTree.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 code/LeetCode/src/tree/ValidateBinarySearchTree.java diff --git a/code/LeetCode/src/tree/ValidateBinarySearchTree.java b/code/LeetCode/src/tree/ValidateBinarySearchTree.java new file mode 100644 index 00000000..2375442a --- /dev/null +++ b/code/LeetCode/src/tree/ValidateBinarySearchTree.java @@ -0,0 +1,30 @@ +package tree; + +import common.TreeNode; + +// https://leetcode.com/problems/validate-binary-search-tree/ +public class ValidateBinarySearchTree { + + public boolean isValidBST(TreeNode root) { + if (root == null) { + return true; + } + + return isValidBSTWithLowerAndUpper(root, null, null); + } + + public boolean isValidBSTWithLowerAndUpper(TreeNode root, Integer lower, Integer upper) { + if (root == null) { + return true; + } + if (lower != null && root.val <= lower) { + return false; + } + if (upper != null && root.val >= upper) { + return false; + } + + + return isValidBSTWithLowerAndUpper(root.left, lower, root.val) && isValidBSTWithLowerAndUpper(root.right, root.val, upper); + } +} From a2b16edc7efb4bd07850cdec04e1e8dd151f8569 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 16 Jul 2019 09:59:47 +0800 Subject: [PATCH 095/162] validate binary search tree with iterate --- .../src/tree/ValidateBinarySearchTree.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/code/LeetCode/src/tree/ValidateBinarySearchTree.java b/code/LeetCode/src/tree/ValidateBinarySearchTree.java index 2375442a..b8f1b685 100644 --- a/code/LeetCode/src/tree/ValidateBinarySearchTree.java +++ b/code/LeetCode/src/tree/ValidateBinarySearchTree.java @@ -2,6 +2,9 @@ import common.TreeNode; +import java.util.LinkedList; +import java.util.Queue; + // https://leetcode.com/problems/validate-binary-search-tree/ public class ValidateBinarySearchTree { @@ -27,4 +30,45 @@ public boolean isValidBSTWithLowerAndUpper(TreeNode root, Integer lower, Integer return isValidBSTWithLowerAndUpper(root.left, lower, root.val) && isValidBSTWithLowerAndUpper(root.right, root.val, upper); } + + public boolean isValidBSTWithIterate(TreeNode root) { + if (root == null) { + return true; + } + Queue queue = new LinkedList<>(); + queue.add(root); + Queue valleyQueue = new LinkedList<>(); + valleyQueue.add(null); + Queue peakQueue = new LinkedList<>(); + peakQueue.add(null); + TreeNode current; + Integer valley; + Integer peak; + while (!queue.isEmpty()) { + current = queue.poll(); + valley = valleyQueue.poll(); + peak = peakQueue.poll(); + if (valley != null && current.val <= valley) { + return false; + } + if (peak != null && current.val >= peak) { + return false; + } + + if (current.left != null) { + queue.add(current.left); + valleyQueue.add(valley); + peakQueue.add(current.val); + } + + if (current.right != null) { + queue.add(current.right); + valleyQueue.add(current.val); + peakQueue.add(peak); + } + + } + + return true; + } } From 683340a678f9b1b3d116a1323b74f4889ab414dd Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 16 Jul 2019 09:59:59 +0800 Subject: [PATCH 096/162] merge sorted array --- code/LeetCode/src/array/MergeSortedArray.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 code/LeetCode/src/array/MergeSortedArray.java diff --git a/code/LeetCode/src/array/MergeSortedArray.java b/code/LeetCode/src/array/MergeSortedArray.java new file mode 100644 index 00000000..a7848121 --- /dev/null +++ b/code/LeetCode/src/array/MergeSortedArray.java @@ -0,0 +1,23 @@ +package array; + +// https://leetcode.com/problems/merge-sorted-array/ +public class MergeSortedArray { + public static void merge(int[] nums1, int m, int[] nums2, int n) { + int index = n + m - 1; + int oneIndex = m - 1; + int twoIndex = n - 1; + while (oneIndex >= 0 && twoIndex >= 0) { + nums1[index--] = nums1[oneIndex] > nums2[twoIndex] ? nums1[oneIndex--] : nums2[twoIndex--]; + } + while (index >= 0) { + nums1[index--] = oneIndex >= 0 ? nums1[oneIndex--] : nums2[twoIndex--]; + } + } + + public static void main(String[] args) { + int[] nums1 = {2, 0}; + int[] nums2 = {1}; + + merge(nums1, 1, nums2, 1); + } +} From 2510f060c33c1182bf8945d0df06a7a04730a60a Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 16 Jul 2019 10:04:01 +0800 Subject: [PATCH 097/162] // nums2 is not empty, need to fill in; nums1 is content itself, no need to change --- code/LeetCode/src/array/MergeSortedArray.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/LeetCode/src/array/MergeSortedArray.java b/code/LeetCode/src/array/MergeSortedArray.java index a7848121..5eddb526 100644 --- a/code/LeetCode/src/array/MergeSortedArray.java +++ b/code/LeetCode/src/array/MergeSortedArray.java @@ -6,11 +6,13 @@ public static void merge(int[] nums1, int m, int[] nums2, int n) { int index = n + m - 1; int oneIndex = m - 1; int twoIndex = n - 1; + // big --> small, descending while (oneIndex >= 0 && twoIndex >= 0) { nums1[index--] = nums1[oneIndex] > nums2[twoIndex] ? nums1[oneIndex--] : nums2[twoIndex--]; } - while (index >= 0) { - nums1[index--] = oneIndex >= 0 ? nums1[oneIndex--] : nums2[twoIndex--]; + // nums2 is not empty, need to fill in; nums1 is content itself, no need to change + while (twoIndex >= 0) { + nums1[index--] = nums2[twoIndex--]; } } From deef29e8f4a739fa3c593eb476e2ca917cc86dd7 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 16 Jul 2019 12:42:57 +0800 Subject: [PATCH 098/162] climbing stairs --- code/LeetCode/src/dp/ClimbingStairs.java | 57 ++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 code/LeetCode/src/dp/ClimbingStairs.java diff --git a/code/LeetCode/src/dp/ClimbingStairs.java b/code/LeetCode/src/dp/ClimbingStairs.java new file mode 100644 index 00000000..ce4cc78d --- /dev/null +++ b/code/LeetCode/src/dp/ClimbingStairs.java @@ -0,0 +1,57 @@ +package dp; + +import java.util.Arrays; + +// https://leetcode.com/problems/climbing-stairs/ +public class ClimbingStairs { + + int[] memo = null; + // recursive : problem > Time Limit Exceeded + public int climbStairs(int n) { + if (memo == null) { + memo = new int[n + 1]; + Arrays.fill(memo, -1); + } + if (n == 1 || n == 0) { + return 1; + } + + if (memo[n] != -1) { + return memo[n]; + } + memo[n] = climbStairs(n - 1) + climbStairs(n - 2); + return memo[n]; + } + + // Fibonacci + public int climbStairsWithFibonacci(int n) { + if (n == 0 || n == 1) { + return 1; + } + int pre = 1; + int current = 1; + int temp; + for (int i = 2; i <= n; i++) { + temp = pre + current; + pre = current; + current = temp; + } + + return current; + } + + // dynamic program + public int climbStairsWithDP(int n) { + if (n == 1 || n == 0) { + 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]; + } + + return dp[n]; + } +} From 4d0f281527210eb8cd6a8403ecb8c97f17b03362 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 2 Aug 2019 12:41:40 +0800 Subject: [PATCH 099/162] count and say --- code/LeetCode/src/array/CountAndSay.java | 87 ++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 code/LeetCode/src/array/CountAndSay.java diff --git a/code/LeetCode/src/array/CountAndSay.java b/code/LeetCode/src/array/CountAndSay.java new file mode 100644 index 00000000..67e9a772 --- /dev/null +++ b/code/LeetCode/src/array/CountAndSay.java @@ -0,0 +1,87 @@ +package array; + +import java.awt.*; +import java.util.LinkedList; +import java.util.Queue; + +// https://leetcode.com/problems/count-and-say/ +public class CountAndSay { + public String countAndSay(int n) { + if (n == 0) { + return "1"; + } + Queue queue = new LinkedList<>(); + queue.add(1); + int size; + Integer pre = null; + int count = 1; + Integer current; + for (int i = 2; i <= n; i++) { + size = queue.size(); + for (int k = 0; k < size; k++) { + current = queue.poll(); + if (pre == current) { + count++; + } else { + if (pre != null) { + queue.add(count); + queue.add(pre); + } + + // reset date + pre = current; + count = 1; + } + } + // add last + queue.add(count); + queue.add(pre); + + // reset pre && count + pre = null; + count = 1; + } + + int l; + StringBuilder sb = new StringBuilder(); + while (!queue.isEmpty()) { + l = queue.poll(); + sb.append(Integer.toString(l)); + } + + return sb.toString(); + } + + public String countAndSayWithRecursive(int n) { + String s = "1"; + for (int i = 1; i < n; i++) { + s = countIdx(s); + } + + return s; + } + + public String countIdx(String s) { + StringBuilder sb = new StringBuilder(); + char c = s.charAt(0); + int count = 1; + for (int i = 1; i < s.length(); i++) { + if (s.charAt(i) == c) { + count++; + } else { + sb.append(count); + sb.append(c); + + c = s.charAt(i); + count = 1; + } + } + + sb.append(count); + sb.append(c); + return sb.toString(); + } + + + +} From 246a240fdccb82dd2abe0b90f16658f3d656896c Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 2 Aug 2019 12:41:52 +0800 Subject: [PATCH 100/162] maximum subarray --- code/LeetCode/src/array/MaximumSubarray.java | 33 ++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 code/LeetCode/src/array/MaximumSubarray.java diff --git a/code/LeetCode/src/array/MaximumSubarray.java b/code/LeetCode/src/array/MaximumSubarray.java new file mode 100644 index 00000000..f85a778a --- /dev/null +++ b/code/LeetCode/src/array/MaximumSubarray.java @@ -0,0 +1,33 @@ +package array; + +// https://leetcode.com/problems/maximum-subarray/ +public class MaximumSubarray { + + public int maxSubArrayWithDP(int[] nums) { + int[] dp = new int[nums.length + 1]; + dp[0] = nums[0]; + int max = dp[0]; + for (int i = 1; i < nums.length; i++) { + dp[i] = dp[i - 1] > 0 ? dp[i - 1] + nums[i] : nums[i]; + max = dp[i] > max ? dp[i] : max; + } + + return max; + } + + public int maxSubArray(int[] nums) { + if (nums.length <= 0) { + return 0; + } + int sum = 0; + int max = nums[0]; + for (int i = 0; i < nums.length; i++) { + sum = sum > 0 ? sum + nums[i] : nums[i]; + if (sum > max) { + max = sum; + } + } + + return max; + } +} From 3dff0e9525d04b5e017a3e66b4928cb3b40cfc73 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 2 Aug 2019 12:41:58 +0800 Subject: [PATCH 101/162] plus one --- code/LeetCode/src/array/PlusOne.java | 53 ++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 code/LeetCode/src/array/PlusOne.java diff --git a/code/LeetCode/src/array/PlusOne.java b/code/LeetCode/src/array/PlusOne.java new file mode 100644 index 00000000..70502f77 --- /dev/null +++ b/code/LeetCode/src/array/PlusOne.java @@ -0,0 +1,53 @@ +package array; + +import java.util.ArrayList; +import java.util.List; + +// https://leetcode.com/problems/plus-one/ +public class PlusOne { + + public int[] plusOneChangeSource(int[] digits) { + int len = digits.length; + for (int i = len - 1; i >= 0; i--) { + if (digits[i] < 9) { + digits[i]++; + return digits; + } + + digits[i] = 0; + } + + int[] result = new int[len + 1]; + result[0] = 1; + + return result; + } + + public int[] plusOne(int[] digits) { + List list = new ArrayList<>(); + int carry = 1; + int sum; + for (int i = digits.length - 1; i >= 0; i--) { + if (carry == 0) { + list.add(0, digits[i]); + continue; + } + + sum = digits[i] + carry; + carry = sum / 10; + digits[i] = sum % 10; + list.add(0, digits[i]); + } + // carry is 1, add one in the first + if (carry == 1) { + list.add(0, 1); + } + + int[] result = new int[list.size()]; + for (int i = 0; i < list.size(); i++) { + result[i] = list.get(i); + } + + return result; + } +} From dd06246cdf38af8ff10e60375b8de9d328ffa665 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 2 Aug 2019 12:42:12 +0800 Subject: [PATCH 102/162] remove duplicates from sorted array --- .../RemoveDuplicatesFromSortedArray.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 code/LeetCode/src/array/RemoveDuplicatesFromSortedArray.java diff --git a/code/LeetCode/src/array/RemoveDuplicatesFromSortedArray.java b/code/LeetCode/src/array/RemoveDuplicatesFromSortedArray.java new file mode 100644 index 00000000..c51a7b05 --- /dev/null +++ b/code/LeetCode/src/array/RemoveDuplicatesFromSortedArray.java @@ -0,0 +1,22 @@ +package array; + +// https://leetcode.com/problems/remove-duplicates-from-sorted-array/ +public class RemoveDuplicatesFromSortedArray { + public int removeDuplicates(int[] nums) { + if (nums.length == 0) { + return 0; + } + int current = nums[0]; + int count = 1; + + for (int i = 1; i < nums.length; i++) { + if (current != nums[i]) { + nums[count] = nums[i]; + current = nums[i]; + count++; + } + } + + return count; + } +} From d635c5bb5f885878eda00c50736999d63e401761 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 2 Aug 2019 12:42:18 +0800 Subject: [PATCH 103/162] sqrtx --- code/LeetCode/src/binarysearch/Sqrtx.java | 31 +++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 code/LeetCode/src/binarysearch/Sqrtx.java diff --git a/code/LeetCode/src/binarysearch/Sqrtx.java b/code/LeetCode/src/binarysearch/Sqrtx.java new file mode 100644 index 00000000..117ba496 --- /dev/null +++ b/code/LeetCode/src/binarysearch/Sqrtx.java @@ -0,0 +1,31 @@ +package binarysearch; + +// https://leetcode.com/problems/sqrtx/ +public class Sqrtx { + + public static int mySqrt(int x) { + if (x == 1 || x == 0) { + return x; + } + int left = 0; + int right = x; + int mid; + while (left < right) { + mid = left + ((right - left) >> 1); + if (mid > x / mid) { + right = mid - 1; + } else { + if ((mid + 1) > x / (mid + 1)) { + return mid; + } + left = mid + 1; + } + } + + return left; + } + + public static void main(String[] args) { + mySqrt(10); + } +} From 8bf660d91b79666728661a9869ae21449701761b Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 2 Aug 2019 12:42:30 +0800 Subject: [PATCH 104/162] merge two sorted lists --- .../src/node/MergeTwoSortedLists.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 code/LeetCode/src/node/MergeTwoSortedLists.java diff --git a/code/LeetCode/src/node/MergeTwoSortedLists.java b/code/LeetCode/src/node/MergeTwoSortedLists.java new file mode 100644 index 00000000..1017af54 --- /dev/null +++ b/code/LeetCode/src/node/MergeTwoSortedLists.java @@ -0,0 +1,55 @@ +package node; + +import common.ListNode; + +// https://leetcode.com/problems/merge-two-sorted-lists/ +public class MergeTwoSortedLists { + + public ListNode mergeTwoLists(ListNode l1, ListNode l2) { + ListNode list = new ListNode(0); + ListNode head = list; + while (l1 != null && l2 != null) { + if (l1.val < l2.val) { + list.next = new ListNode(l1.val); + l1 = l1.next; + } else { + list.next = new ListNode(l2.val); + l2 = l2.next; + } + list = list.next; + + } + + while (l1 != null) { + list.next = new ListNode(l1.val); + list = list.next; + l1 = l1.next; + } + + while (l2 != null) { + list.next = new ListNode(l2.val); + list = list.next; + l2 = l2.next; + } + + return head.next; + } + + + public ListNode mergeTwoListsWithRecursive(ListNode l1, ListNode l2) { + if (l1 == null) { + return l2; + } + if (l2 == null) { + return l1; + } + if (l1.val < l2.val) { + l1.next = mergeTwoListsWithRecursive(l1.next, l2); + return l1; + } else { + l2.next = mergeTwoListsWithRecursive(l1, l2.next); + return l2; + } + } + +} From 2a2baf789b8a1816084b1a5602b35103a734ed6b Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 2 Aug 2019 12:42:40 +0800 Subject: [PATCH 105/162] valid parentheses --- code/LeetCode/src/stack/ValidParentheses.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 code/LeetCode/src/stack/ValidParentheses.java diff --git a/code/LeetCode/src/stack/ValidParentheses.java b/code/LeetCode/src/stack/ValidParentheses.java new file mode 100644 index 00000000..dd7aa712 --- /dev/null +++ b/code/LeetCode/src/stack/ValidParentheses.java @@ -0,0 +1,34 @@ +package stack; + +import java.util.HashMap; +import java.util.Map; +import java.util.Stack; + +// https://leetcode.com/problems/valid-parentheses/ +public class ValidParentheses { + public boolean isValid(String s) { + Map map = new HashMap<>(); + map.put(']', '['); + map.put('}', '{'); + map.put(')', '('); + Stack stack = new Stack<>(); + for (char c: s.toCharArray()) { + if (c == '[' || c == '(' || c == '{') { + stack.push(c); + continue; + } + + if (stack.isEmpty()) { + return false; + } + + char pre = stack.pop(); + if (map.get(c) != pre) { + return false; + } + } + + return stack.isEmpty(); + } + +} From 1ebf6a77c2319fc3eeaf09b37a1fc27fde9e8fb7 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 2 Aug 2019 12:42:49 +0800 Subject: [PATCH 106/162] implement str str --- code/LeetCode/src/String/ImplementStrStr.java | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 code/LeetCode/src/String/ImplementStrStr.java diff --git a/code/LeetCode/src/String/ImplementStrStr.java b/code/LeetCode/src/String/ImplementStrStr.java new file mode 100644 index 00000000..cb01526e --- /dev/null +++ b/code/LeetCode/src/String/ImplementStrStr.java @@ -0,0 +1,62 @@ +package String; + +// https://leetcode.com/problems/implement-strstr/ +public class ImplementStrStr { + + public int strStr(String haystack, String needle) { + if (haystack.length() == 0 && needle.length() == 0) { + return 0; + } + if (haystack.length() == 0 || needle.length() == 0 || haystack.length() < needle.length()) { + return -1; + } + + for (int i = 0; i <= haystack.length() - needle.length(); i++) { + for (int k = 0; k < needle.length(); k++) { + if (haystack.charAt(i + k) != needle.charAt(k)) { + break; + } + + if (k == needle.length() - 1) { + return i; + } + } + } + + return -1; + } + + public int strStrWithEqual(String haystack, String needle) { + int hayLen = haystack.length(); + int needleLen = needle.length(); + if (needleLen == 0) { + return 0; + } else if (hayLen < needleLen) { + return -1; + } + int zoom = hayLen - needleLen; + for (int i = 0; i <= zoom; i++) { + if (haystack.substring(i, i + needleLen).equals(needle)) { + return i; + } + } + + return -1; + } + + public int strStrElegant(String haystack, String needle) { + for (int i = 0; ; i++) { + for (int k = 0; ; k++) { + if (k == needle.length()) { + return i; + } + if (i + k == haystack.length()) { + return -1; + } + if (haystack.charAt(i + k) != needle.charAt(k)) { + break; + } + } + } + } +} From 931eedf175b20afbac8176ae62d9ba9fee36b834 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 19 Aug 2019 12:44:03 +0800 Subject: [PATCH 107/162] Longest common prefix --- .../src/array/LongestCommonPrefix.java | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 code/LeetCode/src/array/LongestCommonPrefix.java diff --git a/code/LeetCode/src/array/LongestCommonPrefix.java b/code/LeetCode/src/array/LongestCommonPrefix.java new file mode 100644 index 00000000..5381ed7b --- /dev/null +++ b/code/LeetCode/src/array/LongestCommonPrefix.java @@ -0,0 +1,146 @@ +package array; + +// https://leetcode.com/problems/longest-common-prefix/ +public class LongestCommonPrefix { + + public String longestCommonPrefix(String[] strs) { + // edge trecking + if (strs.length == 0) { + return ""; + } else if (strs.length == 1) { + return strs[0]; + } + // find short string + String shortString = strs[0]; + for (int i = 1; i < strs.length; i++) { + if (strs[i].length() < shortString.length()) { + shortString = strs[i]; + } + } + + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < shortString.length(); i++) { + char c = shortString.charAt(i); + for (int k = 0; k < strs.length; k++) { + if (c != strs[k].charAt(i)) { + return sb.toString(); + } + + if (k == strs.length - 1) { + sb.append(c); + } + } + } + + return sb.toString(); + } + + public static void main(String[] args) { + String[] strs = {"flower","flow","flight"}; + longestCommonPrefixWithBinarySearch(strs); + } + + public static String longestCommonPrefixWithBinarySearch(String[] strs) { + if (strs == null || strs.length == 0) { + return ""; + } else if(strs.length == 1) { + return strs[0]; + } + int minLen = strs[0].length(); + for (int i = 1; i < strs.length; i++) { + if (strs[i].length() < minLen) { + minLen = strs[i].length(); + } + } + int left = 1; + int right = minLen; + int mid; + while (left <= right) { + mid = left + ((right - left) >> 1); + if (isCommonPre(strs, mid)) { + left = mid + 1; + } else { + right = mid - 1; + } + } + + return strs[0].substring(0, (left + ((right - left) >> 1) )); + } + + public static boolean isCommonPre(String[] strs, int len) { + String preString = strs[0].substring(0, len); + for (int i = 1; i < strs.length; i++) { + if (strs[i].indexOf(preString) != 0) { + return false; + } + } + + return true; + } + + public String longestCommonPrefixWithDivideConque(String[] strs) { + if (strs.length == 0) { + return ""; + } + + return longestCommonPrefixWithDivideConque(strs, 0, strs.length - 1); + } + + public String longestCommonPrefixWithDivideConque(String[] strs, int left, int right) { + if (left == right) { + return strs[left]; + } + + int mid = left + ((right - left) >> 1); + String commonLeft = longestCommonPrefixWithDivideConque(strs, left, mid); + String commonRight = longestCommonPrefixWithDivideConque(strs, mid + 1, right); + + return commonBetweenTwoString(commonLeft, commonRight); + } + + public String commonBetweenTwoString(String s1, String s2) { + int minLen = Math.min(s1.length(), s2.length()); + for (int i = 0; i < minLen; i++) { + if (s1.charAt(i) != s2.charAt(i)) { + return s1.substring(0, i); + } + } + + return s1.substring(0, minLen); + } + + + public String longestCommonPrefixWithVerticalScan(String[] strs) { + if (strs.length == 0) { + return ""; + } + for (int i = 0; i < strs[0].length(); i++) { + char c = strs[0].charAt(i); + for (int k = 1; k < strs.length; k++) { + if (i == strs[k].length() || c != strs[k].charAt(i)) { + return strs[0].substring(0, i); + } + } + } + + return strs[0]; + } + + public String longestCommonPrefixWithHorizontalScan(String[] strs) { + if (strs.length == 0) { + return ""; + } + String pre = strs[0]; + for (int i = 1; i < strs.length; i++) { + while (strs[i].indexOf(pre) != 0) { + pre = pre.substring(0, pre.length() - 1); + if (pre.isEmpty()) { + return ""; + } + } + } + + return pre; + } +} From 603a58d7d753812a9827b7748ec4fdfcf4dd3fcf Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 19 Aug 2019 12:44:14 +0800 Subject: [PATCH 108/162] add two numbers --- code/LeetCode/src/node/AddTwoNumbers.java | 64 +++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 code/LeetCode/src/node/AddTwoNumbers.java diff --git a/code/LeetCode/src/node/AddTwoNumbers.java b/code/LeetCode/src/node/AddTwoNumbers.java new file mode 100644 index 00000000..eb47bee0 --- /dev/null +++ b/code/LeetCode/src/node/AddTwoNumbers.java @@ -0,0 +1,64 @@ +package node; + +import common.ListNode; + +// https://leetcode.com/problems/add-two-numbers/ +public class AddTwoNumbers { + public ListNode addTwoNumbersWithTidyStyle(ListNode l1, ListNode l2) { + ListNode dummyHead = new ListNode(0); + ListNode current = dummyHead; + int carry = 0; + int sum; + while (l1 != null || l2 != null) { + sum = (l1 != null ? l1.val : 0) + (l2 != null ? l2.val : 0) + carry; + current.next = new ListNode(sum % 10); + carry = sum / 10; + l1 = l1 != null ? l1.next : l1; + l2 = l2 != null ? l2.next : l2; + current = current.next; + } + if (carry == 1) { + current.next = new ListNode(1); + } + + return dummyHead.next; + } + + public ListNode addTwoNumbers(ListNode l1, ListNode l2) { + ListNode head = new ListNode(0); + ListNode result = head; + int carry = 0; + int sum; + // sum for every two Node's value, mark carry + while (l1 != null && l2 != null) { + sum = l1.val + l2.val + carry; + head.next = new ListNode(sum % 10); + carry = sum / 10; + l1 = l1.next; + l2 = l2.next; + head = head.next; + } + + // add carry for left item + ListNode leftListNode = l1 != null ? l1 : l2; + while (leftListNode != null) { + if (carry == 0) { + head.next = leftListNode; + break; + } + sum = leftListNode.val + carry; + head.next = new ListNode(sum % 10); + carry = sum / 10; + leftListNode = leftListNode.next; + head = head.next; + } + + // consider the last item still have carry, add new one + if (carry == 1) { + head.next = new ListNode(1); + head = head.next; + } + + return result.next; + } +} From 6c051a3c504b47c487bf3f3b847379d6941c2dd2 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 19 Aug 2019 12:44:24 +0800 Subject: [PATCH 109/162] reverse integer --- code/LeetCode/src/number/ReverseInteger.java | 25 ++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 code/LeetCode/src/number/ReverseInteger.java diff --git a/code/LeetCode/src/number/ReverseInteger.java b/code/LeetCode/src/number/ReverseInteger.java new file mode 100644 index 00000000..62dee99a --- /dev/null +++ b/code/LeetCode/src/number/ReverseInteger.java @@ -0,0 +1,25 @@ +package number; + +// https://leetcode.com/problems/reverse-integer/ +public class ReverseInteger { + public int reverse(int x) { + int result = 0; + int pop; + int maxIntDivideTen = Integer.MAX_VALUE / 10; + int minIntDevideTen = Integer.MIN_VALUE / 10; + while (x != 0 ) { + pop = x % 10; + // consider integer overflows, return -1 + if (result > maxIntDivideTen || (result == maxIntDivideTen && pop > 7)) { + return 0; + } else if (result < minIntDevideTen || (result == minIntDevideTen && pop < -8)) { + return 0; + } + + result = result * 10 + pop; + x = x / 10; + } + + return result; + } +} From 821c3041a0fd86c8834d7acd38069a2a57134626 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 19 Aug 2019 12:44:34 +0800 Subject: [PATCH 110/162] two sum --- code/LeetCode/src/number/TwoSum.java | 50 ++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 code/LeetCode/src/number/TwoSum.java diff --git a/code/LeetCode/src/number/TwoSum.java b/code/LeetCode/src/number/TwoSum.java new file mode 100644 index 00000000..8ab71eba --- /dev/null +++ b/code/LeetCode/src/number/TwoSum.java @@ -0,0 +1,50 @@ +package number; + +import java.util.HashMap; +import java.util.Map; + +// https://leetcode.com/problems/two-sum/ +public class TwoSum { + public int[] twoSum(int[] nums, int target) { + for (int i = 0; i < nums.length; i++) { + for (int k = i + 1; k < nums.length; k++) { + if (nums[i] + nums[k] == target) { + return new int[]{nums[i], nums[k]}; + } + } + } + + return null; + } + + public int[] twoSumWithHashMap(int[] nums, int target) { + Map map = new HashMap<>(); + for (int i = 0; i < nums.length; i++) { + map.put(nums[i], i); + } + int remain; + for (int i = 0; i < nums.length; i++) { + remain = target - nums[i]; + if (map.containsKey(remain) && map.get(remain) != i) { + return new int[]{i, map.get(remain)}; + } + } + + throw new IllegalArgumentException("No two sum solution"); + } + + + public int[] twoSumWithMap(int[] nums, int target) { + Map map = new HashMap<>(); + int remain; + for (int i = 0; i < nums.length; i++) { + remain = target - nums[i]; + if (map.containsKey(nums[i])) { + return new int[]{map.get(nums[i]) , i}; + } + map.put(remain, i); + } + + throw new IllegalArgumentException("No two sum solution"); + } +} From 8f7d51f9edd823d7f70e1f6713fd1c72f2e3c68b Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 19 Aug 2019 12:44:43 +0800 Subject: [PATCH 111/162] roman to integer --- code/LeetCode/src/String/RomanToInteger.java | 111 +++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 code/LeetCode/src/String/RomanToInteger.java diff --git a/code/LeetCode/src/String/RomanToInteger.java b/code/LeetCode/src/String/RomanToInteger.java new file mode 100644 index 00000000..607eda2b --- /dev/null +++ b/code/LeetCode/src/String/RomanToInteger.java @@ -0,0 +1,111 @@ +package String; + +import java.util.HashMap; +import java.util.Map; + +// https://leetcode.com/problems/roman-to-integer/ +public class RomanToInteger { + + public static void main(String[] args) { + String input = "IV"; + romanToInt(input); + } + + public int romanToIntWithMap(String s) { + Map charMap = new HashMap<>(); + charMap.put('I', 1); + charMap.put('V', 5); + charMap.put('X', 10); + charMap.put('L', 50); + charMap.put('C', 100); + charMap.put('D', 500); + charMap.put('M', 1000); + int pre = 0; + int sum = 0; + int current; + for (int i = s.length() - 1; i >= 0; i--) { + current = charMap.get(s.charAt(i)); + if (current >= pre) { + sum += current; + } else { + sum -= current; + } + pre = current; + } + + return sum; + } + + + public int romanToIntReverseOrder(String s) { + if (s == null || s.length() == 0) { + return -1; + } + int sum = 0; + for (int i = s.length() - 1; i >= 0; i--) { + switch (s.charAt(i)) { + case 'I': { + sum += (sum >= 5 ? -1 : 1); + break; + } + case 'V': { + sum += 5; + break; + } + case 'X': { + sum += 10 * (sum >= 50 ? -1 : 1); + break; + } + case 'L': { + sum += 50; + break; + } + case 'C': { + sum += 100 * (sum >= 500 ? -1 : 1); + break; + } + case 'D': { + sum += 500; + break; + } + case 'M': { + sum += 1000; + break; + } + } + } + + return sum; + } + + public static int romanToInt(String s) { + Map doubleMap = new HashMap<>(); + doubleMap.put("IV", 4); + doubleMap.put("IX", 9); + doubleMap.put("XL", 40); + doubleMap.put("XC", 90); + doubleMap.put("CD", 400); + doubleMap.put("CM", 900); + int sum = 0; + for (String item: doubleMap.keySet()) { + if (s.contains(item)) { + sum += doubleMap.get(item); + s = s.replace(item, ""); + } + } + + Map charMap = new HashMap<>(); + charMap.put('I', 1); + charMap.put('V', 5); + charMap.put('X', 10); + charMap.put('L', 50); + charMap.put('C', 100); + charMap.put('D', 500); + charMap.put('M', 1000); + for (char c: s.toCharArray()) { + sum += charMap.get(c); + } + + return sum; + } +} From 747e4ddadfc435fc0a9a6a421da72ffba6e42dd2 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 3 Sep 2019 13:06:22 +0800 Subject: [PATCH 112/162] longest palindromic sub strings --- .../src/dp/LongestPalindromicSubstrins.java | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 code/LeetCode/src/dp/LongestPalindromicSubstrins.java diff --git a/code/LeetCode/src/dp/LongestPalindromicSubstrins.java b/code/LeetCode/src/dp/LongestPalindromicSubstrins.java new file mode 100644 index 00000000..2f9a9088 --- /dev/null +++ b/code/LeetCode/src/dp/LongestPalindromicSubstrins.java @@ -0,0 +1,149 @@ +package dp; + +// https://leetcode.com/problems/longest-palindromic-substring/ +public class LongestPalindromicSubstrins { + + public String longestPalindromeWithdp(String s) { + if (s == null || s.length() == 0) { + return ""; + } + boolean[][] dp = new boolean[s.length()][s.length()]; + String result = ""; + for (int i = s.length() - 1; i >= 0; i--) { + for (int k = i; k < s.length(); k++) { + dp[i][k] = (s.charAt(i) == s.charAt(k) && (k - i < 3 || dp[i + 1][k - 1])); + + if (dp[i][k] && k - i + 1 > result.length()) { + result = s.substring(i, k + 1); + } + } + } + + return result; + } + + public String longestPalindromeRecursive(String s) { + if (s == null || s.length() == 0) { + return ""; + } + + char[] chars = s.toCharArray(); + int max = 0; + int start = 0; + int end = 0; + for (int i = 0; i < chars.length; i++) { + if (validPalindrome(chars, i - max - 1, i)) { + start = i - max - 1; + end = i; + max += 2; + } else if (validPalindrome(chars, i - max, i)) { + start = i - max; + end = i; + max += 1; + } + } + + return s.substring(start, end + 1); + } + + public boolean validPalindrome(char[] chars, int start, int end) { + if (start < 0) { + return false; + } + while (start < end) { + if (chars[start++] != chars[end--]) { + return false; + } + } + + return true; + } + + public static String longestPalindromeSynchronize(String s) { + // edge case + if (s == null || s.length() == 0) { + return ""; + } + int max = 1; + String result = s.substring(0, 1); + for (int i = 0; i < s.length(); i++) { + int len1 = expandPalindrom(s, i, i); + int len2 = expandPalindrom(s, i, i + 1); + int len = Math.max(len1, len2); + if (max < len) { + max = len; + int left = i - (len - 1) / 2; + int right = i + len / 2; + result = s.substring(left, right + 1); + } + } + + return result; + } + + public static int expandPalindrom(String s, int left, int right) { + while (left >= 0 && right < s.length()) { + if (s.charAt(left) != s.charAt(right)) { + break; + } + + left--; + right++; + } + + return right - left - 1; + } + + public static void main(String[] args) { + String result = longestPalindromeSynchronize("bb"); + System.out.println(result); + } + + public static String longestPalindrome(String s) { + if (s == null || s.length() == 0) { + return ""; + } + int max = 1; + String result = s.substring(0, 1); + String current; + for (int i = 1; i < s.length(); i++) { + // assume the left string is palindrome, if its length is less than max, can break; + int dreamMax = Math.min(i, s.length() - i - 1) * 2 + 1; + if (max > dreamMax) { + break; + } + + // i is pivot center, such as 0i0 + current = helper(s, i - 1, i + 1); + if (max < current.length()) { + max = current.length(); + result = current; + } + + // i & i - 1 is pivot center, such as 0ii0 + if (s.charAt(i) != s.charAt(i - 1)) { + continue; + } + current = helper(s, i - 2, i + 1); + if (max < current.length()) { + max = current.length(); + result = current; + } + } + + return result; + } + + public static String helper(String s, int left, int right) { + while (left >= 0 && right < s.length()) { + if (s.charAt(left) != s.charAt(right)) { + break; + } + + left--; + right++; + } + + return right - left == 2 ? "" : s.substring(left + 1, right); + } +} From 9adc4c9659f970585f123086082af83c7d4aaacb Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 3 Sep 2019 13:06:40 +0800 Subject: [PATCH 113/162] longest substring without repeating characters --- ...stSubstringWithoutRepeatingCharacters.java | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 code/LeetCode/src/String/LongestSubstringWithoutRepeatingCharacters.java diff --git a/code/LeetCode/src/String/LongestSubstringWithoutRepeatingCharacters.java b/code/LeetCode/src/String/LongestSubstringWithoutRepeatingCharacters.java new file mode 100644 index 00000000..64a5d6e0 --- /dev/null +++ b/code/LeetCode/src/String/LongestSubstringWithoutRepeatingCharacters.java @@ -0,0 +1,84 @@ +package String; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +// https://leetcode.com/problems/longest-substring-without-repeating-characters/ +public class LongestSubstringWithoutRepeatingCharacters { + + public int lengthOfLongestSubstringWithArray(String s) { + int max = 0; + int[] array = new int[128]; + char c; + for (int i = 0, j = 0; j < s.length(); j++) { + c = s.charAt(j); + i = Math.max(array[c], i); + max = Math.max(max, (j - i + 1)); + array[c] = j + 1; + } + + return max; + } + + public int lengthOfLongestSubstringWithMap(String s) { + Map map = new HashMap<>(); + int max = 0; + char c; + for (int i = 0, j = 0; j < s.length(); j++) { + c = s.charAt(j); + if (map.containsKey(c)) { + i = Math.max(i, map.get(c)); + } + + max = Math.max(max, (j - i + 1)); + map.put(c, j + 1); + } + + return max; + } + + public int lengthOfLongestSubstringWithSet(String s) { + Set set = new HashSet<>(); + int max = 0; + int left = 0; + int right = 0; + char c; + while (right < s.length()) { + c = s.charAt(right); + if (!set.contains(c)) { + // not contain, add to set, replace max, right++ + set.add(c); + max = Math.max(max, (right - left + 1)); + right++; + } else { + // remove left item, left++ + set.remove(s.charAt(left)); + left++; + } + } + + return max; + } + + public int lengthOfLongestSubstring(String s) { + int longest = 0; + String current = ""; + for (char c : s.toCharArray()) { + if (current.indexOf(c) == -1) { + current += c; + if (current.length() > longest) { + longest = current.length(); + } + continue; + } + + int index = current.indexOf(c); + current += c; + current = current.substring(index + 1); + } + + return longest; + } +} From 16ea8112461c0c6811b2fe6de530ad096ec19ee2 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 3 Sep 2019 13:06:51 +0800 Subject: [PATCH 114/162] String to integer atoi --- .../src/String/StringToIntegerAtoi.java | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 code/LeetCode/src/String/StringToIntegerAtoi.java diff --git a/code/LeetCode/src/String/StringToIntegerAtoi.java b/code/LeetCode/src/String/StringToIntegerAtoi.java new file mode 100644 index 00000000..84e0c6b5 --- /dev/null +++ b/code/LeetCode/src/String/StringToIntegerAtoi.java @@ -0,0 +1,53 @@ +package String; + +// https://leetcode.com/problems/string-to-integer-atoi/ +public class StringToIntegerAtoi { + + public int myAtoi(String str) { + if (str == null || str.length() == 0) { + return 0; + } + char[] chars = str.toCharArray(); + int flag = 1; + int result = 0; + int i = 0; + int len = chars.length; + while (i < len && chars[i] == ' ') { + i++; + } + if (i < len && chars[i] == '-') { + flag = -1; + i++; + } else if (i < len && chars[i] == '+') { + flag = 1; + i++; + } + + if (i < len) { + int gap = chars[i] - '0'; + if (gap < 0 || gap > 9) { + return 0; + } + } + + int maxDevideTen = Integer.MAX_VALUE / 10; + int gap; + for (; i < len; i++) { + gap = chars[i] - '0'; + if (gap < 0 || gap > 9) { + break; + } + + if (flag == 1 && (result > maxDevideTen || (result == maxDevideTen && gap > 7))) { + return Integer.MAX_VALUE; + } else if (flag == -1 && (result > maxDevideTen || (result == maxDevideTen && gap > 8))) { + return Integer.MIN_VALUE; + } + + result = result * 10 + gap; + } + + return flag * result; + } + +} From 46afe3a0a0972eb1e7b772a29f43565bca42875b Mon Sep 17 00:00:00 2001 From: zgpeace Date: Wed, 18 Sep 2019 12:50:22 +0800 Subject: [PATCH 115/162] container with most water --- .../src/array/ContainerWithMostWater.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 code/LeetCode/src/array/ContainerWithMostWater.java diff --git a/code/LeetCode/src/array/ContainerWithMostWater.java b/code/LeetCode/src/array/ContainerWithMostWater.java new file mode 100644 index 00000000..f35fd95e --- /dev/null +++ b/code/LeetCode/src/array/ContainerWithMostWater.java @@ -0,0 +1,38 @@ +package array; + +import sun.security.util.Length; + +// https://leetcode.com/problems/container-with-most-water/ +public class ContainerWithMostWater { + + public int maxAreaWithTwoPointer(int[] height) { + int left = 0; + int right = height.length - 1; + int result = 0; + while (left < right) { + result = Math.max(result, Math.min(height[left], height[right]) * (right - left)); + if (height[left] < height[right]) { + left++; + } else { + right--; + } + } + + return result; + } + + public int maxArea(int[] height) { + int current; + int result = 0; + for (int i = 0; i < height.length; i++) { + for (int k = height.length - 1; k > i; k--) { + current = (k - i) * Math.min(height[k], height[i]); + if (current > result) { + result = current; + } + } + } + + return result; + } +} From 31de355efd7b5c4267ea5f611a1375d9b76326c2 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Wed, 18 Sep 2019 12:50:30 +0800 Subject: [PATCH 116/162] three sum --- code/LeetCode/src/array/ThreeSum.java | 65 +++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 code/LeetCode/src/array/ThreeSum.java diff --git a/code/LeetCode/src/array/ThreeSum.java b/code/LeetCode/src/array/ThreeSum.java new file mode 100644 index 00000000..ae5fd592 --- /dev/null +++ b/code/LeetCode/src/array/ThreeSum.java @@ -0,0 +1,65 @@ +package array; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +// https://leetcode.com/problems/3sum/ +public class ThreeSum { + + public static void main(String[] args) { + int[] nums = {0, 0, 0, 0}; + threeSum(nums); + } + + public static List> threeSum(int[] nums) { + List> result = new ArrayList<>(); + Arrays.sort(nums); + // edge condition track + if (nums == null || nums.length < 3 || nums[0] > 0 || nums[nums.length - 1] < 0) { + return result; + } + int l, r; + int len = nums.length; + // pivot i + int i = 0; + // increase the min one + while (i < len - 2 && nums[i]+ nums[len - 1] * 2 < 0) { + i++; + } + int rightMax = len - 1; + // decrease the max one + while (i < rightMax && nums[i] * 2 + nums[rightMax] > 0) { + rightMax--; + } + + int remain; + for (; i < rightMax; i++) { + if (i - 1 >= 0 && nums[i] == nums[i - 1]) { + continue; + } + l = i + 1; + r = rightMax; + remain = 0 - nums[i]; + // shrink between l and r + while (l < r) { + if (nums[l] + nums[r] == remain) { + result.add(Arrays.asList(nums[i], nums[l], nums[r])); + while (l < r && nums[l] == nums[++l]) { + } + while (l < r && nums[r] == nums[--r]) { + } + } + while (l < r && nums[l] + nums[r] < remain) { + l++; + } + while (l < r && nums[l] + nums[r] > remain) { + r--; + } + } + + } + + return result; + } +} From 3d84f441320e7b1c7363783c81ebd651897fe221 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Wed, 18 Sep 2019 12:50:46 +0800 Subject: [PATCH 117/162] remove nth node from end of list --- .../src/node/RemoveNthNodeFromEndOfList.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 code/LeetCode/src/node/RemoveNthNodeFromEndOfList.java diff --git a/code/LeetCode/src/node/RemoveNthNodeFromEndOfList.java b/code/LeetCode/src/node/RemoveNthNodeFromEndOfList.java new file mode 100644 index 00000000..0cb93a6c --- /dev/null +++ b/code/LeetCode/src/node/RemoveNthNodeFromEndOfList.java @@ -0,0 +1,32 @@ +package node; + +import common.ListNode; + +// https://leetcode.com/problems/remove-nth-node-from-end-of-list/ +public class RemoveNthNodeFromEndOfList { + + public static void main(String[] args) { + RemoveNthNodeFromEndOfList obj = new RemoveNthNodeFromEndOfList(); + int[] intArray = {1, 2, 3, 4, 5}; + ListNode node = ListNode.listNodeWithIntArray(intArray); + obj.removeNthFromEnd(node, 2); + } + + public ListNode removeNthFromEnd(ListNode head, int n) { + ListNode slow = new ListNode(0); + slow.next = head; + ListNode slowHead = slow; + ListNode fast = slow; + // add one more head Node, so need one step forward + for (int i = 0; i <= n; i++) { + fast = fast.next; + } + while (fast != null) { + slow = slow.next; + fast = fast.next; + } + slow.next = slow.next.next; + + return slowHead.next; + } +} From 3424d2b120640fff3adc3cc50e67af1ac9b880c6 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Wed, 18 Sep 2019 12:50:59 +0800 Subject: [PATCH 118/162] letter conbinations of a phone number --- .../LetterCombinationsOfAPhoneNumber.java | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 code/LeetCode/src/String/LetterCombinationsOfAPhoneNumber.java diff --git a/code/LeetCode/src/String/LetterCombinationsOfAPhoneNumber.java b/code/LeetCode/src/String/LetterCombinationsOfAPhoneNumber.java new file mode 100644 index 00000000..0b7d8aad --- /dev/null +++ b/code/LeetCode/src/String/LetterCombinationsOfAPhoneNumber.java @@ -0,0 +1,77 @@ +package String; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +// https://leetcode.com/problems/letter-combinations-of-a-phone-number/ +public class LetterCombinationsOfAPhoneNumber { + + Map phone = new HashMap() {{ + put('2', "abc"); + put('3', "def"); + put('4', "ghi"); + put('5', "jkl"); + put('6', "mno"); + put('7', "pqrs"); + put('8', "tuv"); + put('9', "wxyz"); + }}; + + public static void main(String[] args) { + LetterCombinationsOfAPhoneNumber obj = new LetterCombinationsOfAPhoneNumber(); + obj.letterCombinationsWithBacktrack("23"); + } + + private List resultList = new ArrayList<>(); + + public List letterCombinationsWithBacktrack(String digits) { + if (digits == null || digits.length() == 0) { + return resultList; + } + backTrack("", digits); + + return resultList; + } + + public void backTrack(String combination, String nextDigits) { + if (nextDigits == null || nextDigits.length() == 0) { + resultList.add(combination); + return; + } + char c = nextDigits.charAt(0); + for (char item: phone.get(c).toCharArray()) { + backTrack(combination + item, nextDigits.substring(1)); + } + } + + + public List letterCombinations(String digits) { + // result queue + List queue = new ArrayList<>(); + if (digits == null || digits.length() == 0) { + return queue; + } + // first + queue.add(""); + int gap; + int size; + String charString; + for (char c: digits.toCharArray()) { + charString = phone.get(c); + size = queue.size(); + // iterate exist queue + for (int i = 0; i < size; i++) { + String s = queue.remove(0); + // append char + for (char phoneChar: charString.toCharArray()) { + String result = s + phoneChar; + queue.add(result); + } + } + } + + return queue; + } +} From fccab764ae7b9303a9c06036ff15081fe2a6d12c Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 7 Oct 2019 12:42:03 +0800 Subject: [PATCH 119/162] divide two integers. template var use long type. --- .../src/binarysearch/DivideTwoIntegers.java | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 code/LeetCode/src/binarysearch/DivideTwoIntegers.java diff --git a/code/LeetCode/src/binarysearch/DivideTwoIntegers.java b/code/LeetCode/src/binarysearch/DivideTwoIntegers.java new file mode 100644 index 00000000..5897feae --- /dev/null +++ b/code/LeetCode/src/binarysearch/DivideTwoIntegers.java @@ -0,0 +1,61 @@ +package binarysearch; + +// https://leetcode.com/problems/divide-two-integers/ +public class DivideTwoIntegers { + + int maxOfHalf = Integer.MAX_VALUE >> 1; + + public static void main(String[] args) { + DivideTwoIntegers obj = new DivideTwoIntegers(); + int result = obj.divide(-2147483648, -1); + System.out.println("result > " + result); + } + + public int divide(int dividend, int divisor) { + // Reduce the problem to positive long integer to make it easier. + // Use long to avoid integer overflow case. + int sign = -1; + if ((dividend > 0 && divisor > 0) || (dividend < 0 && divisor < 0)) { + sign = 1; + } + long ldividend = Math.abs((long)dividend); + long ldivisor = Math.abs((long)divisor); + + // Take care the edge cases. + if (ldivisor == 0) return Integer.MAX_VALUE; + if ((ldividend == 0 || (ldividend < ldivisor))) return 0; + + long lans = ldivide(ldividend, ldivisor); + + int ans; + if (lans > Integer.MAX_VALUE) { + // Handle overflow. + ans = (sign == 1) ? Integer.MAX_VALUE : Integer.MIN_VALUE; + } else { + ans = (int)((sign == 1) ? lans : -lans); + } + + return ans; + } + + private long ldivide(long ldividend, long ldivisor) { + // Recursion exit condition + if (ldividend < ldivisor) { + return 0; + } + + // Find the largest multiple so that (divisor * multiple <= dividend), + // whereas we are moving with stride 1, 2, 4, 8, 16...2^n for performance reason. + // Think this as a binary search. + long sum = ldivisor; + long multiple = 1; + while ((sum << 1) <= ldividend) { + multiple <<= 1; + sum <<= 1; + } + + // Look for additional value for the multiple from the reminder (dividend - sum) recursively. + return multiple + ldivide(ldividend - sum, ldivisor); + } + +} From a37ae3e94ba19eeada1004cfdc1eba4aced572dd Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 8 Oct 2019 12:49:42 +0800 Subject: [PATCH 120/162] implement with my logic --- .../src/binarysearch/DivideTwoIntegers.java | 109 ++++++++++++------ 1 file changed, 75 insertions(+), 34 deletions(-) diff --git a/code/LeetCode/src/binarysearch/DivideTwoIntegers.java b/code/LeetCode/src/binarysearch/DivideTwoIntegers.java index 5897feae..32ca2091 100644 --- a/code/LeetCode/src/binarysearch/DivideTwoIntegers.java +++ b/code/LeetCode/src/binarysearch/DivideTwoIntegers.java @@ -3,58 +3,99 @@ // https://leetcode.com/problems/divide-two-integers/ public class DivideTwoIntegers { - int maxOfHalf = Integer.MAX_VALUE >> 1; - - public static void main(String[] args) { - DivideTwoIntegers obj = new DivideTwoIntegers(); - int result = obj.divide(-2147483648, -1); - System.out.println("result > " + result); - } + //int maxOfHalf = Integer.MAX_VALUE >> 1; + // + //public static void main(String[] args) { + // DivideTwoIntegers obj = new DivideTwoIntegers(); + // int result = obj.divide(-2147483648, -1); + // System.out.println("result > " + result); + //} + // + //public int divide(int dividend, int divisor) { + // // Reduce the problem to positive long integer to make it easier. + // // Use long to avoid integer overflow case. + // int sign = -1; + // if ((dividend > 0 && divisor > 0) || (dividend < 0 && divisor < 0)) { + // sign = 1; + // } + // long ldividend = Math.abs((long)dividend); + // long ldivisor = Math.abs((long)divisor); + // + // // Take care the edge cases. + // if (ldivisor == 0) return Integer.MAX_VALUE; + // if ((ldividend == 0 || (ldividend < ldivisor))) return 0; + // + // long lans = ldivide(ldividend, ldivisor); + // + // int ans; + // if (lans > Integer.MAX_VALUE) { + // // Handle overflow. + // ans = (sign == 1) ? Integer.MAX_VALUE : Integer.MIN_VALUE; + // } else { + // ans = (int)((sign == 1) ? lans : -lans); + // } + // + // return ans; + //} + // + //private long ldivide(long ldividend, long ldivisor) { + // // Recursion exit condition + // if (ldividend < ldivisor) { + // return 0; + // } + // + // // Find the largest multiple so that (divisor * multiple <= dividend), + // // whereas we are moving with stride 1, 2, 4, 8, 16...2^n for performance reason. + // // Think this as a binary search. + // long sum = ldivisor; + // long multiple = 1; + // while ((sum << 1) <= ldividend) { + // multiple <<= 1; + // sum <<= 1; + // } + // + // // Look for additional value for the multiple from the reminder (dividend - sum) recursively. + // return multiple + ldivide(ldividend - sum, ldivisor); + //} public int divide(int dividend, int divisor) { - // Reduce the problem to positive long integer to make it easier. - // Use long to avoid integer overflow case. - int sign = -1; - if ((dividend > 0 && divisor > 0) || (dividend < 0 && divisor < 0)) { - sign = 1; + //sign + int sign = 1; + if ((dividend > 0 && divisor < 0) || (dividend < 0 && divisor > 0)) { + sign = -1; } + // long type long ldividend = Math.abs((long)dividend); long ldivisor = Math.abs((long)divisor); + // edge + if (ldivisor == 0) { + return (sign == 1) ? Integer.MAX_VALUE : Integer.MIN_VALUE; + } + if (ldividend < ldivisor) { + return 0; + } + long result = ldivide(ldividend, ldivisor); - // Take care the edge cases. - if (ldivisor == 0) return Integer.MAX_VALUE; - if ((ldividend == 0 || (ldividend < ldivisor))) return 0; - - long lans = ldivide(ldividend, ldivisor); - - int ans; - if (lans > Integer.MAX_VALUE) { - // Handle overflow. - ans = (sign == 1) ? Integer.MAX_VALUE : Integer.MIN_VALUE; - } else { - ans = (int)((sign == 1) ? lans : -lans); + if (result > Integer.MAX_VALUE) { + return (sign == 1) ? Integer.MAX_VALUE : Integer.MIN_VALUE; } - return ans; + int intResult = (int)result; + return (sign == 1) ? intResult : - intResult; } - private long ldivide(long ldividend, long ldivisor) { - // Recursion exit condition + public long ldivide(long ldividend, long ldivisor) { + // exit condition if (ldividend < ldivisor) { return 0; } - - // Find the largest multiple so that (divisor * multiple <= dividend), - // whereas we are moving with stride 1, 2, 4, 8, 16...2^n for performance reason. - // Think this as a binary search. - long sum = ldivisor; long multiple = 1; + long sum = ldivisor; while ((sum << 1) <= ldividend) { - multiple <<= 1; sum <<= 1; + multiple <<= 1; } - // Look for additional value for the multiple from the reminder (dividend - sum) recursively. return multiple + ldivide(ldividend - sum, ldivisor); } From c92ac3db8438b7cbc3e39fbaeb910b36e1166a56 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 21 Oct 2019 12:43:14 +0800 Subject: [PATCH 121/162] search in rotated sorted array --- .../SearchInRotatedSortedArray.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 code/LeetCode/src/binarysearch/SearchInRotatedSortedArray.java diff --git a/code/LeetCode/src/binarysearch/SearchInRotatedSortedArray.java b/code/LeetCode/src/binarysearch/SearchInRotatedSortedArray.java new file mode 100644 index 00000000..1d89765e --- /dev/null +++ b/code/LeetCode/src/binarysearch/SearchInRotatedSortedArray.java @@ -0,0 +1,54 @@ +package binarysearch; + +// https://leetcode.com/problems/search-in-rotated-sorted-array/ +public class SearchInRotatedSortedArray { + + public static void main(String[] args) { + SearchInRotatedSortedArray obj = new SearchInRotatedSortedArray(); + int[] nums = {1, 3}; + obj.search(nums, 3); + } + + public int search(int[] nums, int target) { + // check edge + if (nums == null || nums.length == 0) { + return -1; + } + // find the divide index + int divideIndex = findDividIndex(nums); + if (target == nums[divideIndex]) { + return divideIndex; + } + int lastIndex = nums.length - 1; + int beginIndex = target > nums[lastIndex] ? 0 : divideIndex; + int endIndex = target > nums[lastIndex] ? divideIndex : lastIndex; + while (beginIndex <= endIndex) { + int midIndex = beginIndex + ((endIndex - beginIndex) >> 1); + if (target == nums[midIndex]) { + return midIndex; + } else if (target > nums[midIndex]) { + beginIndex = midIndex + 1; + } else { + endIndex = midIndex - 1; + } + } + + return -1; + } + + private int findDividIndex(int[] nums) { + int from = 0; + int to = nums.length - 1; + while (from < to) { + int mid = from + ((to - from) >> 1); + if (nums[mid] > nums[to]) { + from = mid + 1; + } else { + to = mid; + } + } + + return from; + } + +} From 2c359c11bcb9c89bc5e2a7d6ebb92974ed0160b1 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Thu, 24 Oct 2019 12:50:52 +0800 Subject: [PATCH 122/162] find first and last position of element in sorted array --- ...AndLastPositionOfElementInSortedArray.java | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 code/LeetCode/src/binarysearch/FindFirstAndLastPositionOfElementInSortedArray.java diff --git a/code/LeetCode/src/binarysearch/FindFirstAndLastPositionOfElementInSortedArray.java b/code/LeetCode/src/binarysearch/FindFirstAndLastPositionOfElementInSortedArray.java new file mode 100644 index 00000000..320308f0 --- /dev/null +++ b/code/LeetCode/src/binarysearch/FindFirstAndLastPositionOfElementInSortedArray.java @@ -0,0 +1,156 @@ +package binarysearch; + +import java.util.Arrays; + +// https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/ +public class FindFirstAndLastPositionOfElementInSortedArray { + + public static void main(String[] args) { + int[] nums = {2, 2}; + int target = 2; + FindFirstAndLastPositionOfElementInSortedArray obj = new FindFirstAndLastPositionOfElementInSortedArray(); + int[] result = obj.searchRangeWithFirstGreatEqual(nums, target); + System.out.println(Arrays.toString(result)); + } + + public int[] searchRangeWithFirstGreatEqual(int[] nums, int target) { + int[] result = new int[]{-1, -1}; + // edge check + if (nums == null || nums.length == 0) { + return result; + } + int find = findFirstGreatEqual(nums, target); + if (find >= nums.length || nums[find] != target) { + return result; + } + result[0] = find; + result[1] = findFirstGreatEqual(nums, target + 1) - 1; + + return result; + } + + //find the first number that is greater than or equal to target. + //could return A.length if target is greater than A[A.length-1]. + private int findFirstGreatEqual(int[] nums, int target) { + int low = 0; + int high = nums.length; + while (low < high) { + int mid = low + ((high - low) >> 1); + //low <= mid < high + if (nums[mid] < target) { + low = mid + 1; + } else { + //should not be mid-1 when A[mid]==target. + //could be mid even if A[mid]>target because mid> 1); + if (nums[mid] >= target) { + right = mid - 1; + } else { + left = mid + 1; + } + if (nums[mid] == target) { + result = mid; + } + } + + return result; + } + + private int findLast(int[] nums, int target) { + int result = -1; + int left = 0; + int right = nums.length - 1; + while (left <= right) { + int mid = left + ((right - left) >> 1); + if (nums[mid] <= target) { + left = mid + 1; + } else { + right = mid - 1; + } + if (nums[mid] == target) { + result = mid; + } + } + + + return result; + } + + public int[] searchRange(int[] nums, int target) { + int[] result = new int[]{-1, -1}; + // edge check + if (nums == null || nums.length == 0) { + return result; + } + + int left = 0; + int right = nums.length - 1; + int find = -1; + while (left <= right && find == -1) { + int mid = left + ((right - left) >> 1); + if (nums[mid] == target) { + find = mid; + break; + } else if (nums[mid] < target) { + left = mid + 1; + } else { + right = mid - 1; + } + } + + // no found return + if (find == -1) { + return result; + } + + int findMinRight = find; + while (left <= findMinRight) { + int mid = left + ((findMinRight - left) >> 1); + if (nums[mid] == target) { + result[0] = mid; + findMinRight = mid - 1; + } else { + // less than target + left = mid + 1; + } + } + + int findMaxLeft = find; + while (findMaxLeft <= right) { + int mid = findMaxLeft + ((right - findMaxLeft) >> 1); + if (nums[mid] == target) { + result[1] = mid; + findMaxLeft = mid + 1; + } else { + // more than target + right = mid - 1; + } + } + + return result; + } +} From 3a128c79da888e67d6c3e9ee7d769a2828f52d52 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 1 Nov 2019 14:21:57 +0800 Subject: [PATCH 123/162] valid suduku --- code/LeetCode/src/hashtable/ValidSudoku.java | 119 +++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 code/LeetCode/src/hashtable/ValidSudoku.java diff --git a/code/LeetCode/src/hashtable/ValidSudoku.java b/code/LeetCode/src/hashtable/ValidSudoku.java new file mode 100644 index 00000000..cf5364df --- /dev/null +++ b/code/LeetCode/src/hashtable/ValidSudoku.java @@ -0,0 +1,119 @@ +package hashtable; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; + +// https://leetcode.com/problems/valid-sudoku/ +public class ValidSudoku { + + public static void main(String[] args) { + Map map = new HashMap<>(); + System.out.println("map coantins 0 > " + map.get(0) + " > validate bolean :" + map.containsKey(0)); + } + + public boolean isValidSudokuWithOneHashset(char[][] board) { + HashSet set = new HashSet<>(); + char item; + for (int i = 0; i < 9; i++) { + for (int j = 0; j < 9; j++) { + item = board[i][j]; + if (item == '.') { + continue; + } + if (!set.add(item + "row" + i)) { + return false; + } + if (!set.add(item + "col" + j)) { + return false; + } + if (!set.add(item + "block" + i/3 + "_" + j/3)) { + return false; + } + } + } + + return true; + } + + public boolean isValidSudokuWithHashset(char[][] board) { + + for (int i = 0; i < 9; i++) { + HashSet rowSet = new HashSet<>(); + HashSet colSet = new HashSet<>(); + HashSet blockSet = new HashSet<>(); + for (int j = 0; j < 9; j++) { + if (board[i][j] != '.' && !rowSet.add(board[i][j])) { + return false; + } + if (board[j][i] != '.' && !colSet.add(board[j][i])) { + return false; + } + int row = 3 * (i / 3); + int col = 3 * (i % 3); + int rowIndex = row + j / 3; + int colIndex = col + j % 3; + if (board[rowIndex][colIndex] != '.' && !blockSet.add(board[rowIndex][colIndex])) { + return false; + } + + } + } + + return true; + } + + public boolean isValidSudoku(char[][] board) { + // init data + Map> containMap = new HashMap<>(); + String rowPre = "row_"; + String columnPre = "col_"; + String blockConnect = "_"; + // row & column map + for (int i = 0; i < 9; i++) { + // row key : row_index + containMap.put(rowPre + i, new HashMap()); + // column key: clo_index + containMap.put(columnPre + i, new HashMap()); + } + // block map, key style: rowIndex_colIndex + for (int i = 0; i < 3; i++) { + for (int k = 0; k < 3; k++) { + containMap.put(i + blockConnect + k, new HashMap()); + } + } + + for (int r = 0; r < 9; r++) { + for (int c = 0; c < 9; c++) { + if (board[r][c] == '.') { + continue; + } + // row char + if (containMap.get(rowPre + r).containsKey(board[r][c])) { + return false; + } else { + containMap.get(rowPre + r).put(board[r][c], c); + } + // column char + if (containMap.get(columnPre + c).containsKey(board[r][c])) { + return false; + } else { + containMap.get(columnPre + c).put(board[r][c], r); + } + + // block + int blockRow = r / 3; + int blockColumn = c / 3; + String blockKey = blockRow+blockConnect+blockColumn; + if (containMap.get(blockKey).containsKey(board[r][c])) { + return false; + } else { + containMap.get(blockKey).put(board[r][c], c); + } + } + + } + + return true; + } +} From 8725e5009a3b68574ec1e500770575c5238c10e4 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Wed, 6 Nov 2019 14:16:19 +0800 Subject: [PATCH 124/162] permutations --- .../src/backtracking/Permutations.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 code/LeetCode/src/backtracking/Permutations.java diff --git a/code/LeetCode/src/backtracking/Permutations.java b/code/LeetCode/src/backtracking/Permutations.java new file mode 100644 index 00000000..73974b11 --- /dev/null +++ b/code/LeetCode/src/backtracking/Permutations.java @@ -0,0 +1,59 @@ +package backtracking; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +// https://leetcode.com/problems/permutations/ +public class Permutations { + + public static void main(String[] args) { + Permutations obj = new Permutations(); + obj.permuteWithCleanRecursive(new int[]{1, 2, 3}); + } + + public List> permuteWithCleanRecursive(int[] nums) { + LinkedList> result = new LinkedList<>(); + result.add(new ArrayList()); + int size; + for (int n: nums) { + size = result.size(); + for (; size > 0; size--) { + List resultItem = result.pollFirst(); + for (int i = 0; i <= resultItem.size(); i++) { + List newList = new ArrayList<>(resultItem); + newList.add(i, n); + result.add(newList); + } + } + + } + + return result; + } + + public List> permute(int[] nums) { + List> result = new ArrayList>(); + if (nums == null || nums.length == 0) { + return result; + } + + // backtracking + addItemInAllPosition(nums, 0, new ArrayList(), result); + + return result; + } + + private void addItemInAllPosition(int[] nums, int start, List list, List> result) { + if (list.size() == nums.length) { + result.add(list); + return; + } + + for (int i = 0; i <= list.size(); i++) { + List newList = new ArrayList<>(list); + newList.add(i, nums[start]); + addItemInAllPosition(nums, start + 1, newList, result); + } + } +} From 81c4824f090d2558a61476d85cbfa6d07e289487 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 11 Nov 2019 14:23:03 +0800 Subject: [PATCH 125/162] rotate image --- code/LeetCode/src/array/RotateImage.java | 81 ++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 code/LeetCode/src/array/RotateImage.java diff --git a/code/LeetCode/src/array/RotateImage.java b/code/LeetCode/src/array/RotateImage.java new file mode 100644 index 00000000..e25677eb --- /dev/null +++ b/code/LeetCode/src/array/RotateImage.java @@ -0,0 +1,81 @@ +package array; + +// https://leetcode.com/problems/rotate-image/ +public class RotateImage { + + /** + * Given input matrix = + * [ + * [1,2,3], + * [4,5,6], + * [7,8,9] + * ], + * + * rotate the input matrix in-place such that it becomes: + * [ + * [7,4,1], + * [8,5,2], + * [9,6,3] + * ] + */ + public void rotate(int[][] matrix) { + + /* + * clockwise rotate + * first reverse up to down, then swap the symmetry + * 1 2 3 7 8 9 7 4 1 + * 4 5 6 => 4 5 6 => 8 5 2 + * 7 8 9 1 2 3 9 6 3 + */ + + // check edge + if (matrix == null || matrix.length <= 1) { + return; + } + + // step 1 > reverse up to down: i < len 2; row[i] <-> row[len - i -1] + + /* 7,8,9 + 4,5,6 + 1,2,3 + */ + int len = matrix.length; + for (int row = 0; row < len / 2; row++) { + int[] temp = matrix[row]; + int downIndex = len - 1 - row; + matrix[row]= matrix[downIndex]; + matrix[downIndex] = temp; + } + + // step 2 > swap the symmetry: row[0,len - 1], col[row, len - 1] + + /* 7,4,1 + 8,5,2 + 9,6,3 + */ + for (int row = 0; row < len; row++) { + for (int col = row + 1; col < len; col++) { + int temp = matrix[row][col]; + matrix[row][col] = matrix[col][row]; + matrix[col][row] = temp; + } + } + + } + + public void rotateWithFourPoint(int[][] matrix) { + if (matrix == null || matrix.length <= 1) { + return; + } + int len = matrix.length; + for (int row = 0; row < len / 2; row++) { + for (int col = row; col < len - 1 - row; col++) { + int temp = matrix[row][col]; + matrix[row][col] = matrix[len - 1 - col][row]; + matrix[len - 1 - col][row] = matrix[len - 1 - row][len - 1 - col]; + matrix[len - 1 - row][len - 1 - col] = matrix[col][len - 1 - row]; + matrix[col][len - 1 - row] = temp; + } + } + } +} From a57db451738c8e3ac2d424f5503c67c76351d3e3 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 2 Dec 2019 12:39:45 +0800 Subject: [PATCH 126/162] group anagrams --- .../LeetCode/src/hashtable/GroupAnagrams.java | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 code/LeetCode/src/hashtable/GroupAnagrams.java diff --git a/code/LeetCode/src/hashtable/GroupAnagrams.java b/code/LeetCode/src/hashtable/GroupAnagrams.java new file mode 100644 index 00000000..b798032c --- /dev/null +++ b/code/LeetCode/src/hashtable/GroupAnagrams.java @@ -0,0 +1,94 @@ +package hashtable; + +import java.util.*; + +// https://leetcode.com/problems/group-anagrams/ +public class GroupAnagrams { + + public static void main(String[] args) { + String[] inputs = {"eat","tea","tan","ate","nat","bat"}; + GroupAnagrams obj = new GroupAnagrams(); + obj.groupAnagrams(inputs); + } + + public List> groupAnagramsWithCharCount(String[] strs) { + // edge check + if (strs == null || strs.length == 0) { + return null; + } + Map> map = new HashMap<>(); + int[] charCountArray = new int[26]; + // build map + for (String s: strs) { + Arrays.fill(charCountArray, 0); + for (char c: s.toCharArray()) { + charCountArray[(c - 'a')]++; + } + StringBuilder sb = new StringBuilder(); + for (int i: charCountArray) { + sb.append('#'); + sb.append(i); + } + + String sortItem = sb.toString(); + if (!map.containsKey(sortItem)) { + map.put(sortItem, new ArrayList()); + } + + map.get(sortItem).add(s); + } + + return new ArrayList<>(map.values()); + + } + + + private String sort(String input) { + char[] chars = input.toCharArray(); + Arrays.sort(chars); + return new String(chars); + } + + public List> groupAnagramsWithMap(String[] strs) { + // edge check + if (strs == null || strs.length == 0) { + return null; + } + Map> map = new HashMap<>(); + // build map + for (String s: strs) { + String sortItem = sort(s); + if (!map.containsKey(sortItem)) { + map.put(sortItem, new ArrayList()); + } + + map.get(sortItem).add(s); + } + + return new ArrayList<>(map.values()); + } + + public List> groupAnagrams(String[] strs) { + List> result = new ArrayList<>(); + + for (String s: strs) { + String sortString = sort(s); + boolean isSame = false; + for (List list: result) { + String item = list.get(0); + if (sortString.length() == item.length() && sort(item).equals(sortString)) { + list.add(s); + isSame = true; + break; + } + } + + if (isSame == false) { + result.add(new ArrayList<>(Arrays.asList(s))); + } + + } + + return result; + } +} From e1653fbdb030c9fc23bf91161f872e7de2f2ea29 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Sun, 8 Dec 2019 08:35:05 +0800 Subject: [PATCH 127/162] powxn --- code/LeetCode/src/binarysearch/Powxn.java | 60 +++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 code/LeetCode/src/binarysearch/Powxn.java diff --git a/code/LeetCode/src/binarysearch/Powxn.java b/code/LeetCode/src/binarysearch/Powxn.java new file mode 100644 index 00000000..4eb75585 --- /dev/null +++ b/code/LeetCode/src/binarysearch/Powxn.java @@ -0,0 +1,60 @@ +package binarysearch; + +public class Powxn { + + public static void main(String[] args) { + Powxn obj = new Powxn(); + System.out.println("Input:2.000, -2147483648 >> " + obj.myPow(2.000, -2147483648) ); + System.out.println("Input:2.000, -2 >> " + obj.myPow(2.000, -2) ); + System.out.println("Input:2.000, 10 >> " + obj.myPow(2.000, 10) ); + System.out.println("Input:2.1, 3 >> " + obj.myPow(2.1, 3) ); + + System.out.println("========================="); + + System.out.println("Input:2.000, -2147483648 >> " + obj.myPowWithIterate(2.000, -2147483648) ); + System.out.println("Input:2.000, -2 >> " + obj.myPowWithIterate(2.000, -2) ); + System.out.println("Input:2.000, 10 >> " + obj.myPowWithIterate(2.000, 10) ); + System.out.println("Input:2.1, 3 >> " + obj.myPowWithIterate(2.1, 3) ); + } + + public double myPow(double x, int n) { + if (n < 0) { + // consider -n overflow + return 1/x * myPow(1/x, -(n + 1)); + } + if (n == 0) { + return 1; + } + if (n == 1) { + return x; + } + + int halfN = n >> 1; + return (n%2 == 0) ? myPow(x * x, halfN) : myPow( x * x, halfN) * x; + } + + + public double myPowWithIterate(double x, int n) { + double result = 1; + if (n < 0) { + // consider -n overflow + x = 1/x; + n = -(n + 1); + result = x; + } + + while (n != 0) { + if (n % 2 == 1) { + result *= x; + if (n == 1) { + break; + } + } + + x = x * x; + n = n >> 1; + } + + return result; + } +} From c5c10afbf15801f1be57fca3d297598e97c3171b Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 17 Dec 2019 14:36:06 +0800 Subject: [PATCH 128/162] letter combinations of a phone number --- .../LetterCombinationsOfAPhoneNumber.java | 44 ++++++- .../LetterCombinationsOfAPhoneNumber.java | 111 ++++++++++++++++++ 2 files changed, 150 insertions(+), 5 deletions(-) create mode 100644 code/LeetCode/src/backtracking/LetterCombinationsOfAPhoneNumber.java diff --git a/code/LeetCode/src/String/LetterCombinationsOfAPhoneNumber.java b/code/LeetCode/src/String/LetterCombinationsOfAPhoneNumber.java index 0b7d8aad..e4d3bcca 100644 --- a/code/LeetCode/src/String/LetterCombinationsOfAPhoneNumber.java +++ b/code/LeetCode/src/String/LetterCombinationsOfAPhoneNumber.java @@ -1,9 +1,6 @@ package String; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; // https://leetcode.com/problems/letter-combinations-of-a-phone-number/ public class LetterCombinationsOfAPhoneNumber { @@ -21,7 +18,44 @@ public class LetterCombinationsOfAPhoneNumber { public static void main(String[] args) { LetterCombinationsOfAPhoneNumber obj = new LetterCombinationsOfAPhoneNumber(); - obj.letterCombinationsWithBacktrack("23"); + obj.letterCombinationWithIterate("23"); + } + + public List letterCombinationWithIterate(String digits) { + List result = new ArrayList<>(); + if (digits == null || digits.length() == 0) { + return result; + } + + char[][] map = new char[8][]; + map[0] = "abc".toCharArray(); + map[1] = "def".toCharArray(); + map[2] = "ghi".toCharArray(); + map[3] = "jkl".toCharArray(); + map[4] = "mno".toCharArray(); + map[5] = "pqrs".toCharArray(); + map[6] = "tuv".toCharArray(); + map[7] = "wxyz".toCharArray(); + + result.add(""); + for (char digit: digits.toCharArray()) { + result = append(result, map[digit - '2']); + } + + System.out.println("result > " + Arrays.toString(result.toArray())); + + return result; + } + + private List append(List lastList, char[] charArray) { + List nextList = new ArrayList<>(); + for (String s: lastList) { + for (char c: charArray) { + nextList.add(s + c); + } + } + + return nextList; } private List resultList = new ArrayList<>(); diff --git a/code/LeetCode/src/backtracking/LetterCombinationsOfAPhoneNumber.java b/code/LeetCode/src/backtracking/LetterCombinationsOfAPhoneNumber.java new file mode 100644 index 00000000..fbf0062b --- /dev/null +++ b/code/LeetCode/src/backtracking/LetterCombinationsOfAPhoneNumber.java @@ -0,0 +1,111 @@ +package backtracking; + +import java.util.*; + +// https://leetcode.com/problems/letter-combinations-of-a-phone-number/ +public class LetterCombinationsOfAPhoneNumber { + + Map phone = new HashMap() {{ + put('2', "abc"); + put('3', "def"); + put('4', "ghi"); + put('5', "jkl"); + put('6', "mno"); + put('7', "pqrs"); + put('8', "tuv"); + put('9', "wxyz"); + }}; + + public static void main(String[] args) { + LetterCombinationsOfAPhoneNumber obj = new LetterCombinationsOfAPhoneNumber(); + obj.letterCombinationWithIterate("23"); + } + + public List letterCombinationWithIterate(String digits) { + List result = new ArrayList<>(); + if (digits == null || digits.length() == 0) { + return result; + } + + char[][] map = new char[8][]; + map[0] = "abc".toCharArray(); + map[1] = "def".toCharArray(); + map[2] = "ghi".toCharArray(); + map[3] = "jkl".toCharArray(); + map[4] = "mno".toCharArray(); + map[5] = "pqrs".toCharArray(); + map[6] = "tuv".toCharArray(); + map[7] = "wxyz".toCharArray(); + + result.add(""); + for (char digit: digits.toCharArray()) { + result = append(result, map[digit - '2']); + } + + System.out.println("result > " + Arrays.toString(result.toArray())); + + return result; + } + + private List append(List lastList, char[] charArray) { + List nextList = new ArrayList<>(); + for (String s: lastList) { + for (char c: charArray) { + nextList.add(s + c); + } + } + + return nextList; + } + + private List resultList = new ArrayList<>(); + + public List letterCombinationsWithBacktrack(String digits) { + if (digits == null || digits.length() == 0) { + return resultList; + } + backTrack("", digits); + + return resultList; + } + + public void backTrack(String combination, String nextDigits) { + if (nextDigits == null || nextDigits.length() == 0) { + resultList.add(combination); + return; + } + char c = nextDigits.charAt(0); + for (char item: phone.get(c).toCharArray()) { + backTrack(combination + item, nextDigits.substring(1)); + } + } + + + public List letterCombinations(String digits) { + // result queue + List queue = new ArrayList<>(); + if (digits == null || digits.length() == 0) { + return queue; + } + // first + queue.add(""); + int gap; + int size; + String charString; + for (char c: digits.toCharArray()) { + charString = phone.get(c); + size = queue.size(); + // iterate exist queue + for (int i = 0; i < size; i++) { + String s = queue.remove(0); + // append char + for (char phoneChar: charString.toCharArray()) { + String result = s + phoneChar; + queue.add(result); + } + } + } + + return queue; + } +} From cc6bf38b42271830db1a9eea0b0ad224824230dd Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 17 Dec 2019 14:36:15 +0800 Subject: [PATCH 129/162] eight queens --- .../src/backtracking/EightQueens.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 code/LeetCode/src/backtracking/EightQueens.java diff --git a/code/LeetCode/src/backtracking/EightQueens.java b/code/LeetCode/src/backtracking/EightQueens.java new file mode 100644 index 00000000..2ac79c7c --- /dev/null +++ b/code/LeetCode/src/backtracking/EightQueens.java @@ -0,0 +1,51 @@ +package backtracking; + +public class EightQueens { + + public static void main(String[] args) { + EightQueens obj = new EightQueens(); + obj.cal8queens(0); + } + + int count = 0; + int[] result = new int[8];//全局或成员变量,下标表示行,值表示queen存储在哪一列 + public void cal8queens(int row) { // 调用方式:cal8queens(0); + if (row == 8) { // 8个棋子都放置好了,打印结果 + printQueens(result); + return; // 8行棋子都放好了,已经没法再往下递归了,所以就return + } + for (int column = 0; column < 8; ++column) { // 每一行都有8中放法 + if (isOk(row, column)) { // 有些放法不满足要求 + result[row] = column; // 第row行的棋子放到了column列 + cal8queens(row+1); // 考察下一行 + } + } + } + + private boolean isOk(int row, int column) {//判断row行column列放置是否合适 + int leftup = column - 1, rightup = column + 1; + for (int i = row-1; i >= 0; --i) { // 逐行往上考察每一行 + if (result[i] == column) return false; // 第i行的column列有棋子吗? + if (leftup >= 0) { // 考察左上对角线:第i行leftup列有棋子吗? + if (result[i] == leftup) return false; + } + if (rightup < 8) { // 考察右上对角线:第i行rightup列有棋子吗? + if (result[i] == rightup) return false; + } + --leftup; ++rightup; + } + return true; + } + + private void printQueens(int[] result) { // 打印出一个二维矩阵 + System.out.println(">>>>>> solution " + (++count) + " <<<<<<<<"); + for (int row = 0; row < 8; ++row) { + for (int column = 0; column < 8; ++column) { + if (result[row] == column) System.out.print("Q "); + else System.out.print("* "); + } + System.out.println(); + } + System.out.println(); + } +} From 7b55bdb601746610612c40efbcd90f5b4afb9be8 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 17 Dec 2019 14:36:50 +0800 Subject: [PATCH 130/162] package 0 or 1 --- .../src/backtracking/Package0to1.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 code/LeetCode/src/backtracking/Package0to1.java diff --git a/code/LeetCode/src/backtracking/Package0to1.java b/code/LeetCode/src/backtracking/Package0to1.java new file mode 100644 index 00000000..41a19c53 --- /dev/null +++ b/code/LeetCode/src/backtracking/Package0to1.java @@ -0,0 +1,30 @@ +package backtracking; + +public class Package0to1 { + public int maxW = Integer.MIN_VALUE; //存储背包中物品总重量的最大值 + + public static void main(String[] args) { + Package0to1 obj = new Package0to1(); + obj.maxW = Integer.MIN_VALUE; + int[] items = {1, 10, 12, 20, 5, 6, 8, 2, 15, 16, 18}; + obj.f(0, 0, items, 10, 100); + System.out.println("max weight is " + obj.maxW); + } + + // cw表示当前已经装进去的物品的重量和;i表示考察到哪个物品了; +// w背包重量;items表示每个物品的重量;n表示物品个数 +// 假设背包可承受重量100,物品个数10,物品重量存储在数组a中,那可以这样调用函数: +// f(0, 0, a, 10, 100) + public void f(int i, int cw, int[] items, int n, int w) { + if (cw == w || i == n) { // cw==w表示装满了;i==n表示已经考察完所有的物品 + if (cw > maxW) maxW = cw; + return; + } + f(i+1, cw, items, n, w); + if (cw + items[i] <= w) {// 已经超过可以背包承受的重量的时候,就不要再装了 + f(i+1,cw + items[i], items, n, w); + } + } + + +} From d0ea2468fc154b19c58b3ee9b87a40d333b382a9 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 17 Dec 2019 14:37:17 +0800 Subject: [PATCH 131/162] pattern --- code/LeetCode/src/backtracking/Pattern.java | 45 +++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 code/LeetCode/src/backtracking/Pattern.java diff --git a/code/LeetCode/src/backtracking/Pattern.java b/code/LeetCode/src/backtracking/Pattern.java new file mode 100644 index 00000000..ee4746d2 --- /dev/null +++ b/code/LeetCode/src/backtracking/Pattern.java @@ -0,0 +1,45 @@ +package backtracking; + + +public class Pattern { + public static void main(String[] args) { + Pattern obj = new Pattern("*aa?b".toCharArray(), 5); + boolean result = obj.match("bbaabbc".toCharArray(), 7); + boolean result1 = obj.match("bbaabb".toCharArray(), 6); + System.out.println("bbaabbc match *aa?b > " + result); + System.out.println("bbaabb match *aa?b > " + result1); + } + + private boolean matched = false; + private char[] pattern; // 正则表达式 + private int plen; // 正则表达式长度 + + public Pattern(char[] pattern, int plen) { + this.pattern = pattern; + this.plen = plen; + } + + public boolean match(char[] text, int tlen) { // 文本串及长度 + matched = false; + rmatch(0, 0, text, tlen); + return matched; + } + + private void rmatch(int ti, int pj, char[] text, int tlen) { + if (matched) return; // 如果已经匹配了,就不要继续递归了 + if (pj == plen) { // 正则表达式到结尾了 + if (ti == tlen) matched = true; // 文本串也到结尾了 + return; + } + if (pattern[pj] == '*') { // *匹配任意个字符 + for (int k = 0; k <= tlen-ti; ++k) { + rmatch(ti+k, pj+1, text, tlen); + } + } else if (pattern[pj] == '?') { // ?匹配0个或者1个字符 + rmatch(ti, pj+1, text, tlen); + rmatch(ti+1, pj+1, text, tlen); + } else if (ti < tlen && pattern[pj] == text[ti]) { // 纯字符匹配才行 + rmatch(ti+1, pj+1, text, tlen); + } + } +} From 8ca25ca8c814687d230f4be1ff42afb3a64d4489 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 17 Dec 2019 14:37:35 +0800 Subject: [PATCH 132/162] contest --- code/LeetCode/src/contest/Contest.java | 95 ++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 code/LeetCode/src/contest/Contest.java diff --git a/code/LeetCode/src/contest/Contest.java b/code/LeetCode/src/contest/Contest.java new file mode 100644 index 00000000..7a17c4c1 --- /dev/null +++ b/code/LeetCode/src/contest/Contest.java @@ -0,0 +1,95 @@ +package contest; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +public class Contest { + + public static void main(String[] args) { + + //test1(); + + //test2(); + + //test3(); + //help(); + + int k = 8; + int[] inputs = {7, 9, 8, 9}; + List aList = new ArrayList<>(); + for (int i: inputs) { + aList.add(i); + } + + + } + + static long count = 0; + + public static void help(int index, int k, List aList, long[] result) { + //Arrays.fill(result, 0); + if (index == aList.size()) { + long sum = 0; + for (long l: result) { + sum += l; + } + if (sum == k) { + count++; + } + return; + } + + result[index] = 0; + help(index + 1, k, aList, result); + result[index] = aList.get(index); + //help(index + 1, k, aList, result); + } + + + + public static void test3() { + String s = "125"; + long result = Long.parseLong(s); + int len = s.length(); + long[] longArray = new long[s.length()]; + for (int i = 1; i < s.length() - 1; i++) { + Arrays.fill(longArray, 0); + for (int j = 0; j < s.length(); j++) { + + } + } + } + + + public static void test2() { + long minX = 0; + long minY = 0; + int x = 1; + int y = 2; + + if (x > minX && y > minY) { + minX = x; + minY = y; + } else { + double mulX = 1; + double mulY = 1; + if (x > 0) { + mulX = Math.ceil(1.0 * minX / x); + } + if (y > 0) { + mulY = Math.ceil(1.0 * minY / y); + } + long mulMax = (long) Math.max(mulX, mulY); + minX = x * mulMax; + minY = y * mulMax; + } + + long result = minX + minY; + System.out.print(result); + } + + + +} From df960d3c53a5fe917ae708a2dab13855412092c0 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Wed, 18 Dec 2019 12:55:08 +0800 Subject: [PATCH 133/162] generate parentheses --- .../src/backtracking/GenerateParentheses.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 code/LeetCode/src/backtracking/GenerateParentheses.java diff --git a/code/LeetCode/src/backtracking/GenerateParentheses.java b/code/LeetCode/src/backtracking/GenerateParentheses.java new file mode 100644 index 00000000..4549c31c --- /dev/null +++ b/code/LeetCode/src/backtracking/GenerateParentheses.java @@ -0,0 +1,41 @@ +package backtracking; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +// https://leetcode.com/problems/generate-parentheses/ +public class GenerateParentheses { + + public static void main(String[] args) { + GenerateParentheses obj = new GenerateParentheses(); + List result = obj.generateParenthesis(3); + System.out.println("result > " + Arrays.toString(result.toArray())); + } + + public List generateParenthesis(int n) { + List result = new ArrayList<>(); + if (n <= 0) { + return result; + } + + helper(result, "", n, n); + + return result; + } + + public void helper(List result, String combine, int left, int right) { + //exit + if (left == 0 && right == 0) { + result.add(combine); + return; + } + + if (left > 0) { + helper(result, combine + '(', left - 1, right); + } + if (right > left) { + helper(result, combine + ')', left, right - 1); + } + } +} From 8452854cacbd6d5e7fe4527352b16f2155ea30d2 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 30 Dec 2019 07:35:40 +0800 Subject: [PATCH 134/162] conbinationsum --- .../src/backtracking/CombinationSum.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 code/LeetCode/src/backtracking/CombinationSum.java diff --git a/code/LeetCode/src/backtracking/CombinationSum.java b/code/LeetCode/src/backtracking/CombinationSum.java new file mode 100644 index 00000000..6202aa6b --- /dev/null +++ b/code/LeetCode/src/backtracking/CombinationSum.java @@ -0,0 +1,37 @@ +package backtracking; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +// https://leetcode.com/problems/combination-sum/ +public class CombinationSum { + + public static void main(String[] args) { + CombinationSum obj = new CombinationSum(); + int[] candicates = {2, 3, 6, 7}; + int target = 7; + List> resultList = obj.combinationSum(candicates, target); + System.out.println(Arrays.toString(resultList.toArray())); + } + + public List> combinationSum(int[] candidates, int target) { + List> resultList = new ArrayList<>(); + Arrays.sort(candidates); + recursive(candidates, target, 0, new ArrayList<>(), resultList); + + return resultList; + } + + public void recursive(int[] candidates, int target, int start, List list, List> resultList) { + if (target > 0) { + for (int i = start; i < candidates.length && target >= candidates[i]; i++) { + list.add(candidates[i]); + recursive(candidates, target - candidates[i], i, list, resultList); + list.remove(list.size() - 1); + } + } else if (target == 0) { + resultList.add(new ArrayList<>(list)); + } + } +} From ba82a0981faf0df642cc0500383d65a08c0457c4 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 31 Dec 2019 12:26:45 +0800 Subject: [PATCH 135/162] CombinationSumII --- .../src/backtracking/CombinationSumII.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 code/LeetCode/src/backtracking/CombinationSumII.java diff --git a/code/LeetCode/src/backtracking/CombinationSumII.java b/code/LeetCode/src/backtracking/CombinationSumII.java new file mode 100644 index 00000000..a35bb046 --- /dev/null +++ b/code/LeetCode/src/backtracking/CombinationSumII.java @@ -0,0 +1,40 @@ +package backtracking; + +import java.util.*; + +// https://leetcode.com/problems/combination-sum-ii/ +public class CombinationSumII { + + public static void main(String[] args) { + CombinationSumII obj = new CombinationSumII(); + int[] candidates = {10,1,2,7,6,1,5}; + int target = 8; + List> resultList = obj.combinationSum2(candidates, target); + System.out.println("resultList >> " + Arrays.toString(resultList.toArray())); + } + + public List> combinationSum2(int[] candidates, int target) { + List> resultList = new ArrayList<>(); + Arrays.sort(candidates); + recursive(candidates, target, resultList, new ArrayList(), 0); + + return resultList; + } + + public void recursive(int[] candidates, int target, List> resultList, List list, int start) { + if (target == 0) { + List newList = new ArrayList(list); + + resultList.add(newList); + } else if (target > 0) { + for (int i = start; i < candidates.length && target >= candidates[i]; i++) { + if (i > start && candidates[i] == candidates[i - 1]) { + continue; + } + list.add(candidates[i]); + recursive(candidates, target - candidates[i], resultList, list, i + 1); + list.remove(list.size() - 1); + } + } + } +} From 1b29e2952b95b2d9baae5b511cbba4d308e940ed Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 31 Dec 2019 12:48:43 +0800 Subject: [PATCH 136/162] add comment --- code/LeetCode/src/backtracking/CombinationSumII.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/code/LeetCode/src/backtracking/CombinationSumII.java b/code/LeetCode/src/backtracking/CombinationSumII.java index a35bb046..c65f4bd7 100644 --- a/code/LeetCode/src/backtracking/CombinationSumII.java +++ b/code/LeetCode/src/backtracking/CombinationSumII.java @@ -27,7 +27,10 @@ public void recursive(int[] candidates, int target, List> resultLi resultList.add(newList); } else if (target > 0) { - for (int i = start; i < candidates.length && target >= candidates[i]; i++) { + for (int i = start; i < candidates.length && target >= candidates[i]; i++) { + /* 表示第一个数字不能跟以前相同,比如这里有两个1,那么[1, 2, 5], [1,7],就会有两个。 + * 第一次以1开头,那么第二个就要以2开头。这里需要调试就能找到规律。 + */ if (i > start && candidates[i] == candidates[i - 1]) { continue; } From f60a6b9894cf9648186b04debd29d8d869011ecd Mon Sep 17 00:00:00 2001 From: zgpeace Date: Thu, 2 Jan 2020 07:39:38 +0800 Subject: [PATCH 137/162] =?UTF-8?q?=E8=A6=81=E4=B9=88=E9=80=89=E6=8B=A9?= =?UTF-8?q?=EF=BC=8C=E8=A6=81=E4=B8=8D=E4=B8=8D=E9=80=89=E6=8B=A9=EF=BC=8C?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=95=B0=E7=BB=84=E5=85=A8=E6=8E=92=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/backtracking/Permutations.java | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/code/LeetCode/src/backtracking/Permutations.java b/code/LeetCode/src/backtracking/Permutations.java index 73974b11..61c10190 100644 --- a/code/LeetCode/src/backtracking/Permutations.java +++ b/code/LeetCode/src/backtracking/Permutations.java @@ -9,10 +9,10 @@ public class Permutations { public static void main(String[] args) { Permutations obj = new Permutations(); - obj.permuteWithCleanRecursive(new int[]{1, 2, 3}); + obj.permuteWithIterate(new int[]{1, 2, 3}); } - public List> permuteWithCleanRecursive(int[] nums) { + public List> permuteWithIterate(int[] nums) { LinkedList> result = new LinkedList<>(); result.add(new ArrayList()); int size; @@ -56,4 +56,32 @@ private void addItemInAllPosition(int[] nums, int start, List list, Lis addItemInAllPosition(nums, start + 1, newList, result); } } + + + public List> permuteWithPickupOrNo(int[] nums) { + List> resultList = new ArrayList>(); + if (nums == null || nums.length == 0) { + return resultList; + } + + recursive(nums, new ArrayList(), resultList); + + return resultList; + } + + public void recursive(int[] nums, List list, List> resultList) { + if (list.size() == nums.length) { + resultList.add(new ArrayList(list)); + return; + } + + for(int item: nums) { + if (list.contains(item)) { + continue; + } + list.add(item); + recursive(nums, list, resultList); + list.remove(list.size() - 1); + } + } } From c8b1ae1d155513ab9c587f4d9beb23c6967a7b99 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Thu, 2 Jan 2020 11:28:23 +0800 Subject: [PATCH 138/162] permutations II --- .../src/backtracking/PermutationsII.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 code/LeetCode/src/backtracking/PermutationsII.java diff --git a/code/LeetCode/src/backtracking/PermutationsII.java b/code/LeetCode/src/backtracking/PermutationsII.java new file mode 100644 index 00000000..05f29a7e --- /dev/null +++ b/code/LeetCode/src/backtracking/PermutationsII.java @@ -0,0 +1,49 @@ +package backtracking; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +// https://leetcode.com/problems/permutations-ii/ +public class PermutationsII { + + public static void main(String[] args) { + PermutationsII obj = new PermutationsII(); + int[] input = {1,1,2}; + List> resultList = obj.permuteUnique(input); + System.out.println(Arrays.toString(resultList.toArray())); + } + + public List> permuteUnique(int[] nums) { + List> resultList = new ArrayList>(); + Arrays.sort(nums); + boolean[] used = new boolean[nums.length]; + if (nums == null || nums.length == 0) { + return resultList; + } + dfs(nums, resultList, new ArrayList(), used); + + return resultList; + } + + private void dfs(int[] nums, List> resultList, List list, boolean[] used) { + if (list.size() == nums.length) { + resultList.add(new ArrayList(list)); + return; + } + for (int i = 0; i < nums.length; i++) { + if (used[i]) { + continue; + } + if (i > 0 && nums[i] == nums[i - 1] && !used[i - 1]) { + continue; + } + used[i] = true; + list.add(nums[i]); + dfs(nums, resultList, list, used); + used[i] = false; + list.remove(list.size() - 1); + } + } +} From 029e01b7aed32c85f52ad7c71a1c8588158c3b39 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 3 Jan 2020 19:04:20 +0800 Subject: [PATCH 139/162] permutation sequence --- .../src/backtracking/PermutationSequence.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 code/LeetCode/src/backtracking/PermutationSequence.java diff --git a/code/LeetCode/src/backtracking/PermutationSequence.java b/code/LeetCode/src/backtracking/PermutationSequence.java new file mode 100644 index 00000000..7b1714ba --- /dev/null +++ b/code/LeetCode/src/backtracking/PermutationSequence.java @@ -0,0 +1,50 @@ +package backtracking; + +import java.util.ArrayList; +import java.util.List; + +// https://leetcode.com/problems/permutation-sequence/ +public class PermutationSequence { + + public static void main(String[] args) { + PermutationSequence obj = new PermutationSequence(); + String result = obj.getPermutation(4, 9); + System.out.println("result > " + result); + } + + public String getPermutation(int n, int k) { + // factorial + int[] factorial = new int[n + 1]; + factorial[0] = 1; + int sum = 1; + + // create an array of factorial lookup + for (int i = 1; i <= n; i++) { + sum *= i; + // factorial[] = {1, 1, 2, 6, 24, ..., n!} + factorial[i] = sum; + } + + // create a list of numbers to get indices + List items = new ArrayList(); + for (int i = 1; i <= n; i++) { + // numbers = {1, 2, 3, 4} + items.add(i); + } + + // i from 0, so k - 1 + k--; + + StringBuilder sb = new StringBuilder(); + // calculate + for (int i = 1; i <= n; i++) { + int index = k / factorial[n - i]; + int item = items.get(index); + sb.append(String.valueOf(item)); + items.remove(index); + k -= index * factorial[n - i]; + } + + return sb.toString(); + } +} From 37e2ffc47462d46fa416bf4e78d9da24d6bbdad8 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Sat, 4 Jan 2020 08:26:52 +0800 Subject: [PATCH 140/162] combinations --- .../src/backtracking/Combinations.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 code/LeetCode/src/backtracking/Combinations.java diff --git a/code/LeetCode/src/backtracking/Combinations.java b/code/LeetCode/src/backtracking/Combinations.java new file mode 100644 index 00000000..526eb336 --- /dev/null +++ b/code/LeetCode/src/backtracking/Combinations.java @@ -0,0 +1,67 @@ +package backtracking; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +// https://leetcode.com/problems/combinations/ +public class Combinations { + + public static void main(String[] args) { + Combinations obj = new Combinations(); + int n = 4; + int k = 2; + List> resultList = obj.combineBaseOnFormular(n , k); + System.out.println("resultList > " + Arrays.toString(resultList.toArray())); + } + + public List> combine(int n, int k) { + List> resultList = new ArrayList>(); + if (n == 0 || k == 0) { + return resultList; + } + + // dfs + dfs(n, k, resultList, new ArrayList(), 1); + + return resultList; + } + + public void dfs(int n, int k, List> resultList, List list, int start) { + if (k == 0) { + resultList.add(new ArrayList(list)); + return; + } + + for (int i = start; i <= n - k + 1; i++) { + // [1, 2], [1, 3], [1, 4] + // [2, 3], [2, 4] + // [3, 4] + list.add(i); + dfs(n, k - 1, resultList, list, i + 1); + list.remove(list.size() - 1); + } + } + + // based on C(n,k)=C(n-1,k-1)+C(n-1,k) + public List> combineBaseOnFormular(int n, int k) { + List> resultList = new LinkedList>(); + if (n < k || k == 0) { + return resultList; + } + resultList = combineBaseOnFormular(n - 1, k - 1); + // if at this point resultList is empty, it can only be that k - 1 == 0, + // n - 1 < k - 1 is not possible since n >= k (if n < k, the function would have already returned at an early point) + if (resultList.isEmpty()) { + resultList.add(new LinkedList()); + } + for (List list: resultList) { + list.add(n); + } + + resultList.addAll(combineBaseOnFormular(n - 1, k)); + + return resultList; + } +} From d089e6d3c54b2206c69b76c36a8f0b7f74ab2852 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Sun, 5 Jan 2020 08:17:57 +0800 Subject: [PATCH 141/162] plus --- .../src/backtracking/AddPlusSymbol.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 code/LeetCode/src/backtracking/AddPlusSymbol.java diff --git a/code/LeetCode/src/backtracking/AddPlusSymbol.java b/code/LeetCode/src/backtracking/AddPlusSymbol.java new file mode 100644 index 00000000..d90e0a49 --- /dev/null +++ b/code/LeetCode/src/backtracking/AddPlusSymbol.java @@ -0,0 +1,50 @@ +package backtracking; + +import java.util.ArrayList; +import java.util.List; + +public class AddPlusSymbol { + + public static void main(String[] args) { + AddPlusSymbol obj = new AddPlusSymbol(); + String input1 = "125"; + Long result1 = obj.addPlus(input1); + System.out.println("input > " + input1 + " ; result > " + result1); + String input2 = "9999999999"; + Long result2 = obj.addPlus(input2); + System.out.println("input > " + input2 + " ; result > " + result2); + } + + public long addPlus(String input) { + if (input == null || input.length() == 0) { + return 0; + } + + long result = 0; + List resultList = new ArrayList(); + char[] chars = input.toCharArray(); + // dfs + dfs(chars, resultList, "", 0); + + // loop list sum + for (String s: resultList) { + String[] nums = s.split("\\+"); + for (String n: nums) { + result += Long.parseLong(n); + } + } + + return result; + } + + private void dfs(char[] chars, List resultList, String s, int start) { + // exit + if (start == chars.length - 1) { + resultList.add(s + chars[chars.length - 1]); + return; + } + s += chars[start]; + dfs(chars, resultList, s + '+', start + 1); + dfs(chars, resultList, s, start + 1); + } +} From 60bbfc032b9378b4cb7db6dc17b9d922ed9da4ab Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 6 Jan 2020 08:07:36 +0800 Subject: [PATCH 142/162] pickup cards --- .../src/backtracking/PickupCards.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 code/LeetCode/src/backtracking/PickupCards.java diff --git a/code/LeetCode/src/backtracking/PickupCards.java b/code/LeetCode/src/backtracking/PickupCards.java new file mode 100644 index 00000000..c141b2c8 --- /dev/null +++ b/code/LeetCode/src/backtracking/PickupCards.java @@ -0,0 +1,56 @@ +package backtracking; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +// https://ac.nowcoder.com/acm/contest/3286/D +public class PickupCards { + + public static void main(String[] args) { + PickupCards obj = new PickupCards(); + //int[] inputs = {7, 9, 8, 9}; + //int target = 8; + int[] inputs = {3, 6, 2, 8, 7, 6, 5, 9}; + int target = 5; + int result = obj.pickupCards(inputs, target); + + System.out.println("result > " + result); + } + + public int pickupCards(int[] inputs, int target) { + // check edges + if (inputs == null || inputs.length == 0) { + return 0; + } + List> resultList = new ArrayList>(); + Arrays.sort(inputs); + List list = new ArrayList(); + //dfs + dfs(inputs, resultList, list, 0, target); + + return resultList.size(); + } + + private void dfs(int[] inputs, List> resultList, List list, int start, int target) { + // exit condition + long sum = 0; + for (int item: list) { + sum += item; + } + if (list.size() != 0 && sum / list.size() == target && sum % list.size() == 0) { + System.out.println(Arrays.toString(list.toArray())); + resultList.add(new ArrayList(list)); + return; + } + + if (start >= inputs.length) { + return; + } + + list.add(inputs[start]); + dfs(inputs, resultList, list, start + 1, target); + list.remove(list.size() - 1); + dfs(inputs, resultList, list, start + 1, target); + } +} From 1eb63ee5f0c742f66ca2df4f0532c8cb6b092cd1 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 6 Jan 2020 12:50:51 +0800 Subject: [PATCH 143/162] subsets --- code/LeetCode/src/backtracking/Subsets.java | 40 +++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 code/LeetCode/src/backtracking/Subsets.java diff --git a/code/LeetCode/src/backtracking/Subsets.java b/code/LeetCode/src/backtracking/Subsets.java new file mode 100644 index 00000000..f9fb14b8 --- /dev/null +++ b/code/LeetCode/src/backtracking/Subsets.java @@ -0,0 +1,40 @@ +package backtracking; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +// https://leetcode.com/problems/subsets/ +public class Subsets { + + public static void main(String[] args) { + int[] nums = new int[]{1,2,3}; + Subsets obj = new Subsets(); + List> resultList = obj.subsets(nums); + System.out.println(Arrays.toString(resultList.toArray())); + } + + public List> subsets(int[] nums) { + List> resultList = new ArrayList>(); + // dfs + dfs(nums, resultList, new ArrayList(), 0); + + return resultList; + } + + private void dfs(int[] nums, List> resultList, List list, int index) { + // exit + if (nums == null || index == nums.length) { + resultList.add(new ArrayList(list)); + return; + } + + // add item + list.add(nums[index]); + dfs(nums, resultList, list, index + 1); + + // not add item + list.remove(list.size() - 1); + dfs(nums, resultList, list, index + 1); + } +} From 5e60d767777402a3f961e262e8d7e7a595336862 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 7 Jan 2020 08:49:32 +0800 Subject: [PATCH 144/162] subsets add iterate, backtrack, binary sorted --- code/LeetCode/src/backtracking/Subsets.java | 72 ++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/code/LeetCode/src/backtracking/Subsets.java b/code/LeetCode/src/backtracking/Subsets.java index f9fb14b8..c5a57aad 100644 --- a/code/LeetCode/src/backtracking/Subsets.java +++ b/code/LeetCode/src/backtracking/Subsets.java @@ -1,5 +1,6 @@ package backtracking; +import javax.annotation.Resource; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -10,7 +11,10 @@ public class Subsets { public static void main(String[] args) { int[] nums = new int[]{1,2,3}; Subsets obj = new Subsets(); - List> resultList = obj.subsets(nums); + //List> resultList = obj.subsets(nums); + //List> resultList = obj.subsetsWithRecursion(nums); + //List> resultList = obj.subsetsWithBacktrack(nums); + List> resultList = obj.subsetsWithBinarySorted(nums); System.out.println(Arrays.toString(resultList.toArray())); } @@ -37,4 +41,70 @@ private void dfs(int[] nums, List> resultList, List list, list.remove(list.size() - 1); dfs(nums, resultList, list, index + 1); } + + + public List> subsetsWithRecursion(int[] nums) { + List> outputList = new ArrayList>(); + outputList.add(new ArrayList()); + for (int num: nums) { + List> newList = new ArrayList>(); + for (List list: outputList) { + newList.add(new ArrayList(list) {{ add(num); }}); + } + + for (List list: newList) { + outputList.add(list); + } + } + + return outputList; + } + + public List> subsetsWithBacktrack(int[] nums) { + List> resultList = new ArrayList>(); + for (int len = 0; len <= nums.length; len++) { + // backtrack + backtrack(nums, resultList, new ArrayList(), 0, len); + } + + return resultList; + } + + private void backtrack(int[] nums, List> resultList, List list, int first, int len) { + // exit + if (list.size() == len) { + resultList.add(new ArrayList(list)); + return; + } + + if (first == nums.length) { + return; + } + list.add(nums[first]); + backtrack(nums, resultList, list, first + 1, len); + list.remove(list.size() - 1); + backtrack(nums, resultList, list, first + 1, len); + } + + public List> subsetsWithBinarySorted(int[] nums) { + List> resultList = new ArrayList>(); + int n = nums.length; + + for (int i = (int)Math.pow(2, n); i < (int)Math.pow(2, n + 1); i++) { + // generate bitmask, from 0..00 to 1..11 + String bitmask = Integer.toBinaryString(i).substring(1); + + // append subset corresponding to that bitmask + List list = new ArrayList(); + for (int k = 0; k < n; k++) { + if (bitmask.charAt(k) == '1') { + list.add(nums[k]); + } + } + + resultList.add(list); + } + + return resultList; + } } From a3b309d2034e9360ad6b737da704e4f6eeed7a5f Mon Sep 17 00:00:00 2001 From: zgpeace Date: Wed, 8 Jan 2020 08:23:21 +0800 Subject: [PATCH 145/162] word search --- .../LeetCode/src/backtracking/WordSearch.java | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 code/LeetCode/src/backtracking/WordSearch.java diff --git a/code/LeetCode/src/backtracking/WordSearch.java b/code/LeetCode/src/backtracking/WordSearch.java new file mode 100644 index 00000000..5f2eae00 --- /dev/null +++ b/code/LeetCode/src/backtracking/WordSearch.java @@ -0,0 +1,65 @@ +package backtracking; + +// https://leetcode.com/problems/word-search/ +public class WordSearch { + + public static void main(String[] args) { + WordSearch obj = new WordSearch(); + char[][] board = {{'A','B','C','E'}, + {'S','F','C','S'}, + {'A','D','E','E'}}; + //String word = "ABCCED"; + //String word = "SEE"; + String word = "ABCB"; + boolean result = obj.exist(board, word); + System.out.println("result > " + result); + } + + public boolean exist(char[][] board, String word) { + // check edge + if (word == null || word.length() == 0) { + return true; + } + if (board == null || board.length == 0 || board[0].length == 0) { + return false; + } + // used boolean + boolean[][] used = new boolean[board.length][board[0].length]; + + // dfs + for (int row = 0; row < board.length; row++) { + for (int col = 0; col < board[row].length; col++) { + if (dfs(board, word, used, row, col, 0)) { + return true; + } + } + } + + + return false; + } + + private boolean dfs(char[][] board, String word, boolean[][] used, int row, int col, int wordIndex) { + if (word == null || wordIndex == word.length()) { + return true; + } + char currentChar = word.charAt(wordIndex); + if (row < 0 || col < 0 + || row >= board.length || col >= board[row].length + || currentChar != board[row][col] || used[row][col]) + { + return false; + } + // mark use + used[row][col] = true; + boolean result = dfs(board, word, used, row + 1, col, wordIndex + 1) + || dfs(board, word, used, row - 1, col, wordIndex + 1) + || dfs(board, word, used, row, col + 1, wordIndex + 1) + || dfs(board, word, used, row, col - 1, wordIndex + 1); + + // mark not use + used[row][col] = false; + + return result; + } +} From 8c1c93a61ef1f63b638d1f4691115efb5e078ba8 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Thu, 9 Jan 2020 07:49:14 +0800 Subject: [PATCH 146/162] gray code --- code/LeetCode/src/backtracking/GrayCode.java | 24 ++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 code/LeetCode/src/backtracking/GrayCode.java diff --git a/code/LeetCode/src/backtracking/GrayCode.java b/code/LeetCode/src/backtracking/GrayCode.java new file mode 100644 index 00000000..f6005355 --- /dev/null +++ b/code/LeetCode/src/backtracking/GrayCode.java @@ -0,0 +1,24 @@ +package backtracking; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +// https://leetcode.com/problems/gray-code/ +public class GrayCode { + + public static void main(String[] args) { + GrayCode obj = new GrayCode(); + List result = obj.grayCode(2); + System.out.println(Arrays.toString(result.toArray())); + } + + public List grayCode(int n) { + List result = new ArrayList<>(); + for (int i = 0; i < (1<> 1)); + } + + return result; + } +} From f91a968fcc1a3c6c45c07e4ef9d42eaab3913b92 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 10 Jan 2020 12:53:55 +0800 Subject: [PATCH 147/162] subsets II --- code/LeetCode/src/backtracking/SubsetsII.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 code/LeetCode/src/backtracking/SubsetsII.java diff --git a/code/LeetCode/src/backtracking/SubsetsII.java b/code/LeetCode/src/backtracking/SubsetsII.java new file mode 100644 index 00000000..2ce6cae4 --- /dev/null +++ b/code/LeetCode/src/backtracking/SubsetsII.java @@ -0,0 +1,67 @@ +package backtracking; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +// https://leetcode.com/problems/subsets-ii/ +public class SubsetsII { + + public static void main(String[] args) { + int[] nums = {1,2,2}; + SubsetsII obj = new SubsetsII(); + List> resultList = obj.subsetsWithDup(nums); + System.out.println(Arrays.toString(resultList.toArray())); + } + + public List> subsetsWithDup(int[] nums) { + Arrays.sort(nums); + List> resultList = new ArrayList>(); + // dfs + dfs(nums, resultList, new ArrayList(), 0); + + return resultList; + } + + private void dfs(int[] nums, List> resultList, List list, int start) { + if (start <= nums.length) { + resultList.add(list); + } + int i = start; + while (i < nums.length) { + list.add(nums[i]); + dfs(nums, resultList, new ArrayList(list), i + 1); + + list.remove(list.size() - 1); + i++; + while (i < nums.length && nums[i] == nums[i - 1]) { + i++; + } + } + + } + + // still have some duplicate data + //private void dfs1(int[] nums, List> resultList, List list, int start) { + // // exit + // if (start == nums.length) { + // resultList.add(new ArrayList<>(list)); + // return; + // } + // + // for (int i = start; i < nums.length; i++) { + // // duplicate case + // if (i > start && nums[i] == nums[i - 1]) { + // continue; + // } + // + // // pick up + // list.add(nums[i]); + // dfs(nums, resultList, list, i + 1); + // + // // not pick up + // list.remove(list.size() - 1); + // dfs(nums, resultList, list, i + 1); + // } + //} +} From f872f34ff6a5fb8462e5cbba8675dc3709e105a9 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Sun, 12 Jan 2020 08:42:04 +0800 Subject: [PATCH 148/162] add iterate, add recursive with for loop method --- code/LeetCode/src/backtracking/SubsetsII.java | 76 +++++++++++++------ 1 file changed, 51 insertions(+), 25 deletions(-) diff --git a/code/LeetCode/src/backtracking/SubsetsII.java b/code/LeetCode/src/backtracking/SubsetsII.java index 2ce6cae4..875ae60b 100644 --- a/code/LeetCode/src/backtracking/SubsetsII.java +++ b/code/LeetCode/src/backtracking/SubsetsII.java @@ -10,7 +10,8 @@ public class SubsetsII { public static void main(String[] args) { int[] nums = {1,2,2}; SubsetsII obj = new SubsetsII(); - List> resultList = obj.subsetsWithDup(nums); + //List> resultList = obj.subsetsWithDup(nums); + List> resultList = obj.subsetsWithDupIterate(nums); System.out.println(Arrays.toString(resultList.toArray())); } @@ -18,7 +19,9 @@ public List> subsetsWithDup(int[] nums) { Arrays.sort(nums); List> resultList = new ArrayList>(); // dfs - dfs(nums, resultList, new ArrayList(), 0); + //dfs(nums, resultList, new ArrayList(), 0); + dfsWithFor(nums, resultList, new ArrayList(), 0); + //subsetsWithDupHelper(nums, resultList, new ArrayList(), 0); return resultList; } @@ -41,27 +44,50 @@ private void dfs(int[] nums, List> resultList, List list, } - // still have some duplicate data - //private void dfs1(int[] nums, List> resultList, List list, int start) { - // // exit - // if (start == nums.length) { - // resultList.add(new ArrayList<>(list)); - // return; - // } - // - // for (int i = start; i < nums.length; i++) { - // // duplicate case - // if (i > start && nums[i] == nums[i - 1]) { - // continue; - // } - // - // // pick up - // list.add(nums[i]); - // dfs(nums, resultList, list, i + 1); - // - // // not pick up - // list.remove(list.size() - 1); - // dfs(nums, resultList, list, i + 1); - // } - //} + private void dfsWithFor(int[] nums, List> resultList, List list, int start) { + // exit + if (start <= nums.length) { + resultList.add(new ArrayList<>(list)); + } + + for (int i = start; i < nums.length; i++) { + // duplicate case + if (i > start && nums[i] == nums[i - 1]) { + continue; + } + + // pick up + list.add(nums[i]); + dfsWithFor(nums, resultList, list, i + 1); + + // not pick up + list.remove(list.size() - 1); + } + } + + public List> subsetsWithDupIterate(int[] nums) { + Arrays.sort(nums); + List> resultList = new ArrayList>(); + List list = new ArrayList(); + resultList.add(list); + + int duplicateStart = 0; + for (int i = 0; i < nums.length; i++) { + int begin = 0; + int size = resultList.size(); + if (i > 0 && nums[i] == nums[i - 1]) { + begin = duplicateStart; + } + + for (int k = begin; k < size; k++) { + List newList = new ArrayList(resultList.get(k)); + newList.add(nums[i]); + resultList.add(newList); + } + + duplicateStart = size; + } + + return resultList; + } } From 2c7cf2ecfc99ea6b15635771db49c04c8c21fce8 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 13 Jan 2020 08:12:26 +0800 Subject: [PATCH 149/162] restore ip address --- .../src/backtracking/RestoreIPAddress.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 code/LeetCode/src/backtracking/RestoreIPAddress.java diff --git a/code/LeetCode/src/backtracking/RestoreIPAddress.java b/code/LeetCode/src/backtracking/RestoreIPAddress.java new file mode 100644 index 00000000..334464a9 --- /dev/null +++ b/code/LeetCode/src/backtracking/RestoreIPAddress.java @@ -0,0 +1,50 @@ +package backtracking; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +// https://leetcode.com/problems/restore-ip-addresses/ +public class RestoreIPAddress { + + public static void main(String[] args) { + RestoreIPAddress obj = new RestoreIPAddress(); + String s = "25525511135"; + List resultList = obj.restoreIpAddresses(s); + System.out.println(Arrays.toString(resultList.toArray())); + } + + public List restoreIpAddresses(String s) { + List resultList = new ArrayList(); + if (s == null || s.length() < 4) { + return resultList; + } + + // DFS + dfs(resultList, s, 0, "", 0); + + return resultList; + } + + private void dfs(List resultList, String s, int start, String stored, int count) { + //exit + if (start == s.length() && count == 4) { + resultList.add(stored); + } + + if (start == s.length() || count == 4) { + return; + } + + for (int i = 1; i < 4; i++) { + if (start + i > s.length()) { + break; + } + String part = s.substring(start, start + i); + if ((part.startsWith("0") && part.length() > 1) || (i == 3 && Integer.valueOf(part) > 255)) { + continue; + } + dfs(resultList, s, start + i, stored + part + (count == 3 ? "" : "."), count + 1); + } + } +} From 433a8ffcee91d84333ae4175087492a7f4c709c0 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 13 Jan 2020 12:45:02 +0800 Subject: [PATCH 150/162] Restore IP Address, iterate solution --- .../src/backtracking/RestoreIPAddress.java | 44 ++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/code/LeetCode/src/backtracking/RestoreIPAddress.java b/code/LeetCode/src/backtracking/RestoreIPAddress.java index 334464a9..2e2ed377 100644 --- a/code/LeetCode/src/backtracking/RestoreIPAddress.java +++ b/code/LeetCode/src/backtracking/RestoreIPAddress.java @@ -10,7 +10,8 @@ public class RestoreIPAddress { public static void main(String[] args) { RestoreIPAddress obj = new RestoreIPAddress(); String s = "25525511135"; - List resultList = obj.restoreIpAddresses(s); + //List resultList = obj.restoreIpAddresses(s); + List resultList = obj.restoreIpAddressesWithIterate(s); System.out.println(Arrays.toString(resultList.toArray())); } @@ -32,7 +33,7 @@ private void dfs(List resultList, String s, int start, String stored, in resultList.add(stored); } - if (start == s.length() || count == 4) { + if (start >= s.length() || count == 4) { return; } @@ -47,4 +48,43 @@ private void dfs(List resultList, String s, int start, String stored, in dfs(resultList, s, start + i, stored + part + (count == 3 ? "" : "."), count + 1); } } + + + public List restoreIpAddressesWithIterate(String s) { + List resultList = new ArrayList(); + if (s == null || s.length() < 4) { + return resultList; + } + + int len = s.length(); + String splitS = "."; + // iterate + for (int fisrt = 1; fisrt < 4 && fisrt < len - 2; fisrt++) { + for (int second = fisrt + 1; second < fisrt + 4 && second < len - 1; second++) { + for (int third = second + 1; third < second + 4 && third < len; third++) { + String part1 = s.substring(0, fisrt); + String part2 = s.substring(fisrt, second); + String part3 = s.substring(second, third); + String part4 = s.substring(third); + if (valideIP(part1) && valideIP(part2) && valideIP(part3) && valideIP(part4)) { + String result = part1 + splitS + part2 + splitS + part3 + splitS + part4; + resultList.add(result); + } + } + } + + } + + return resultList; + } + + private Boolean valideIP(String part) { + if (part.length() == 0 || part.length() > 3 + || (part.startsWith("0") && part.length() != 1) + || (part.length() == 3 && Integer.valueOf(part) > 255 )) { + return false; + } + + return true; + } } From 04e2c00a7016a7570f7def4ddbc74fed7ecf5d24 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Fri, 17 Jan 2020 12:43:59 +0800 Subject: [PATCH 151/162] palindrome partitioning --- .../backtracking/PalindromePartitioning.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 code/LeetCode/src/backtracking/PalindromePartitioning.java diff --git a/code/LeetCode/src/backtracking/PalindromePartitioning.java b/code/LeetCode/src/backtracking/PalindromePartitioning.java new file mode 100644 index 00000000..3ce78782 --- /dev/null +++ b/code/LeetCode/src/backtracking/PalindromePartitioning.java @@ -0,0 +1,56 @@ +package backtracking; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +// https://leetcode.com/problems/palindrome-partitioning/ +public class PalindromePartitioning { + + public static void main(String[] args) { + String s = "aab"; + PalindromePartitioning obj = new PalindromePartitioning(); + List> resultList = obj.partition(s); + System.out.println(Arrays.toString(resultList.toArray())); + } + + public List> partition(String s) { + List> resultList = new ArrayList>(); + // dfs + dfs(s, 0, resultList, new ArrayList()); + + return resultList; + } + + private void dfs(String s, int start, List> resultList, List list) { + // exit + if (start >= s.length()) { + resultList.add(new ArrayList(list)); + return; + } + + // for + for (int i = start; i < s.length(); i++) { + + // isPalindrome + if (isPal(s, start, i)) { + // add + list.add(s.substring(start, i + 1)); + dfs(s, i + 1, resultList, list); + + // not add + list.remove(list.size() - 1); + } + } + } + + private boolean isPal(String s, int l, int r) { + while (l < r) { + if (s.charAt(l++) != s.charAt(r--)) { + return false; + } + } + + return true; + } +} From 3ac5ff24eb5bcfd2857be1e72b5cd5cd838d6105 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Sun, 19 Jan 2020 08:41:44 +0800 Subject: [PATCH 152/162] dp solution for palindrome partitioning --- .../backtracking/PalindromePartitioning.java | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/code/LeetCode/src/backtracking/PalindromePartitioning.java b/code/LeetCode/src/backtracking/PalindromePartitioning.java index 3ce78782..594bcbca 100644 --- a/code/LeetCode/src/backtracking/PalindromePartitioning.java +++ b/code/LeetCode/src/backtracking/PalindromePartitioning.java @@ -1,8 +1,6 @@ package backtracking; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.*; // https://leetcode.com/problems/palindrome-partitioning/ public class PalindromePartitioning { @@ -10,7 +8,8 @@ public class PalindromePartitioning { public static void main(String[] args) { String s = "aab"; PalindromePartitioning obj = new PalindromePartitioning(); - List> resultList = obj.partition(s); + //List> resultList = obj.partition(s); + List> resultList = obj.partitionWithDP(s); System.out.println(Arrays.toString(resultList.toArray())); } @@ -53,4 +52,30 @@ private boolean isPal(String s, int l, int r) { return true; } + + public List> partitionWithDP(String s) { + int len = s.length(); + List>[] results = new List[len + 1]; + results[0] = new ArrayList>(); + results[0].add(new ArrayList()); + + boolean[][] pair = new boolean[len][len]; + for (int i = 0; i < len; i++) { + results[i + 1] = new ArrayList>(); + for (int left = 0; left <= i; left++) { + if (s.charAt(left) == s.charAt(i) && (i-left <= 1 || pair[left + 1][i - 1])) { + pair[left][i] = true; + String sub = s.substring(left, i + 1); + for (List list: results[left]) { + List newList = new ArrayList(list); + newList.add(sub); + results[i + 1].add(newList); + } + } + } + + } + + return results[len]; + } } From 70e28c756cf4da949e8f2a247ce03cd38035bb32 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Mon, 20 Jan 2020 12:53:46 +0800 Subject: [PATCH 153/162] word dictionary --- .../src/backtracking/WordDictionary.java | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 code/LeetCode/src/backtracking/WordDictionary.java diff --git a/code/LeetCode/src/backtracking/WordDictionary.java b/code/LeetCode/src/backtracking/WordDictionary.java new file mode 100644 index 00000000..3bd1b2e9 --- /dev/null +++ b/code/LeetCode/src/backtracking/WordDictionary.java @@ -0,0 +1,100 @@ +package backtracking; + +// https://leetcode.com/problems/add-and-search-word-data-structure-design/ + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * Your WordDictionary object will be instantiated and called as such: + * WordDictionary obj = new WordDictionary(); + * obj.addWord(word); + * boolean param_2 = obj.search(word); + */ +public class WordDictionary { + + private class TrieNode { + private boolean isWord; + private Map childMap; + + public TrieNode() { + isWord = false; + childMap = new HashMap(); + } + + } + + private TrieNode root; + + /** Initialize your data structure here. */ + public WordDictionary() { + root = new TrieNode(); + } + + /** Adds a word into the data structure. */ + public void addWord(String word) { + TrieNode curr = root; + for (char c: word.toCharArray()) { + if (!curr.childMap.containsKey(c)) { + curr.childMap.put(c, new TrieNode()); + } + curr = curr.childMap.get(c); + } + + curr.isWord = true; + } + + /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */ + public boolean search(String word) { + return dfs(word,0, root); + } + + public boolean dfs(String word, int pos, TrieNode node) { + // if the word has all been scanned, return + if (pos == word.length()) { + return node.isWord; + } + // reach the leaf before finishing scanning the word + if (node.childMap.size() == 0) { + return false; + } + + Character c = word.charAt(pos); + // if the character at current position is '.', + // recursive check whether the remaining word is in the trie + if (c == '.') { + for (char item: node.childMap.keySet()) { + if (dfs(word, pos + 1, node.childMap.get(item))) { + return true; + } + } + } + + // if character at position 'pos' is neither equal to the node nor '.', return false + if (!node.childMap.containsKey(c)) { + return false; + } + + // if character at current position matches the node, + // recursively search the remaining word + return dfs(word, pos + 1, node.childMap.get(c)); + } + + public static void main(String[] args) { + WordDictionary obj = new WordDictionary(); + obj.addWord("bad"); + obj.addWord("dad"); + obj.addWord("mad"); + obj.addWord("a"); + System.out.println(obj.search("pad")); + System.out.println(obj.search("bad")); + System.out.println(obj.search(".ad")); + System.out.println(obj.search("b..")); + //obj.search("pad") -> false + //obj.search("bad") -> true + //obj.search(".ad") -> true + //obj.search("b..") -> true + } +} From 298d86ef11ef944834e73e629b0fcd625d3c108c Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 21 Jan 2020 09:44:43 +0800 Subject: [PATCH 154/162] combination sum III --- .../src/backtracking/CombinationSumIII.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 code/LeetCode/src/backtracking/CombinationSumIII.java diff --git a/code/LeetCode/src/backtracking/CombinationSumIII.java b/code/LeetCode/src/backtracking/CombinationSumIII.java new file mode 100644 index 00000000..e6b92758 --- /dev/null +++ b/code/LeetCode/src/backtracking/CombinationSumIII.java @@ -0,0 +1,44 @@ +package backtracking; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +// https://leetcode.com/problems/combination-sum-iii/ +public class CombinationSumIII { + + public static void main(String[] args) { + int k = 3; + int n = 9; + CombinationSumIII obj = new CombinationSumIII(); + List> resultList = obj.combinationSum3(k ,n); + System.out.println(Arrays.toString(resultList.toArray())); + } + + public List> combinationSum3(int k, int n) { + List> resultList = new ArrayList>(); + // dfs + dfs(resultList, new ArrayList(), k, n, 1); + + return resultList; + } + + private void dfs(List> resultList, List list, int k, int sum, int start) { + if (sum == 0 && k == 0) { + resultList.add(new ArrayList(list)); + return; + } + if (sum < 0 || start > 9) { + return; + } + for (int i = start; i <= 9; i++) { + // add num + list.add(i); + dfs(resultList, list, k - 1, sum - i, i + 1); + + // not add num + list.remove(list.size() - 1); + } + } + +} From ee319cecfe255489f8f15e61dacfb4201cf6e4e7 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Tue, 21 Jan 2020 09:46:13 +0800 Subject: [PATCH 155/162] reduce unnecessary condition --- code/LeetCode/src/backtracking/CombinationSumIII.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/LeetCode/src/backtracking/CombinationSumIII.java b/code/LeetCode/src/backtracking/CombinationSumIII.java index e6b92758..b0f351da 100644 --- a/code/LeetCode/src/backtracking/CombinationSumIII.java +++ b/code/LeetCode/src/backtracking/CombinationSumIII.java @@ -28,7 +28,7 @@ private void dfs(List> resultList, List list, int k, int resultList.add(new ArrayList(list)); return; } - if (sum < 0 || start > 9) { + if (sum < 0) { return; } for (int i = start; i <= 9; i++) { From 078411aa7c1e9630ee35cfbbf85bea4fab00b878 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Thu, 23 Jan 2020 08:27:55 +0800 Subject: [PATCH 156/162] factor combinations --- .../src/backtracking/FactorCombinations.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 code/LeetCode/src/backtracking/FactorCombinations.java diff --git a/code/LeetCode/src/backtracking/FactorCombinations.java b/code/LeetCode/src/backtracking/FactorCombinations.java new file mode 100644 index 00000000..1892e08c --- /dev/null +++ b/code/LeetCode/src/backtracking/FactorCombinations.java @@ -0,0 +1,59 @@ +package backtracking; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +// https://leetcode.com/problems/factor-combinations/ +public class FactorCombinations { + + public static void main(String[] args) { + FactorCombinations obj = new FactorCombinations(); + int n = 12; + List> resultList = obj.getFactors(12); + System.out.println(Arrays.toString(resultList.toArray())); + } + + public List> getFactors(int n) { + List> resultList = new ArrayList>(); + // DFS + //dfs(resultList, new ArrayList(), n, 2); + dfs1(resultList, new ArrayList(), n, 2); + + return resultList; + } + + private void dfs(List> resultList, List list, int n, int start) { + // exit + if (n == 1) { + if (list.size() > 1) { + resultList.add(new ArrayList(list)); + } + + return; + } + + for (int i = start; i <= n; i++) { + if (n % i == 0) { + list.add(i); + dfs(resultList, list, n / i, i); + + list.remove(list.size() - 1); + } + } + } + + + private void dfs1(List> resultList, List list, int n, int start) { + for (int i = start; i * i < n; i++) { + if (n % i == 0) { + List newList = new ArrayList(list); + newList.add(i); + dfs1(resultList, newList, n / i, i); + + newList.add(n / i); + resultList.add(new ArrayList(newList)); + } + } + } +} From 86b5e2a01b74db8f07bd246137651db0c27bd3f8 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Thu, 23 Jan 2020 09:10:10 +0800 Subject: [PATCH 157/162] add remove method to reach the otherwise way --- .../src/backtracking/FactorCombinations.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/code/LeetCode/src/backtracking/FactorCombinations.java b/code/LeetCode/src/backtracking/FactorCombinations.java index 1892e08c..e4fe0f47 100644 --- a/code/LeetCode/src/backtracking/FactorCombinations.java +++ b/code/LeetCode/src/backtracking/FactorCombinations.java @@ -18,7 +18,8 @@ public List> getFactors(int n) { List> resultList = new ArrayList>(); // DFS //dfs(resultList, new ArrayList(), n, 2); - dfs1(resultList, new ArrayList(), n, 2); + //dfs1(resultList, new ArrayList(), n, 2); + dfs2(resultList, new ArrayList(), n, 2); return resultList; } @@ -52,7 +53,21 @@ private void dfs1(List> resultList, List list, int n, int dfs1(resultList, newList, n / i, i); newList.add(n / i); - resultList.add(new ArrayList(newList)); + resultList.add(newList); + } + } + } + + private void dfs2(List> resultList, List list, int n, int start) { + for (int i = start; i * i < n; i++) { + if (n % i == 0) { + list.add(i); + dfs2(resultList, list, n / i, i); + + list.add(n / i); + resultList.add(new ArrayList(list)); + list.remove(list.size() - 1); + list.remove(list.size() - 1); } } } From 5728b0faaaa1dc9e50efe2e61b8820b6d468f5c7 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Sun, 14 Jun 2020 16:08:44 +0800 Subject: [PATCH 158/162] update common ListNode --- code/LeetCode/src/common/ListNode.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/LeetCode/src/common/ListNode.java b/code/LeetCode/src/common/ListNode.java index 76bad308..6bf38476 100644 --- a/code/LeetCode/src/common/ListNode.java +++ b/code/LeetCode/src/common/ListNode.java @@ -3,8 +3,8 @@ public class ListNode { public int val; public ListNode next; - public ListNode(int x) { - val = x; + public ListNode(int val) { + this.val = val; } static public ListNode listNodeWithIntArray(int[] input) { From cd111ed8feec4a86e03607211a96d2337926a7cc Mon Sep 17 00:00:00 2001 From: zgpeace Date: Sun, 14 Jun 2020 16:09:04 +0800 Subject: [PATCH 159/162] add print structure in treeNode --- code/LeetCode/src/common/TreeNode.java | 84 +++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/code/LeetCode/src/common/TreeNode.java b/code/LeetCode/src/common/TreeNode.java index 5686ec4c..d89ee75f 100644 --- a/code/LeetCode/src/common/TreeNode.java +++ b/code/LeetCode/src/common/TreeNode.java @@ -1,11 +1,91 @@ package common; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + public class TreeNode { public int val; public TreeNode left; public TreeNode right; - public TreeNode(int x) { - val = x; + public TreeNode() { } + public TreeNode(int val) { + this.val = val; + } + + public TreeNode(int val, TreeNode left, TreeNode right) { + this.val = val; + this.left = left; + this.right = right; } + @Override + public String toString() { + if (this == null) { + return "null"; + } + + String result = ""; + List row = null; + List> list = new ArrayList>(); + + LinkedList rowNode = new LinkedList<>(); + rowNode.add(this); + while (!rowNode.isEmpty()) { + int rowSize = rowNode.size(); + row = new ArrayList(); + + int rowCount = rowSize; + int nullCount = 0; + while (rowSize > 0) { + TreeNode current = rowNode.pop(); + if (current == null) { + row.add("null"); + nullCount++; + } else { + row.add(Integer.toString(current.val)); + } + + if (current == null || current.left == null) { + rowNode.add(null); + } else { + rowNode.add(current.left); + } + if (current == null || current.right == null) { + rowNode.add(null); + } else { + rowNode.add(current.right); + } + + rowSize--; + } + + if (nullCount == rowCount) { + break; + } + + list.add(row); + } + + // print data + String blank = " "; + for (int i = 0; i < list.size(); i ++) { + for (int j = i; j < list.size(); j++) { + // print blank + System.out.print(blank); + } + List rowList = list.get(i); + for (int k = 0; k < rowList.size(); k++) { + System.out.print(rowList.get(k)); + System.out.print(blank); + } + + System.out.println(); + } + + + //return Arrays.toString(list.toArray()); + + return super.toString(); + } } From fc25de03052f9f0b0682010091fd5403ec2e4c1a Mon Sep 17 00:00:00 2001 From: zgpeace Date: Sun, 14 Jun 2020 16:09:20 +0800 Subject: [PATCH 160/162] middle of the linked list --- .../src/linkedlist/MiddleOfTheLinkedList.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 code/LeetCode/src/linkedlist/MiddleOfTheLinkedList.java diff --git a/code/LeetCode/src/linkedlist/MiddleOfTheLinkedList.java b/code/LeetCode/src/linkedlist/MiddleOfTheLinkedList.java new file mode 100644 index 00000000..453de9c8 --- /dev/null +++ b/code/LeetCode/src/linkedlist/MiddleOfTheLinkedList.java @@ -0,0 +1,25 @@ +package linkedlist; + +import common.ListNode; + +public class MiddleOfTheLinkedList { + + public ListNode middleNode(ListNode head) { + ListNode slow = head; + ListNode fast = head; + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + } + + return slow; + } + + public static void main(String[] args) { + int[] intArray = {1, 2, 3, 4, 5}; + ListNode head = ListNode.listNodeWithIntArray(intArray); + MiddleOfTheLinkedList obj = new MiddleOfTheLinkedList(); + ListNode middleNode = obj.middleNode(head); + System.out.println(middleNode.toString()); + } +} From 6da2823a221b023fa39135969dcad0a6ff977ed8 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Sun, 14 Jun 2020 16:09:32 +0800 Subject: [PATCH 161/162] remove linked list elements --- .../linkedlist/RemoveLinkedListElements.java | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 code/LeetCode/src/linkedlist/RemoveLinkedListElements.java diff --git a/code/LeetCode/src/linkedlist/RemoveLinkedListElements.java b/code/LeetCode/src/linkedlist/RemoveLinkedListElements.java new file mode 100644 index 00000000..23d937b9 --- /dev/null +++ b/code/LeetCode/src/linkedlist/RemoveLinkedListElements.java @@ -0,0 +1,93 @@ +package linkedlist; + +// https://leetcode.com/problems/remove-linked-list-elements/ + + +import common.ListNode; + +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +public class RemoveLinkedListElements { + + public ListNode removeElements(ListNode head, int val) { + ListNode result = head; + ListNode preNode = null; + boolean isFirstNode = true; + while (head != null) { + // the first one + if (isFirstNode == true) { + if (head.val == val) { + // if the first one equal to the remove value, then the element still first + head = head.next; + result = head; + } else { + isFirstNode = false; + preNode = head; + head = head.next; + } + + continue; + } + + // middle section + if (head.val == val) { + preNode.next = head.next; + head = head.next; + } else { + preNode = head; + head = head.next; + } + + // the last one, the same as middle section + + } + + return result; + } + + public ListNode removeElementsWithRecursive(ListNode head, int val) { + // exit condition + if (head == null) return null; + // recursive from tail to head. + head.next = removeElementsWithRecursive(head.next, val); + return head.val == val ? head.next : head; + } + + public ListNode removeElementWithFakeHead(ListNode head, int val) { + ListNode fakeHead = new ListNode(-1); + fakeHead.next = head; + ListNode pre = fakeHead; + while (head != null) { + if (head.val == val) { + pre.next = head.next; + } else { + pre = head; + } + + head = head.next; + } + + return fakeHead.next; + } + + public static void main(String[] args) { + RemoveLinkedListElements obj = new RemoveLinkedListElements(); + int[] originArray = {1, 2, 6, 3, 4, 5, 6}; + ListNode head = ListNode.listNodeWithIntArray(originArray); + System.out.println(head.toString()); + //ListNode result = obj.removeElements(head, 6); + //ListNode result = obj.removeElementsWithRecursive(head, 6); + ListNode result = obj.removeElementWithFakeHead(head, 6); + System.out.println(result.toString()); + + } + +} From c6fcafdf0bb1eeb7e3220ed6a85143489c5791a8 Mon Sep 17 00:00:00 2001 From: zgpeace Date: Sun, 14 Jun 2020 16:09:42 +0800 Subject: [PATCH 162/162] convert bst to greater tree --- .../src/tree/ConvertBSTToGreaterTree.java | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 code/LeetCode/src/tree/ConvertBSTToGreaterTree.java diff --git a/code/LeetCode/src/tree/ConvertBSTToGreaterTree.java b/code/LeetCode/src/tree/ConvertBSTToGreaterTree.java new file mode 100644 index 00000000..db2469de --- /dev/null +++ b/code/LeetCode/src/tree/ConvertBSTToGreaterTree.java @@ -0,0 +1,60 @@ +package tree; + +import common.TreeNode; + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + +// https://leetcode.com/problems/convert-bst-to-greater-tree/ +public class ConvertBSTToGreaterTree { + + private int sum = 0; + + public TreeNode convertBST(TreeNode root) { + if (root != null) { + convertBST(root.right); + sum += root.val; + root.val = sum; + convertBST(root.left); + } + + return root; + } + + public static void main(String[] args) { + //TreeNode left1 = new TreeNode(2); + //TreeNode right1 = new TreeNode(13); + // + //TreeNode root = new TreeNode(5, left1, right1); + + TreeNode left1 = new TreeNode(1); + TreeNode right1 = new TreeNode(3); + + TreeNode rootLeft = new TreeNode(2, left1, right1); + + TreeNode left2 = new TreeNode(6); + TreeNode right2 = new TreeNode(15); + + TreeNode rootRight = new TreeNode(13, left2, right2); + + TreeNode root = new TreeNode(5, rootLeft, rootRight); + + root.toString(); + ConvertBSTToGreaterTree obj = new ConvertBSTToGreaterTree(); + TreeNode result = obj.convertBST(root); + result.toString(); + } +}