├── .gitignore ├── 2021-04-16 ├── LevelOrderBottom107.java ├── GetLeastNumbers40.java └── TopKFrequent347.java ├── 2021-02-18 ├── MergeDuplicate.md ├── MergeMultiFile.md └── MergeBigFile.md ├── 2021-03-14 ├── SingleNumber136.java ├── XorGame810.java ├── FindRepeatNumberJianZhi03.java ├── FindKthNumber440.java └── ShortestSubarray862.java ├── 2021-03-02 └── ClimbStairs70.java ├── 2021-05-08 ├── SingleNumber136.java ├── MoveZeroes283.java └── MinDepth111.java ├── 2021-02-28 ├── MaxSubArray53.java └── MinimumTotal120.java ├── 2021-05-11 ├── GetDecimalValue1290.java ├── PeakIndexInMountainArray852.java ├── IsAnagram242.java ├── SortArrayByParity905.java ├── MaxDepth559.java ├── Preorder589.java └── ReverseParentheses1190.java ├── 2021-03-29 ├── MiddleNode876.java ├── LengthOfLIS300.java ├── MaxSubArray53.java ├── HasPathSum112.java ├── MaxProfit122.java └── IsBalanced55.java ├── 2021-05-09 ├── Transpose867.java ├── Generate118.java ├── AddBinary67.java └── RomanToInt13.java ├── 2021-04-19 ├── JumpGame55.java └── JumpGame45.java ├── 2021-04-09 ├── Reverse7.java ├── MaxArea11.java └── FindMedianSortedArrays4.java ├── 2021-04-30 ├── TranslateNum46.java ├── IsPalindrome9.java └── SimplifyPath71.java ├── 2021-04-05 ├── RemoveElement27.java ├── RemoveDuplicates26.java └── Rotate48.java ├── 2021-04-08 ├── CanJump55.java ├── Jump45.java └── FindMin153.java ├── 2021-03-06 ├── MaxProfit121.java ├── IsPalindrome125.java └── ThreeSum54.java ├── 2021-04-28 ├── JudgeSquareSum633.java └── IsBalanced55.java ├── 2021-03-23 ├── FirstBadVersion278.java ├── SearchMatrix74.java ├── RotateSearch33.java ├── SearchRange34.java └── FindPeakElement162.java ├── 2021-04-24 ├── LastRemaining62.java ├── MySqrt69.java └── CombinationSum377.java ├── 2021-04-10 ├── IsUgly263.java ├── ReversePrintJianZhi06.java ├── UniquePathsII63.java └── VerifyPostorderJianZhi33.java ├── 2021-03-22 ├── SortArrayInsertSort912.java ├── AddStrings415.java ├── SortArraySelectSort912.java └── SortArrayMergeSort912.java ├── 2021-05-02 ├── IsSameTree100.java ├── SearchInsert35.java └── GenerateMatrix59.java ├── 2021-03-09 └── UniquePaths62.java ├── 2021-03-20 ├── PredictTheWinner486.java └── EmployeeFreeTime759.java ├── 2021-02-19 ├── FirstBadVersion278.java ├── SearchMatrix74.java ├── RotateSearch33.java ├── SearchRange34.java └── FindPeakElement162.java ├── 2021-02-20 ├── RotateArray189.java ├── MySqrt69.java └── FindDuplicate287.java ├── 2021-04-21 ├── StrStr28.java ├── IsValid20.java ├── RandomPickIndex528.java ├── SpiralOrder54.java ├── NextPermutation31.java └── LowestCommonAncestor235.java ├── 2021-02-22 ├── NumTrees96.java ├── InorderSuccessorWithParent510.java ├── InsertNodeBstLintcode85.java ├── GenerateTreesBst95.java ├── SearchRangeLintcode11.java ├── DeleteNodeBst450.java └── IsValidBST98.java ├── 2021-03-24 ├── RotateArray189.java ├── FindDuplicate287.java ├── FindRepeatNumberJianZhi03.java └── MySqrt69.java ├── 2021-03-26 ├── NumTrees96.java ├── InorderSuccessorWithParent510.java ├── MaxPathSum124.java └── SerializeBTree297.java ├── 2021-03-04 ├── TwoSumNewCode.java └── SingleNumbersNewCode.java ├── 2021-04-20 ├── SortColors75.java ├── CoinChange322.java └── Trap42.java ├── 2021-03-03 ├── MinPathSum64.java ├── ReOrderArrayNewCode.java └── SpiralOrder54.java ├── 2021-05-22 └── Pick398.java ├── 2021-03-31 ├── GetIntersectionNode52.java ├── MinStack155.java └── ReverseKGroup25.java ├── 2021-03-19 ├── LengthOfLongestSubstring48.java └── SpiralOrder29.java ├── 2021-05-05 ├── ReverseWords58.java ├── AddTwoNumbers2.java └── Exist12.java ├── 2021-03-30 ├── MajorityElement169.java └── SortArrayByParityII922.java ├── 2021-03-13 ├── GetKthFromEnd22.java └── ReverseBetween92.java ├── 2021-03-15 ├── MaxSubArray53.java └── Permutation38.java ├── 2021-02-14 ├── SortArrayInsertSort912.java └── SortArrayBubbleSort912.java ├── 2021-02-16 └── AddStrings415.java ├── 2021-04-13 ├── NumTrees96.java ├── MinDiffInBST783.java ├── SortedListToBST109.java └── GenerateTreesBst95.java ├── 2021-05-04 ├── SingleNumber260.java └── CanCompleteCircuit134.java ├── 2021-04-11 ├── NthUglyNumber264.java └── TreeToDoublyList36.java ├── 2021-02-06 └── LongestCommonSubsequence1143.java ├── 2021-02-15 ├── SortArraySelectSort912.java └── SortArrayMergeSort912.java ├── 2021-05-18 └── GetMoneyAmount375.java ├── 2021-05-07 └── MaxProfit123.java ├── 2021-02-24 ├── DeleteDuplicates83.java ├── PartitionList86.java ├── DeleteDuplicates82.java └── MergeTwoLists21.java ├── 2021-04-29 └── ReverseLeftWords58.java ├── 2021-05-01 ├── Subsets78.java └── IsMatch10Re.java ├── 2021-03-27 ├── DeleteDuplicates83.java ├── HasCycle141.java ├── RemoveNthFromEnd19.java ├── DetectCycle142.java ├── PartitionList86.java ├── DeleteDuplicates82.java └── MergeTwoLists21.java ├── 2021-04-12 ├── InvertTree226.java ├── LargestNumber179.java ├── MergeTrees617.java ├── IsBalanced110.java ├── DiameterOfBinaryTree543.java ├── SortedArrayToBST108.java └── PathSum437.java ├── 2021-03-01 ├── MinSubArrayLen209.java ├── Intersection349.java └── MedianLintCode80.java ├── 2021-02-27 ├── GetIntersectionNode160.java └── CopyRandomList138.java ├── 2021-02-25 ├── HasCycle141.java └── DetectCycle142.java ├── 2021-04-01 ├── MinArray11.java ├── LongestConsecutive128.java └── FindContinuousSequence57.java ├── 2021-03-10 ├── SwapPairs24.java ├── MaxAreaOfIsland695.java └── AddTwoNumbers445.java ├── 2021-04-25 ├── LowestCommonAncestor68II.java └── LargestBSTSubtree333.java ├── 2021-03-12 ├── IsPalindrome125.java └── Rand470.java ├── 2021-03-05 └── LongestCommonPrefix14.java ├── 2021-04-06 ├── IsPalindrome125.java └── ValidPalindrome680.java ├── 2021-03-07 ├── Permute46.java ├── CombinationSum39.java ├── PermuteUnique47.java └── CombinationSum40.java ├── 2021-05-20 └── ConfusingNumber1056.java ├── 2021-04-02 └── Search81.java ├── 2021-04-14 ├── LengthOfLongestSubstring3.java └── Merge56.java ├── 2021-05-21 └── SnapshotArray1146.java ├── 2021-05-13 ├── Convert6.java └── Partition131.java ├── 2021-02-05 └── ReverseList206.java ├── 2021-03-21 ├── AddTwoNumbers2.java ├── SortArrayHeapSort912.java └── SortArrayBubbleSort912.java ├── 2021-02-08 └── GetKthFromEnd22.java ├── 2021-05-10 └── DailyTemperatures739.java ├── 2021-05-14 └── GenerateParenthesis22.java ├── 2021-02-23 ├── MaxPathSum124.java └── SerializeBTree297.java ├── 2021-02-13 └── SortArrayHeapSort912.java ├── 2021-04-22 └── GoodNodes1448.java ├── 2021-04-23 ├── MinMeetingRooms253.java └── LengthOfLIS300.java ├── 2021-04-15 └── Rob213.java ├── 2021-05-23 └── Merge56.java ├── 2021-02-26 └── RotateRight61.java ├── 2021-03-18 └── isNumberNewCode20.java ├── 2021-04-18 └── MinDistance72.java ├── 2021-05-03 └── Candy135.java ├── 2021-05-17 └── EvalRPN150.java ├── 2021-04-04 ├── isNumberNewCode20.java └── DecodeString394.java ├── 2021-02-04 └── Rand470.java ├── 2021-04-17 └── ContainsNearbyAlmostDuplicate220.java ├── 2021-04-03 └── ReorderList143.java ├── 2021-05-12 └── BackspaceCompare844.java └── 2021-03-25 └── GenerateTreesBst95.java /.gitignore: -------------------------------------------------------------------------------- 1 | */.DS_Store 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /2021-04-16/LevelOrderBottom107.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class LevelOrderBottom107 { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /2021-02-18/MergeDuplicate.md: -------------------------------------------------------------------------------- 1 | ## 两个文件包含无序的数字,数字的大小范围是0-500w左右。如何求两个文件中的重复的数据? 2 | ### Bit Map 3 | - 两个文件分别为A和B,采用2-Bitmap(每个数分配2bit,00表示两个文件都不存在,01表示在A出现过,10表示在两个文件中都出现过,11没有意义)进行。 4 | - 因为800万数据约为2^23次方,所以500万数据共需内存2^23 * 2 bit=1000bit=2MB内存,内存可以接受。 5 | - 然后扫描扫描两个文件中的整数,查看Bitmap中相对应位,如果是00变01,00变10,10保持不变。 6 | - 所有数据描完后,查看bitmap,把对应位是10的整数输出即可。 -------------------------------------------------------------------------------- /2021-03-14/SingleNumber136.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class SingleNumber136 { 4 | 5 | /** 6 | * 任何数和 00 做异或运算,结果仍然是原来的数。 7 | * 任何数和其自身做异或运算,结果是 0。 8 | * 异或运算满足交换律和结合律。 9 | */ 10 | public int singleNumber(int[] nums) { 11 | int res =0; 12 | for(int i: nums){ 13 | res ^= i; 14 | } 15 | return res; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /2021-03-02/ClimbStairs70.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class ClimbStairs70 { 4 | /* Method : DP; Time: O(N), Space:O(1)**/ 5 | public int climbStairs(int n) { 6 | int pre = 0; 7 | int cur = 0; 8 | int sum = 1; 9 | for(int i=1; i<=n; i++) { 10 | pre = cur; 11 | cur = sum; 12 | sum = pre+cur; 13 | } 14 | return sum; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /2021-03-14/XorGame810.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class XorGame810 { 4 | /** 5 | 思路:分两种情况:奇数和偶数位 6 | 如果初始异或和就是 0, 先手直接赢了。 7 | 胜负其实和数组长度有关,如果长度为偶数,先手必胜,否则必败。 8 | **/ 9 | public boolean xorGame(int[] nums) { 10 | int res = 0; 11 | for(int i=0;i= len-1) { 12 | return true; 13 | } 14 | } 15 | } 16 | return false; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /2021-05-11/PeakIndexInMountainArray852.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class PeakIndexInMountainArray852 { 4 | 5 | /*Method: Binary Search, Time: O(LogN), Space:O(1)**/ 6 | public int peakIndexInMountainArray(int[] arr) { 7 | int l = 0, h= arr.length-1; 8 | while(l-1; i--){ 9 | String tmp = s.substring(i, i+2); 10 | int c= tmp.compareTo("10") >= 0 && tmp.compareTo("25") <= 0 ? a+b:a; 11 | b=a; 12 | a=c; 13 | } 14 | return a; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /2021-05-11/IsAnagram242.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.Arrays; 4 | 5 | public class IsAnagram242 { 6 | /*Method:Sort, Time: O(NLogN), Space:O(LogN)**/ 7 | public boolean isAnagram(String s, String t) { 8 | if(s.length() != t.length()) { 9 | return false; 10 | } 11 | char[] str1 = s.toCharArray(); 12 | char[] str2 = t.toCharArray(); 13 | Arrays.sort(str1); 14 | Arrays.sort(str2); 15 | return Arrays.equals(str1, str2); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /2021-04-05/RemoveElement27.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class RemoveElement27 { 4 | /**Method: Two pointers; Time:O(N); Space: O(1) **/ 5 | /** 6 | 思路:双指针 7 | 指针1: count指向已经移除了val以后的index 8 | 指针2: i表当前数组遍历的值 9 | **/ 10 | public int removeElement(int[] nums, int val) { 11 | int count =0; 12 | for(int i=0;i=len-1) { 12 | return true; 13 | } 14 | } 15 | 16 | } 17 | return false; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /2021-03-06/MaxProfit121.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class MaxProfit121 { 4 | /*Method: DP, Time: O(N), Space:O(1)**/ 5 | public int maxProfit(int[] prices) { 6 | int minPrice = Integer.MAX_VALUE; 7 | int maxValue = 0; 8 | for(int i=0;i maxValue){ 12 | maxValue = prices[i] - minPrice; 13 | } 14 | } 15 | return maxValue; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /2021-04-28/JudgeSquareSum633.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class JudgeSquareSum633 { 4 | /* Method: Two Pointer , Time: O(sqrt(C)), Space:O(1)**/ 5 | public boolean judgeSquareSum(int c) { 6 | long l=0; 7 | long r = (long) Math.sqrt(c); 8 | while(l <= r) { 9 | long sum = l*l + r*r; 10 | if(sum == c) { 11 | return true; 12 | } else if(sum > c) { 13 | r--; 14 | } else { 15 | l++; 16 | } 17 | } 18 | return false; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /2021-03-23/FirstBadVersion278.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class FirstBadVersion278 { 4 | /**Method: Binary search; Time: O(log(n)); Space: O(1) **/ 5 | public int firstBadVersion(int n) { 6 | int s = 0, e = n; 7 | while(s=0 && insertNode < a[j]; j--) { 13 | a[j+1] = a[j]; 14 | } 15 | a[j+1] =insertNode; 16 | } 17 | return a; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /2021-05-02/IsSameTree100.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import Leetcode.IsSymmetric803.TreeNode; 4 | 5 | public class IsSameTree100 { 6 | /**Method: Recursive; Time:O(Min(M,N)); Space: O(Min(M,N)) **/ 7 | public boolean isSameTree(TreeNode p, TreeNode q) { 8 | if(p==null && q==null) { 9 | return true; 10 | } 11 | if(p == null || q == null) { 12 | return false; 13 | } 14 | if(p.val != q.val) { 15 | return false; 16 | } 17 | return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); 18 | 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /2021-03-14/FindRepeatNumberJianZhi03.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class FindRepeatNumberJianZhi03 { 4 | /** Method: in place sort to get the nums[i] == i; Time: O(N) ; Space: O(1) **/ 5 | public int findRepeatNumber(int[] nums) { 6 | for(int i =0; i< nums.length;i++) { 7 | while( i != nums[i]) { 8 | if(nums[i] == nums[nums[i]]) { 9 | return nums[i]; 10 | } 11 | int temp = nums[nums[i]]; 12 | nums[nums[i]] = nums[i]; 13 | nums[i] = temp; 14 | } 15 | 16 | } 17 | return -1; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /2021-05-02/SearchInsert35.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class SearchInsert35 { 4 | /**Method: Binary Search; Time:O(LogN); Space: O(1) **/ 5 | /** 6 | 直接套用二分法,不断用二分法逼近查找第一个大于等于 target 的下标 。 7 | **/ 8 | public int searchInsert(int[] nums, int target) { 9 | int n=nums.length; 10 | int l = 0, r = n-1, res = n; 11 | while(l<=r) { 12 | int mid = l + (r-l)/2; 13 | if(target <= nums[mid]) { 14 | res = mid; 15 | r = mid-1; 16 | } else { 17 | l = mid+1; 18 | } 19 | } 20 | return res; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /2021-03-09/UniquePaths62.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class UniquePaths62 { 4 | /** Method: DP; Time: O(N*M); Space: O(Min(N,M)) **/ 5 | public int uniquePaths(int m, int n) { 6 | if(m ==0 || n == 0) { 7 | return 0; 8 | } 9 | if(m>n) { 10 | return uniquePaths(n, m); 11 | } 12 | int[] dp = new int[m]; 13 | for(int i=0; i=0;i--){ 13 | for(int j=i+1; j=0; 18 | } 19 | 20 | 21 | } 22 | -------------------------------------------------------------------------------- /2021-02-19/FirstBadVersion278.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class FirstBadVersion278 { 4 | /**Method: Binary search; Time: O(log(n)); Space: O(1) **/ 5 | public int firstBadVersion(int n) { 6 | int start = 0; 7 | int end = n; 8 | while(start < end) { 9 | int mid = start + (end - start) /2; 10 | if(isBadVersion(mid)) { 11 | end = mid; 12 | } else { 13 | start = mid + 1; 14 | } 15 | } 16 | return start; 17 | } 18 | 19 | boolean isBadVersion(int version) { 20 | return false; //Unimplemented 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /2021-04-08/FindMin153.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class FindMin153 { 4 | /**Method: BinarySearch; Time:O(LogN); Space: O(1) **/ 5 | /** 6 | 思路:把待搜索区间分成两个部分: 7 | 1. 一定不存在 目标元素的区间:下一轮搜索的时候,不用考虑它; 8 | 2. 可能存在 目标元素的区间:下一轮搜索的时候,需要考虑它。 9 | **/ 10 | public int findMin(int[] nums) { 11 | int l = 0; 12 | int h = nums.length-1; 13 | while(l, Time: O(N), Space:O(N)**/ 8 | public int[] twoSum (int[] numbers, int target) { 9 | int[] res = new int[2]; 10 | HashMap map = new HashMap<>(); 11 | for(int i=0; i< numbers.length; i++) { 12 | if(map.containsKey(numbers[i])) { 13 | res[0] = map.get(numbers[i]) + 1; 14 | res[1] = i + 1; 15 | } else { 16 | map.put(target - numbers[i], i); 17 | } 18 | } 19 | return res; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /2021-04-20/SortColors75.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class SortColors75 { 4 | /**Method: Two Pointers; Time: O(N); Space:O(1);**/ 5 | public void sortColors(int[] nums) { 6 | int zero = -1, one =0, two =nums.length; 7 | while(onerevertNumber) { 15 | revertNumber = revertNumber * 10 + x %10; 16 | x/=10; 17 | } 18 | return x == revertNumber || x == revertNumber /10; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /2021-05-22/Pick398.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.Random; 4 | 5 | public class Pick398 { 6 | /*Method: Reservoir Sampling, Time: O(N), Space:O(1)**/ 7 | /** :对第i个元素,以k/i的概率更新取值,以1 - k/i的概率保留原值。 */ 8 | int[] nums; 9 | public Pick398(int[] nums) { 10 | this.nums = nums; 11 | } 12 | 13 | public int pick(int target) { 14 | Random r = new Random(); 15 | int count=0, res=0; 16 | for(int i=0; i< nums.length; i++){ 17 | if(target == nums[i]){ 18 | if(r.nextInt(++count) == 0){ // 取0的概率为1/i 19 | res = i; 20 | } 21 | } 22 | } 23 | return res; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /2021-03-31/GetIntersectionNode52.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | 4 | import Leetcode.RemoveNthFromEnd19.ListNode; 5 | 6 | public class GetIntersectionNode52 { 7 | /*Method: Two pointers, Time: O(N+M), Space:O(1)**/ 8 | /** 9 | 链表1的长度 = x + z; 10 | 链表2的长度 = y + z; 11 | 所以x+z+y = y+z+x 12 | **/ 13 | public ListNode getIntersectionNode(ListNode headA, ListNode headB) { 14 | ListNode l1 = headA; 15 | ListNode l2 = headB; 16 | while(l1 != l2) { 17 | l1 = l1 == null? headB: l1.next; //注意这里是l1 == null,不是l1.next 18 | l2 = l2 == null? headA: l2.next; 19 | } 20 | return l1; 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /2021-04-21/IsValid20.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.Stack; 4 | 5 | public class IsValid20 { 6 | /**Method: Stack; Time: O(N), Space: O(N) **/ 7 | public boolean isValid(String s) { 8 | if(s.isEmpty()) 9 | return true; 10 | Stack stack=new Stack(); 11 | for(char c:s.toCharArray()){ 12 | if(c=='(') 13 | stack.push(')'); 14 | else if(c=='{') 15 | stack.push('}'); 16 | else if(c=='[') 17 | stack.push(']'); 18 | else if(stack.empty()||c!=stack.pop()) 19 | return false; 20 | } 21 | return stack.empty(); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /2021-05-08/MoveZeroes283.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class MoveZeroes283 { 4 | /** Method: Two Pointers; Time: O(N); Space:O(1);**/ 5 | /** 6 | 左指针左边均为非零数; 7 | 右指针左边直到左指针处均为零。 8 | 因此每次交换,都是将左指针的零与右指针的非零数交换,且非零数的相对顺序并未改变。 9 | **/ 10 | public void moveZeroes(int[] nums) { 11 | int len=nums.length, l = 0, r=0; 12 | while(r> triangle) { 8 | int n = triangle.size(); 9 | int[][] dp = new int[n][n]; 10 | for(int i =0; i< n; i++) { 11 | dp[n-1][i] = triangle.get(n-1).get(i); 12 | } 13 | for(int i =n - 2; i >= 0 ;i--){ 14 | for(int j = 0 ;j map = new HashMap<>(); 11 | int i=-1,res=0; 12 | for(int j=0; j=0) { 10 | while(i >= 0 && s.charAt(i) != ' ') {// 搜索首个空格 11 | i--; 12 | } 13 | res.append(s.substring(i+1, j+1) + ' ');// 添加单词 14 | while(i>=0 && s.charAt(i) == ' ') {// 跳过单词间空格 15 | i--; 16 | } 17 | j=i;// j 指向下个单词的尾字符 18 | } 19 | return res.toString().trim(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /2021-03-22/AddStrings415.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class AddStrings415 { 4 | /** Method: Mock Add; Time: O(max(len1, len2); Space: O(1)) **/ 5 | public String addStrings(String num1, String num2) { 6 | int len1 = num1.length(), len2 = num2.length(); 7 | int carry =0; 8 | int c1= len1-1, c2= len2-1; 9 | StringBuilder res = new StringBuilder(); 10 | while(c1>=0 || c2>=0 || carry >0) { 11 | int x =c1 <0? 0: num1.charAt(c1--)-'0'; 12 | int y = c2<0?0: num2.charAt(c2--)-'0'; 13 | int cur = x+y+carry; 14 | res.append(cur%10); 15 | carry = cur /10; 16 | } 17 | return res.reverse().toString(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /2021-05-09/Generate118.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Generate118 { 7 | /** Method:Math; Time: O(N^2); Space:O(1);**/ 8 | public List> generate(int numRows) { 9 | List> res = new ArrayList<>(); 10 | for(int i=0; i< numRows; i++) { 11 | List row = new ArrayList<>(); 12 | for(int j=0; j<=i; j++){ 13 | if(j==0 || j==i) { 14 | row.add(1); 15 | } else { 16 | row.add(res.get(i-1).get(j-1) + res.get(i-1).get(j)); 17 | } 18 | } 19 | res.add(row); 20 | } 21 | return res; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /2021-03-30/MajorityElement169.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class MajorityElement169 { 4 | /*Method: Boyer-Moore, Time: O(N), Space:O(1)**/ 5 | /** 6 | 遍历数组,如果 times 的值为 0,我们先将nums[i] 的值赋予res,随后我们判断nums[i]: 7 | 如果nums[i] 与 res 相等,那么计数器 times 的值增加 1; 8 | 如果nums[i] 与 res 不等,那么计数器 times 的值减少 1。 9 | **/ 10 | public int majorityElement(int[] nums) { 11 | int times = 0; 12 | int res =0; 13 | for(int i=0; i= 0 && insertNote < a[j]) { 18 | a[j + 1] = a[j]; 19 | j--; 20 | } 21 | a[j + 1] = insertNote; 22 | } 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /2021-02-16/AddStrings415.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class AddStrings415 { 4 | /** Method: Mock Add; Time: O(max(len1, len2); Space: O(1)) **/ 5 | public String addStrings(String num1, String num2) { 6 | int i = num1.length() -1; 7 | int j = num2.length() -1; 8 | int carry = 0; 9 | StringBuilder res = new StringBuilder(); 10 | while(i >= 0 || j >= 0 || carry != 0) { 11 | int x = i >= 0? num1.charAt(i) - '0' : 0; 12 | int y = j >= 0? num2.charAt(j) - '0' : 0; 13 | int result = x + y + carry; 14 | res.append(result % 10); 15 | carry = result / 10; 16 | i --; 17 | j --; 18 | } 19 | return res.reverse().toString(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /2021-04-13/NumTrees96.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.time.Instant; 5 | import java.time.ZoneOffset; 6 | import java.util.Calendar; 7 | import java.util.Date; 8 | import java.util.TimeZone; 9 | 10 | public class NumTrees96 { 11 | /**Method: DP; Time: O(N^2); Space: O(N) **/ 12 | /** 13 | 原问题可以分解成规模较小的两个子问题 14 | DP(i,n)=DP(i−1) * DP(n−i) 15 | **/ 16 | public int numTrees(int n) { 17 | int[] dp = new int[n+1]; 18 | dp[0] = 1; 19 | dp[1] = 1; 20 | for(int i = 2; i <= n; i++) { 21 | for(int j=1; j<=i; j++) { 22 | dp[i] += dp[j-1] * dp[i-j]; //以i为区分,分两边,每次都是乘法 23 | } 24 | } 25 | return dp[n]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /2021-05-04/SingleNumber260.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class SingleNumber260 { 4 | /**Method:Grouping for XOR operation; Time:O(N); Space: O(1) **/ 5 | /** 6 | 先对所有数字进行一次异或,得到两个出现一次的数字的异或值。 7 | 在异或结果中找到任意为 1 的位。 8 | 根据这一位对所有的数字进行分组。 9 | 在每个组内进行异或操作,得到两个数字。 10 | **/ 11 | public int[] singleNumber(int[] nums) { 12 | int res = 0; 13 | for(int n:nums){ 14 | res ^= n; 15 | } 16 | int div = 1; 17 | while((div & res) == 0) { 18 | div <<= 1; 19 | } 20 | int a=0,b=0; 21 | for(int n:nums) { 22 | if((div & n) !=0) { 23 | a ^= n; 24 | } else { 25 | b ^= n; 26 | } 27 | } 28 | return new int[]{a,b}; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /2021-05-08/MinDepth111.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import Leetcode.IsSymmetric803.TreeNode; 4 | 5 | public class MinDepth111 { 6 | /** Method: DFS; Time: O(N); Space:O(H);**/ 7 | /** 8 | 对于每一个非叶子节点,我们只需要分别计算其左右子树的最小叶子节点深度。 9 | **/ 10 | public int minDepth(TreeNode root) { 11 | if(root == null) { 12 | return 0; 13 | } 14 | if(root.left == null && root.right == null){ 15 | return 1; 16 | } 17 | int minLen = Integer.MAX_VALUE; 18 | if(root.left != null){ 19 | minLen = Math.min(minDepth(root.left), minLen); 20 | } 21 | if(root.right != null) { 22 | minLen = Math.min(minDepth(root.right), minLen); 23 | } 24 | return minLen+1; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /2021-03-03/ReOrderArrayNewCode.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class ReOrderArrayNewCode { 4 | /* Method: Bubble , Time: O(N^2), Space:O(1)**/ 5 | public int[] reOrderArray (int[] array) { 6 | if(array == null || array.length == 0) { 7 | return new int[0]; 8 | } 9 | int len = array.length; 10 | boolean changed = true; 11 | for(int i = len-1 ; i >=0 && changed; i--) { 12 | changed =false; 13 | for(int j=0; j< i; j++) { 14 | if(array[j+1] % 2 > array[j] % 2) { 15 | int temp = array[j]; 16 | array[j] = array[j+1]; 17 | array[j+1] = temp; 18 | changed = true; 19 | } 20 | } 21 | } 22 | return array; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /2021-03-24/FindRepeatNumberJianZhi03.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class FindRepeatNumberJianZhi03 { 4 | /** Method: in place sort to get the nums[i] == i; Time: O(N) ; Space: O(1) **/ 5 | public int findRepeatNumber(int[] nums) { //对比https://leetcode-cn.com/problems/find-the-duplicate-number/submissions/ :有多个重复,找一个就可以 6 | for(int i=0;i nums[j] ) { 18 | dp[i] = Math.max(dp[i], dp[j]+1); //只要 nums[i] 严格大于在它位置之前的某个数,那么 nums[i] 就可以接在这个数后面形成一个更长的上升子序列。 19 | } 20 | } 21 | res= Math.max(res, dp[i]); 22 | } 23 | return res; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /2021-02-19/SearchMatrix74.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class SearchMatrix74 { 4 | /**Method: Binary search; Time: O(log(row * col)); Space: O(1) **/ 5 | public boolean searchMatrix(int[][] matrix, int target) { 6 | int row = matrix.length; 7 | if(row <=0) { 8 | return false; 9 | } 10 | int col = matrix[0].length; 11 | int start = 0; 12 | int end = row * col - 1; 13 | while(start<= end) { 14 | int mid = start + (end - start) /2; 15 | int val = matrix[mid /col][mid % col]; 16 | if(val == target) { 17 | return true; 18 | } else if(target < val) { 19 | end = mid -1; 20 | } else{ 21 | start = mid +1; 22 | } 23 | } 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /2021-02-18/MergeMultiFile.md: -------------------------------------------------------------------------------- 1 | ## 1000台机器,每台机器1000个 文件,每个文件存储了10亿个 整数,如何找到其中最小的1000个值? 2 | 3 | ### 分治 + hash + 大顶堆 4 | - 对于每台机器中每个文件存储的10亿个整数,使用hash将10亿个数据分成1000份,每份100万个数据 5 | - 通过大顶堆的方法找每份数据中最小的1000个值 6 | - 对于每台机器上1000个文件,一共有1000*1000=100w个值,再使用大顶堆整个机器上1000份数据集最小的1000个值 7 | - 因为一共1000台机器,每台机器1000个值,最后将这100w数据汇总都传输到一台机器上通过大顶堆找出最小的1000个值 8 | - 时间复杂度:O(NlogK),其中 N= 1000台机器 * (1000份文件 + 1次汇总)* 1000,K = 1000 9 | 10 | ### Bit Map 11 | 如果每个整数使用1 bit来表示,那么10亿个整数 = 2^32 bit/8 = 2^29 Byte,大约等于512MB 12 | 13 | - 每台机器上申请一个int数组长度为 int tmp[N/32+1]即可存储完这些数据,其中N代表要进行查找的总数(这里也就是2^32),tmp中的每个元素在内存在占32位可以对应表示十进制数0~31,所以可得到BitMap表。 14 | - 再顺序扫描这10亿的数,在对应的bit位上标记该数是否出现过。 15 | - 然后找出每台机器上1000个最小值 16 | - 最后将这100w数据汇总都传输到一台机器上通过大顶堆找出最小的1000个值 17 | - 时间复杂度:O(N+100W * logK),其中N是总数据量,K = 1000 -------------------------------------------------------------------------------- /2021-05-18/GetMoneyAmount375.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class GetMoneyAmount375 { 4 | /*Method: DP, Time: O(N^3), Space:O(N^2)**/ 5 | /** 6 | 只需要从(i+(len−1)/2,j) 中选第一个数就可以了,其中 len 是当前区间的长度 7 | **/ 8 | public int getMoneyAmount(int n) { 9 | int[][] dp = new int[n+1][n+1]; 10 | for(int len = 2; len<=n; len++) { 11 | for(int start = 1; start <= n-len+1; start++) { 12 | int minRes = Integer.MAX_VALUE; 13 | for(int i = start +(len-1)/2; i target) { 18 | e = mid -1; 19 | } else { 20 | s = mid +1; 21 | } 22 | } 23 | return false; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /2021-03-26/InorderSuccessorWithParent510.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class InorderSuccessorWithParent510 { 4 | 5 | /**Method: Iteration; Time:O(H); Space: O(1) **/ 6 | public Node inorderSuccessor(Node node) { 7 | if(node == null) { 8 | return null; 9 | } 10 | if(node.right != null) { 11 | node = node.right; 12 | while(node.left != null) { 13 | node = node.left; 14 | } 15 | return node; 16 | } 17 | while(node.parent != null && node.parent.right == node) { 18 | node = node.parent; 19 | } 20 | return node.parent; // 返回的节点的父节点 21 | } 22 | 23 | class Node { 24 | public int val; 25 | public Node left; 26 | public Node right; 27 | public Node parent; 28 | }; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /2021-04-29/ReverseLeftWords58.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class ReverseLeftWords58 { 4 | 5 | /**Method1:Substring; Method: O(N); Space:O(N) **/ 6 | public String reverseLeftWords(String s, int n) { 7 | return s.substring(n, s.length()) + s.substring(0,n); 8 | } 9 | 10 | /**Method2:StringBuilder + charAt(%); Method: O(N); Space:O(N) **/ 11 | /** 12 | 新建一个 StringBuilder(Java) ,记为 res ; 13 | 先向 res 添加 “第 n + 1位至末位的字符” ; 14 | 再向 res 添加 “首位至第 n 位的字符” ; 15 | 将 res 转化为字符串并返回。 16 | **/ 17 | public String reverseLeftWords2(String s, int n) { 18 | StringBuilder res = new StringBuilder(); 19 | for(int i=n; i> subsets(int[] nums) { 12 | List list = new ArrayList<>(); 13 | List> res = new ArrayList<>(); 14 | int n = nums.length; 15 | for(int m=0;m < (1<(list)); 23 | } 24 | return res; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /2021-04-09/MaxArea11.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class MaxArea11 { 4 | /**Method: Two Pointers; Time:O(N); Space: O(1) **/ 5 | /** 6 | 面积公式:两个指针指向的数字中较小值∗指针之间的距离 7 | 由于水槽的实际高度由两板中的短板决定,则可得面积公式 S(i, j) = min(h[i], h[j]) × (j - i)。 8 | 1. 首先左右指针分别指向数组的左右两端, 9 | 2. 如果我们移动数字较大的那个指针,那么前者「两个指针指向的数字中较小值」不会增加,后者「指针之间的距离」会减小,那么这个乘积会减小。 10 | 3. 所以移动数字较大的那个指针是不合理的。因此,我们移动 数字较小的那个指针。 11 | **/ 12 | public int maxArea(int[] height) { 13 | int i = 0; 14 | int j = height.length-1; 15 | int res = 0; 16 | while(i=l; i--) { 21 | matrix[b][i] = num++; 22 | } 23 | b--; 24 | for(int i=b; i>=t; i--) { 25 | matrix[i][l] = num++; 26 | } 27 | l++; 28 | } 29 | return matrix; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /2021-03-27/DeleteDuplicates83.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class DeleteDuplicates83 { 4 | /**Method: Iteration; Time:O(N); Space: O(1) **/ 5 | public ListNode deleteDuplicates(ListNode head) { 6 | ListNode cur = head; //从head开始 7 | while(cur != null && cur.next != null) { //是cur 和 next对比 8 | if(cur.val == cur.next.val) { 9 | cur.next = cur.next.next; 10 | } else { 11 | cur = cur.next; 12 | } 13 | } 14 | return head; 15 | } 16 | 17 | //Definition for singly-linked list. 18 | public class ListNode { 19 | int val; 20 | ListNode next; 21 | ListNode() {} 22 | ListNode(int val) { this.val = val; } 23 | ListNode(int val, ListNode next) { this.val = val; this.next = next; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /2021-03-29/MaxSubArray53.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class MaxSubArray53 { 4 | /*Method : DP, Time: O(N), Space:O(1)**/ 5 | public int maxSubArray(int[] nums) { 6 | int res = nums[0]; //res是从nums[0]开始,因为是从位置最小的开始 7 | int pre = 0; //pre是从0开始,因为每次和0对比 8 | for(int i=0; i< nums.length;i++) { 9 | pre = Math.max(pre + nums[i] , nums[i]); //如果前边累加后还不如自己本身大,那就把前边的都扔掉,从此自己本身重新开始累加。 10 | res = Math.max(res, pre); 11 | } 12 | return res; 13 | } 14 | 15 | 16 | /**两次求最大值:1.前缀和 VS 0; 2.当前的和 VS 之前的和 **/ 17 | public int maxSubArray1(int[] nums) { 18 | int res = nums[0]; 19 | for(int i=1;i= target) { 15 | sumi += nums[i]; 16 | i++; 17 | curVal = sumj - sumi; 18 | } 19 | if(sumj >= target) { 20 | minLen = Math.min(minLen, j-i+2); 21 | } 22 | } 23 | if(minLen == Integer.MAX_VALUE) { 24 | return 0; 25 | } 26 | return minLen; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /2021-05-09/AddBinary67.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class AddBinary67 { 4 | /** Method:Mock; Time: O(Max(M,N)); Space:O(1);**/ 5 | /** 6 | 先反转这个代表二进制数字的字符串,然后低下标对应低位,高下标对应高位。 7 | 对应位置的答案按照顺序存入答案字符串内,最终将答案串反转。 8 | **/ 9 | public String addBinary(String a, String b) { 10 | StringBuilder res = new StringBuilder(); 11 | int n=Math.max(a.length(), b.length()), carry =0; 12 | for(int i=0; i0) { 19 | res.append('1'); 20 | } 21 | res.reverse(); 22 | return res.toString(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /2021-02-20/MySqrt69.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class MySqrt69 { 4 | /**Method1: Math method: exp && log; Time: O(1)); Space: O(1) **/ 5 | public int mySqrt(int x) { 6 | if(x == 0) { 7 | return 0; 8 | } 9 | int ans = (int) Math.exp(0.5 * Math.log(x)); 10 | return (long) (ans + 1) * (ans + 1) <= x ? ans + 1: ans; 11 | } 12 | 13 | /**Method2: Binary search; Time: O(log(x))); Space: O(1) **/ 14 | public int mySqrt2(int x) { 15 | int start = 0; 16 | int end = x; 17 | int res = -1; 18 | while(start <= end) { 19 | int mid = start + (end-start) /2; 20 | if((long) mid * mid <= x) { 21 | res = mid; 22 | start = mid + 1; 23 | } else { 24 | end = mid -1; 25 | } 26 | } 27 | return res; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /2021-03-06/IsPalindrome125.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class IsPalindrome125 { 4 | /*Method : Two pointers, Time: O(N), Space:O(1)**/ 5 | public boolean isPalindrome(String s) { 6 | int len = s.length(); 7 | int left = 0; 8 | int right = len-1; 9 | while(left< right) { 10 | while(left < right && !Character.isLetterOrDigit(s.charAt(left))) { 11 | left++; 12 | } 13 | while(left < right && !Character.isLetterOrDigit(s.charAt(right))) { 14 | right--; 15 | } 16 | if(left < right){ 17 | if(Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right))) { 18 | return false; 19 | } 20 | left++; 21 | right--; 22 | } 23 | } 24 | return true; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /2021-03-24/MySqrt69.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class MySqrt69 { 4 | /**Method1: Math method: exp && log; Time: O(1)); Space: O(1) **/ 5 | public int mySqrt(int x) { 6 | if(x == 0) { 7 | return 0; 8 | } 9 | int ans = (int) Math.exp(0.5 * Math.log(x)); 10 | return (long) (ans + 1) * (ans + 1) <= x ? ans + 1: ans; 11 | } 12 | 13 | /**Method2: Binary search; Time: O(log(x))); Space: O(1) **/ 14 | public int mySqrt2(int x) { 15 | int s = 0; 16 | int e = x; 17 | int res = -1; 18 | while(s<=e) { // 考虑只有一个值,这里应该用= 19 | int m = s+(e-s)/2; 20 | if((long) m*m <= x){ //如果是<=x的时候,应该满足要求,同时还可以更精确,注意long 21 | res = m; 22 | s = m+1; 23 | } else { 24 | e = m -1; 25 | } 26 | 27 | } 28 | return res; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /2021-03-27/HasCycle141.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | 4 | public class HasCycle141 { 5 | /*Method : Two pointers, Time: O(N), Space:O(1)**/ 6 | public boolean hasCycle(ListNode head) { 7 | if(head == null ||head.next ==null) { 8 | return false; 9 | } 10 | ListNode s = head; 11 | ListNode f = head.next; 12 | while(s != f) { 13 | if(f== null || f.next == null) { 14 | return false; 15 | } 16 | s = s.next; 17 | f = f.next.next; 18 | } 19 | return true; 20 | } 21 | 22 | //Definition for singly-linked list. 23 | public class ListNode { 24 | int val; 25 | ListNode next; 26 | ListNode() {} 27 | ListNode(int val) { this.val = val; } 28 | ListNode(int val, ListNode next) { this.val = val; this.next = next; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /2021-04-05/Rotate48.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class Rotate48 { 4 | /**Method: Flip instead of rotate; Time: O(N^2), Space: O(1) **/ 5 | /** 6 | 思路: 先水平翻转,再主对角线翻转 7 | **/ 8 | public void rotate(int[][] matrix) { 9 | int n=matrix.length; 10 | for(int i=0;i chList = root.children; 13 | int maxChildLen = 0; 14 | for(Node child: chList) { 15 | maxChildLen = Math.max(maxDepth(child), maxChildLen); 16 | } 17 | return maxChildLen+1; 18 | } 19 | 20 | class Node { 21 | public int val; 22 | public List children; 23 | 24 | public Node() {} 25 | 26 | public Node(int _val) { 27 | val = _val; 28 | } 29 | 30 | public Node(int _val, List _children) { 31 | val = _val; 32 | children = _children; 33 | } 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /2021-03-23/RotateSearch33.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class RotateSearch33 { 4 | /**Method: Binary search; Time: O(log(n)); Space: O(1) **/ 5 | public int search(int[] nums, int target) { 6 | int len = nums.length; 7 | 8 | int s = 0, e= len-1; 9 | while(s<=e) { 10 | int mid = s+(e-s)/2; 11 | if(nums[mid] == target) { 12 | return mid; 13 | } 14 | if(nums[0] <= nums[mid]) { //先判断旋转是在mid左边还是右边 15 | if(nums[0] <= target && target < nums[mid]) { 16 | e = mid -1; 17 | } else { 18 | s = mid +1; 19 | } 20 | } else { 21 | if(nums[mid] < target && target <= nums[e]) { 22 | s = mid + 1; 23 | } else { 24 | e = mid - 1; 25 | } 26 | } 27 | } 28 | return -1; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /2021-04-12/LargestNumber179.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.Arrays; 4 | 5 | public class LargestNumber179 { 6 | 7 | /*Method: Comparator, Time: O(N), Space:O(N)**/ 8 | /** 9 | 思路: 10 | 1. 数字数组转换成字符串数组, 11 | 2. 排序 12 | 3. 拼接 13 | 4. string等于00的时候处理 14 | **/ 15 | public String largestNumber(int[] nums) { 16 | int len = nums.length; 17 | String[] strs = new String[len]; 18 | 19 | for(int i=0;i { // 排序,主要排序顺序 23 | return (b+a).compareTo(a+b); 24 | }); 25 | StringBuilder res = new StringBuilder(); 26 | for(int i=0;i0) { 10 | int nums = getNums(n, cur, cur+1); 11 | if(nums <= k) { 12 | cur ++; 13 | k -= nums; 14 | } else { 15 | cur *= 10; 16 | k--; 17 | } 18 | } 19 | return cur; 20 | } 21 | private int getNums(int n, long first, long last) { //long 类型; 22 | int nums = 0; 23 | while(first <= n) { 24 | nums += Math.min(n+1, last) - first; 25 | first *= 10; 26 | last *= 10; 27 | } 28 | return nums; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /2021-03-23/SearchRange34.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class SearchRange34 { 4 | /**Method: Binary search; Time: O(logn); Space: O(1) **/ 5 | public int[] searchRange(int[] nums, int target) { 6 | int start = find(nums, -1, nums.length, target-0.5)+1; //target - 0.5找到的是上一个元素的最后位置,所以要+1 7 | int end = find(nums, -1, nums.length, target+0.5); 8 | if(end >= start) { 9 | return new int[] {start, end}; 10 | } 11 | return new int[]{-1, -1}; 12 | } 13 | 14 | private int find(int[] nums, int start, int end, double target) { 15 | if(end - start <=1) { 16 | return start; 17 | } 18 | int mid= start +(end -start) /2; 19 | if(nums[mid] > target) { 20 | return find(nums, start, mid, target); 21 | } else{ 22 | return find(nums, mid, end, target); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /2021-04-20/CoinChange322.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.Arrays; 4 | 5 | public class CoinChange322 { 6 | /**Method: DP; Time: O(SN); Space:O(N);**/ 7 | /** 8 | 时间复杂度:O(SN),其中 S 是金额,N 是面额数 9 | 定义 dp(i)为组成金额 i 所需最少的硬币数量,假设在计算 dp(i) 之前,我们已经计算出 dp(0)-dp(i-1) 的答案。 则 dp(i) 对应的转移方程应为Math.min(dp[i], dp[i - coins[j]] + 1); 10 | **/ 11 | public int coinChange(int[] coins, int amount) { 12 | int max = amount + 1; 13 | int[] dp = new int[amount + 1]; 14 | Arrays.fill(dp, max); 15 | dp[0] = 0; 16 | for (int i = 1; i <= amount; i++) { 17 | for (int j = 0; j < coins.length; j++) { 18 | if (coins[j] <= i) { 19 | dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1); 20 | } 21 | } 22 | } 23 | return dp[amount] > amount ? -1 : dp[amount]; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /2021-02-27/GetIntersectionNode160.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | 4 | public class GetIntersectionNode160 { 5 | /*Method : Two pointers, Time: O(N + M), Space:O(1)**/ 6 | public ListNode getIntersectionNode(ListNode headA, ListNode headB) { 7 | if(headA == null || headB == null) { 8 | return null; 9 | } 10 | ListNode curA = headA; 11 | ListNode curB = headB; 12 | while(curA != curB) { 13 | curA = curA == null ? headB : curA.next; 14 | curB = curB == null ? headA : curB.next; 15 | } 16 | return curB; 17 | } 18 | 19 | //Definition for singly-linked list. 20 | public class ListNode { 21 | int val; 22 | ListNode next; 23 | ListNode() {} 24 | ListNode(int val) { this.val = val; } 25 | ListNode(int val, ListNode next) { this.val = val; this.next = next; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /2021-02-25/HasCycle141.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | 4 | public class HasCycle141 { 5 | /*Method : Two pointers, Time: O(N), Space:O(1)**/ 6 | public boolean hasCycle(ListNode head) { 7 | if(head == null || head.next == null) { 8 | return false; 9 | } 10 | ListNode slow = head; 11 | ListNode fast = slow.next; 12 | while (slow != fast) { 13 | if(fast == null || fast.next == null) { 14 | return false; 15 | } 16 | slow = slow.next; 17 | fast = fast.next.next; 18 | } 19 | return true; 20 | } 21 | 22 | //Definition for singly-linked list. 23 | public class ListNode { 24 | int val; 25 | ListNode next; 26 | ListNode() {} 27 | ListNode(int val) { this.val = val; } 28 | ListNode(int val, ListNode next) { this.val = val; this.next = next; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /2021-02-18/MergeBigFile.md: -------------------------------------------------------------------------------- 1 | ## 两个 10G 大小包含 URL 数据的文件,最多使用 1G 内存,将这两个文件合并,并找到相同的 URL 2 | 这两个文件分别为A和B文件,因为内存无法将所有的URL都载入,所以可以考虑如下两种方法: 3 | #### 1. 分而治之 4 | - 遍历文件A,对每个url求取hash(url)%100,然后根据所取得的值将url分别存储到100个小文件(记为a0,a1,...,a99)中。这样每个小文件的大约为10G/100 = 100M。 5 | - 遍历文件B,采取和A相同的方式将url分别存储到100小文件(记为b0,b1,...,b99)。这样处理后,所有可能相同的url都在对应的小文件(a0vsb0,a1vsb1,...,a99vsb99)中,不对应的小文件不可能有相同的url。然后要求出100对小文件中url的并集和相同的url。 6 | - 可以把其中一个小文件a(i)的url存储到hashSet中。然后遍历另一个小文件b(i)的每个url,看其是否在刚才构建的hashSet中 7 | - 求相同URL:如果b(i)中的url在a(i)中,那么就是共同的url,存到文件里面就可以了。 8 | - 合并URL:把hashSet中的url都存到文件中,如果b(i)中的url不在hashSet中,那么就存到文件里面就可以了。 9 | #### 2. Bloom filter - 近似算法 10 | - 如果允许有一定的错误率,可以使用Bloom filter 11 | - 1G内存大概可以表示80亿bit。将其中一个文件中的url使用Bloom filter映射为这80亿bit,然后挨个读取另外一个文件的url 12 | - 求相同URL:检查是否存在Bloom filter,如果是,那么该url应该是共同的url(注意会有一定的错误率)。 13 | - 合并文件:将第二个文件中的并集都插入到文件中 14 | -------------------------------------------------------------------------------- /2021-04-01/MinArray11.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class MinArray11 { 4 | /*Method: Binary search, Time: O(target), Space:O(1)**/ 5 | /** 6 | 当 nums[m] > nums[e]时: m 一定在 左排序数组 中,即旋转点 x 一定在 [m+1,e] 闭区间内,因此执行 s = m + 1; 7 | 当 nums[m] < nums[e]时: m 一定在 右排序数组 中,即旋转点 x 一定在[s,m] 闭区间内,因此执行 e = m; 8 | 当 nums[m] = nums[e]时: 无法判断 m 在哪个排序数组中,即无法判断旋转点 x 在 [s, m]还是 [m + 1, e]区间中。解决方案: 执行 e = e - 1 缩小判断范围。 9 | **/ 10 | public int minArray(int[] numbers) { 11 | int s=0,e=numbers.length-1; 12 | while(s numbers[e]) { 17 | s = mid + 1; 18 | } else { 19 | e -= 1; //执行 e = e - 1 缩小判断范围 20 | } 21 | } 22 | return numbers[s]; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /2021-03-10/SwapPairs24.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | 4 | public class SwapPairs24 { 5 | 6 | /**Method: Loop + dummy node; Time:O(N); Space: O(1) **/ 7 | public ListNode swapPairs(ListNode head) { 8 | ListNode dummy = new ListNode(-1); 9 | dummy.next = head; 10 | ListNode cur = dummy; 11 | while(cur.next != null && cur.next.next != null) { 12 | ListNode n1 = cur.next; 13 | ListNode n2= cur.next.next; 14 | cur.next = n2; 15 | n1.next = n2.next; 16 | n2.next = n1; 17 | cur = n1; 18 | } 19 | return dummy.next; 20 | } 21 | 22 | //Definition for singly-linked list. 23 | public class ListNode { 24 | int val; 25 | ListNode next; 26 | ListNode() {} 27 | ListNode(int val) { this.val = val; } 28 | ListNode(int val, ListNode next) { this.val = val; this.next = next; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /2021-04-25/LowestCommonAncestor68II.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | import Leetcode.IsSymmetric803.TreeNode; 3 | public class LowestCommonAncestor68II { 4 | /* Method: DFS, Time: O(N), Space:O(H)**/ 5 | /** 6 | 我们从根节点开始遍历; 7 | 如果当前节点的值大于 p 和 q 的值,说明 p 和 q 应该在当前节点的左子树,因此将当前节点移动到它的左子节点; 8 | 如果当前节点的值小于 p 和 q 的值,说明 p 和 q 应该在当前节点的右子树,因此将当前节点移动到它的右子节点; 9 | p 和 q 要么在当前节点的不同的子树中,要么其中一个就是当前节点。` 10 | **/ 11 | public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { 12 | if(root == null || root == p || root == q) { 13 | return root; 14 | } 15 | TreeNode lson = lowestCommonAncestor(root.left, p, q); 16 | TreeNode rson = lowestCommonAncestor(root.right, p, q); 17 | if(lson == null){ 18 | return rson; 19 | } 20 | if(rson == null) { 21 | return lson; 22 | } 23 | return root; 24 | 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /2021-04-01/LongestConsecutive128.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public class LongestConsecutive128 { 7 | 8 | /*Method: Hash set, Time: O(N), Space:O(N)**/ 9 | /** 10 | 用set去重 11 | 用set的contains方法判断是否包含比x小一的数,没有就从x开始 12 | 用set的contains方法循环判断是否包含比x大一的数据,有就增加len 13 | **/ 14 | public int longestConsecutive(int[] nums) { 15 | Set set = new HashSet<>(); //去重 16 | for(int n: nums) { 17 | set.add(n); 18 | } 19 | int res = 0; 20 | for(int n: set) { 21 | if(!set.contains(n-1)) { //如果没有比它小一个的数据 22 | int curNum = n; 23 | int len = 1; 24 | while(set.contains(curNum+1)) { //就一直往后找连续数组 25 | len ++; 26 | curNum ++; 27 | } 28 | res = Math.max(res, len); 29 | } 30 | } 31 | return res; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /2021-04-16/GetLeastNumbers40.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.PriorityQueue; 4 | import java.util.Queue; 5 | 6 | public class GetLeastNumbers40 { 7 | /**Method: Heap Sort; Time: O(NLogK), Space: O(K) **/ 8 | public int[] getLeastNumbers(int[] arr, int k) { 9 | if (k == 0 || arr.length == 0) { 10 | return new int[0]; 11 | } 12 | // 默认是小根堆,实现大根堆需要重写一下比较器。 13 | Queue pq = new PriorityQueue<>((v1, v2) -> v2 - v1); 14 | for (int num: arr) { 15 | if (pq.size() < k) { 16 | pq.offer(num); 17 | } else if (pq.size() == 0 || num < pq.peek()) { 18 | pq.poll(); 19 | pq.offer(num); 20 | } 21 | } 22 | 23 | // 返回堆中的元素 24 | int[] res = new int[pq.size()]; 25 | int idx = 0; 26 | for(int num: pq) { 27 | res[idx++] = num; 28 | } 29 | return res; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /2021-03-12/IsPalindrome125.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class IsPalindrome125 { 4 | /*Method : Two pointers, Time: O(N), Space:O(1)**/ 5 | /** 6 | * 重点:Character.isLetterOrDigit & Character.toLowerCase 7 | * **/ 8 | public boolean isPalindrome(String s) { 9 | int len = s.length(); 10 | int left = 0; 11 | int right = len-1; 12 | while(left< right) { 13 | while(left < right && !Character.isLetterOrDigit(s.charAt(left))) { 14 | left++; 15 | } 16 | while(left < right && !Character.isLetterOrDigit(s.charAt(right))) { 17 | right--; 18 | } 19 | if(left < right){ 20 | if(Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right))) { 21 | return false; 22 | } 23 | left++; 24 | right--; 25 | } 26 | } 27 | return true; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /2021-03-31/MinStack155.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.Stack; 4 | 5 | public class MinStack155 { 6 | /*Method: Two stack, Time: O(1), Space:O(N)**/ 7 | /** 8 | 注意不是要自己实现栈,目标是常数时间内检索到最小值 9 | **/ 10 | Stack stack; 11 | Stack minStack; 12 | /** initialize your data structure here. */ 13 | public MinStack155() { 14 | stack = new Stack<>(); 15 | minStack = new Stack<>(); 16 | minStack.push(Integer.MAX_VALUE); 17 | } 18 | 19 | public void push(int val) { 20 | stack.push(val); 21 | minStack.push(Math.min(minStack.peek(), val)); //minStack提前灌入MAX_VALUE,这样peek就不会为空 22 | } 23 | 24 | public void pop() { 25 | stack.pop(); 26 | minStack.pop(); 27 | } 28 | 29 | public int top() { 30 | return stack.peek(); 31 | } 32 | 33 | public int getMin() { 34 | return minStack.peek(); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /2021-03-27/RemoveNthFromEnd19.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.Stack; 4 | 5 | public class RemoveNthFromEnd19 { 6 | /*Method : Two pointers, Time: O(N), Space:O(1)**/ 7 | public ListNode removeNthFromEnd3(ListNode head, int n) { 8 | ListNode dummy = new ListNode(0, head); 9 | ListNode f = head; //f从head开始, 跑n步 10 | ListNode s = dummy; // s从dummy开始 11 | for(int i = 0; i0 && obstacleGrid[i][j-1] ==0) { 23 | f[j] += f[j-1]; 24 | } 25 | } 26 | } 27 | return f[m-1]; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /2021-03-05/LongestCommonPrefix14.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class LongestCommonPrefix14 { 4 | /*Method : Compare two strings one by one, Time: O(M*N), Space:O(1)**/ 5 | public String longestCommonPrefix(String[] strs) { 6 | if(strs == null || strs.length == 0) { 7 | return ""; 8 | } 9 | String prefix = strs[0]; 10 | int count = strs.length; 11 | for(int i = 1; i < count; i ++) { 12 | prefix = longestCommonPrefix(prefix, strs[i]); 13 | if(prefix.length() == 0) { 14 | break; 15 | } 16 | } 17 | return prefix; 18 | } 19 | 20 | public String longestCommonPrefix(String str1, String str2) { 21 | int minLen = Math.min(str1.length(), str2.length()); 22 | int index = 0 ; 23 | while(index < minLen&&str1.charAt(index) == str2.charAt(index)){ 24 | index++; 25 | } 26 | return str1.substring(0, index); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /2021-03-29/HasPathSum112.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class HasPathSum112 { 4 | /*Method : Recursive, Time: O(N), Space:O(H)**/ 5 | public boolean hasPathSum(TreeNode root, int targetSum) { 6 | if(root == null) { // root 为空的时候,表示没有path, 所以返回false 7 | return false; 8 | } 9 | if(root.left == null && root.right == null) { //左右节点都为空,才行 10 | return root.val == targetSum; 11 | } 12 | return hasPathSum(root.left, targetSum-root.val) || hasPathSum(root.right, targetSum - root.val); 13 | } 14 | 15 | //Definition for a binary tree node. 16 | public class TreeNode { 17 | int val; 18 | TreeNode left; 19 | TreeNode right; 20 | TreeNode() {} 21 | TreeNode(int val) { this.val = val; } 22 | TreeNode(int val, TreeNode left, TreeNode right) { 23 | this.val = val; 24 | this.left = left; 25 | this.right = right; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /2021-04-10/VerifyPostorderJianZhi33.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class VerifyPostorderJianZhi33 { 4 | /*Method1: recur, Time: O(N), Space:O(H)**/ 5 | /** 6 | 思路:遍历后序遍历的 [i, j]区间元素,寻找 第一个大于根节点 的节点,索引记为 m 。此时,可划分出左子树区间 [i,m-1]、右子树区间 [m, j - 1] 、根节点索引 j 。 7 | 1. p = j : 判断 此树 是否正确。 8 | 2. recur(i, m - 1) : 判断 此树的左子树 是否正确。 9 | 3. recur(m, j - 1) : 判断 此树的右子树 是否正确。 10 | **/ 11 | public boolean verifyPostorder(int[] postorder) { 12 | return recur(postorder, 0, postorder.length - 1); 13 | } 14 | 15 | private boolean recur(int[] postOrder, int s, int e) { 16 | if(s>=e) { 17 | return true; 18 | } 19 | int p = s; 20 | while(postOrder[p] < postOrder[e]) { 21 | p++; 22 | } 23 | int m = p; 24 | while(postOrder[p] > postOrder[e]) { 25 | p++; 26 | } 27 | return p==e && recur(postOrder, s, m-1) && recur(postOrder, m, e-1); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /2021-04-06/IsPalindrome125.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class IsPalindrome125 { 4 | /*Method : Two pointers, Time: O(N), Space:O(1)**/ 5 | /** 6 | * 重点:Character.isLetterOrDigit & Character.toLowerCase 7 | 思路: 8 | 1.若前指针遇到不是字母或数字的元素则向后移动,若后指针碰到不是字母或数字的元素则后指针向前移动。 9 | 2.若尾指针在头指针之前则遍历结束,字符串是回文串 10 | 3.若指针指向的元素符合规则但是不相等则不是回文串 11 | **/ 12 | public boolean isPalindrome(String s) { 13 | int l =0; 14 | int h=s.length()-1; 15 | while(l sumGas) { // 如果这个站点发现油不够了 20 | break; 21 | } 22 | cnt++; 23 | } 24 | if(cnt == n) { // 如果能环绕一圈 25 | return i; 26 | } else {// 不行的话,从第一个无法到达的加油站开始继续检查。 27 | i += cnt + 1; 28 | } 29 | } 30 | return -1; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /2021-04-09/FindMedianSortedArrays4.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | 4 | public class FindMedianSortedArrays4 { 5 | /**Method: Mid number of the merged array; Time:O(N+M); Space: O(N+M) **/ 6 | /** 7 | 转化成寻找两个有序数组中的第 k 小的数,其中 k 为 (m+n)/2 或 (m+n)/2+1。 8 | **/ 9 | public double findMedianSortedArrays(int[] nums1, int[] nums2) { 10 | int l1 = nums1.length; 11 | int l2 =nums2.length; 12 | int k1 =0, k2 =0, k=0; 13 | int[] nums = new int[l1+l2]; 14 | while(k1 < l1 && k2 < l2) { 15 | if(nums1[k1] < nums2[k2]) { 16 | nums[k++] = nums1[k1++]; 17 | } else{ 18 | nums[k++] = nums2[k2++]; 19 | } 20 | } 21 | while(k1 < l1) { 22 | nums[k++] = nums1[k1++]; 23 | } 24 | while(k2 < l2) { 25 | nums[k++] = nums2[k2++]; 26 | } 27 | if(k%2 ==1){ 28 | return nums[k/2]; 29 | } 30 | return (float)(nums[k/2-1] + nums[k/2])/2; //注意float 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /2021-04-21/RandomPickIndex528.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Random; 6 | 7 | public class RandomPickIndex528 { 8 | /** Method:Prefix Sum + Bin Search, Time: O(N), Space:O(N)**/ 9 | /** 10 | 求出前缀和数组 p和总数sum 11 | 在范围 [0, p和总数sumt) 中随机选择一个整数 ran。 12 | 使用二分查找来找到下标 x,其中 x 是满足 ran psum = new ArrayList<>(); 15 | int sum=0; 16 | Random rand = new Random(); 17 | public RandomPickIndex528(int[] w) { 18 | for(int x:w){ 19 | sum+=x; 20 | psum.add(sum); 21 | } 22 | } 23 | 24 | public int pickIndex() { 25 | int tag = rand.nextInt(sum); 26 | int s =0, e= psum.size()-1; 27 | while(s= psum.get(mid)) { 30 | s = mid+1; 31 | } else { 32 | e = mid; 33 | } 34 | } 35 | return s; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /2021-03-15/Permutation38.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public class Permutation38 { 7 | /*Method: BackTrack, Time: O(N*N!), Space:O(N)**/ 8 | Set res = new HashSet<>(); 9 | boolean[] visited; 10 | public String[] permutation(String str) { 11 | if(str==null){ 12 | return new String[]{}; 13 | } 14 | int len = str.length(); 15 | visited=new boolean[len]; 16 | backtracking(str,""); 17 | return res.toArray(new String[len]); 18 | } 19 | private void backtracking(String s,String letter){ 20 | if(s.length() == letter.length()) { 21 | res.add(letter); 22 | return; 23 | } 24 | for(int i=0; i> res = new ArrayList<>(); 9 | List list = new ArrayList<>(); 10 | public List> permute(int[] nums) { 11 | boolean[] visited = new boolean[nums.length]; 12 | backtrack(nums, 0, visited); 13 | return res; 14 | } 15 | private void backtrack(int[] nums, int begin, boolean[] visited) { 16 | if(begin == nums.length) { 17 | res.add(new ArrayList<>(list)); 18 | return; 19 | } 20 | for(int i=0; i< nums.length; i++) { 21 | if(visited[i]) { 22 | continue; 23 | } 24 | visited[i] = true; 25 | list.add(nums[i]); 26 | backtrack(nums, begin + 1, visited); 27 | visited[i] = false; 28 | list.remove(list.size() - 1); 29 | } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /2021-05-20/ConfusingNumber1056.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class ConfusingNumber1056 { 7 | 8 | /*Method: Map, Time: O(N), Space:O(M) -M is the number of confusing**/ 9 | /** 10 | 思路: 11 | 1.输入转字符数组,方便反转判断 12 | 2.遍历数组,同时生成翻转字符串,判断是否0,1,6,8,9. 否直接返回false 13 | 3. 判断是否与翻转后的字符串一致 14 | **/ 15 | public boolean confusingNumber(int n) { 16 | Map map = new HashMap<>(); 17 | map.put("0", "0"); 18 | map.put("1", "1"); 19 | map.put("6", "9"); 20 | map.put("8", "8"); 21 | map.put("9", "6"); 22 | String str = String.valueOf(n); 23 | String res = ""; 24 | for(char c: str.toCharArray()) { 25 | if(!map.containsKey(String.valueOf(c))) { 26 | return false; 27 | } 28 | res = res+ map.get(String.valueOf(c)); 29 | } 30 | return !new StringBuffer(str).reverse().toString().equalsIgnoreCase(res); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /2021-03-07/CombinationSum39.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | public class CombinationSum39 { 8 | /*Method: BackTrack, Time: O(N*2^N), Space:O(Target)**/ 9 | List> result = new ArrayList<>(); 10 | List list = new ArrayList<>(); 11 | public List> combinationSum(int[] candidates, int target) { 12 | Arrays.sort(candidates); 13 | backtrack(candidates, 0, target); 14 | return result; 15 | } 16 | 17 | private void backtrack(int[] candidates, int begin, int target) { 18 | if (target == 0) { 19 | result.add(new ArrayList<>(list)); 20 | return; 21 | } 22 | for (int i = begin; i < candidates.length && target - candidates[i] >= 0; i++) { 23 | list.add(candidates[i]); 24 | backtrack(candidates, i, target - candidates[i]); 25 | list.remove(list.size() - 1); 26 | } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /2021-03-10/MaxAreaOfIsland695.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class MaxAreaOfIsland695 { 4 | 5 | /**Method: DFS; Time:O(R×C); Space: O(R×C) **/ 6 | private int r, c; 7 | private int[][] direction = {{0,1}, {0, -1}, {1, 0}, {-1, 0}}; 8 | public int maxAreaOfIsland(int[][] grid) { 9 | if(grid == null || grid.length == 0) { 10 | return 0; 11 | } 12 | r = grid.length; 13 | c = grid[0].length; 14 | int maxArea = 0; 15 | for(int i=0; i< r;i++) { 16 | for(int j=0; j< c; j++) { 17 | maxArea = Math.max(dfs(grid, i, j), maxArea); 18 | } 19 | } 20 | return maxArea; 21 | } 22 | 23 | private int dfs(int[][] grid, int i, int j){ 24 | if(i<0 || i>=r || j<0 || j>= c || grid[i][j] == 0) { 25 | return 0; 26 | } 27 | grid[i][j] = 0; 28 | int area = 1; 29 | for(int[] d: direction) { 30 | area += dfs(grid, i+d[0], j+d[1]); 31 | } 32 | return area; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /2021-03-27/DetectCycle142.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class DetectCycle142 { 4 | /*Method : Two pointers, Time: O(N), Space:O(1)**/ 5 | public ListNode detectCycle(ListNode head) { 6 | if(head == null || head.next == null) { 7 | return null; //为空 8 | } 9 | 10 | ListNode s = head; 11 | ListNode f = s.next; // f从s的下一个开始 12 | while( f!=s) { 13 | if(f ==null || f.next == null) { //f或者f.next为空,直接返回 14 | return null; 15 | } 16 | f = f.next.next; 17 | s = s.next; 18 | } 19 | s = head; 20 | f = f.next; // f从f的下一个开始 21 | while(s!=f) { 22 | s = s.next; 23 | f = f.next; 24 | } 25 | return s; 26 | } 27 | //Definition for singly-linked list. 28 | public class ListNode { 29 | int val; 30 | ListNode next; 31 | ListNode() {} 32 | ListNode(int val) { this.val = val; } 33 | ListNode(int val, ListNode next) { this.val = val; this.next = next; } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /2021-04-02/Search81.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class Search81 { 4 | /*Method: Binary Search, Time: O(N), Space:O(1)**/ 5 | public boolean search(int[] nums, int target) { 6 | int len = nums.length; 7 | int s =0, e = len-1; 8 | while(s <= e) { 9 | int mid = s+(e-s)/2; 10 | if(nums[mid] == target) { 11 | return true; 12 | } 13 | 14 | if(nums[s] == nums[mid]) { // 分不清到底是前面有序还是后面有序,此时 start++ 即可。相当于去掉一个重复的干扰项。 15 | s ++; 16 | continue; 17 | } 18 | if(nums[s] <= nums[mid]) { 19 | if(nums[s] <= target && target < nums[mid]) { //nums[mid] <=target 20 | e= mid-1; 21 | } else { 22 | s = mid+1; 23 | } 24 | } else { 25 | if(nums[mid] < target && target <= nums[e]) {//target <= nums[e] 26 | s = mid +1; 27 | } else{ 28 | e= mid-1; 29 | } 30 | } 31 | } 32 | return false; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /2021-02-19/RotateSearch33.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class RotateSearch33 { 4 | /**Method: Binary search; Time: O(log(n)); Space: O(1) **/ 5 | public int search(int[] nums, int target) { 6 | int n = nums.length; 7 | if(n == 0) { 8 | return -1; 9 | } 10 | if(n == 1) { 11 | return nums[0] == target ? 0: -1; 12 | } 13 | int start = 0; 14 | int end = n -1; 15 | while (start <= end) { 16 | int mid = start + (end - start) /2; 17 | if(nums[mid] == target) { 18 | return mid; 19 | } 20 | if(nums[0] <= nums[mid]) { 21 | if(target < nums[mid] && nums[0] <= target) { 22 | end = mid - 1; 23 | } else { 24 | start = mid + 1; 25 | } 26 | } else{ 27 | if(target <= nums[n-1] && nums[mid] < target) { 28 | start = mid + 1; 29 | } else { 30 | end = mid - 1; 31 | } 32 | } 33 | } 34 | return -1; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /2021-02-19/SearchRange34.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class SearchRange34 { 4 | /**Method: Binary search; Time: O(logn); Space: O(1) **/ 5 | public int[] searchRange(int[] nums, int target) { 6 | int startIdx = binarySearch(nums, target, true); 7 | int endIdx = binarySearch(nums, target, false) - 1; 8 | if(startIdx <= endIdx && endIdx < nums.length && nums[startIdx] == target && nums[endIdx] == target ) { 9 | return new int[]{startIdx, endIdx}; 10 | } 11 | return new int[]{-1, -1}; 12 | } 13 | 14 | private int binarySearch(int[] nums, int target, boolean isLower) { 15 | int lower = 0, high = nums.length - 1, ans = nums.length; 16 | while(lower <= high) { 17 | int mid = lower + (high - lower) / 2; 18 | if(nums[mid] > target || (isLower && nums[mid] == target)) { 19 | high = mid -1; 20 | ans = mid; 21 | } else { 22 | lower = mid + 1; 23 | } 24 | } 25 | return ans; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /2021-03-14/ShortestSubarray862.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.Deque; 4 | import java.util.LinkedList; 5 | 6 | public class ShortestSubarray862 { 7 | /** Method: sliding window; Time:O(n); Space:o(n) **/ 8 | public int shortestSubarray(int[] A, int K) { 9 | int res = Integer.MAX_VALUE; 10 | Deque dq = new LinkedList(); 11 | int len = A.length; 12 | int[] preSum = new int[len+1]; 13 | for(int i=0;i= preSum[i]) { //如果当前前缀和小于前一个数的前缀和 19 | dq.pollLast(); 20 | } 21 | while(!dq.isEmpty() && preSum[i] - preSum[dq.peekFirst()] >= K) { 22 | res = Math.min(res, i-dq.pollFirst()); 23 | } 24 | } 25 | dq.addLast(i); 26 | } 27 | return res == Integer.MAX_VALUE? -1: res; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /2021-03-29/MaxProfit122.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class MaxProfit122 { 4 | 5 | /*Method 1: DP, Time: O(N), Space:O(1)**/ 6 | public int maxProfit(int[] prices) { 7 | int len = prices.length; 8 | int dp0 = 0; 9 | int dp1 = -prices[0]; //一开始是买入,就是负值 10 | for(int i=1;i map =new HashMap<>(); 17 | int start=-1, res =0; 18 | for(int end=0; end 10 | List> arr = new ArrayList<>(); 11 | int snap = 0; 12 | public SnapshotArray1146(int length) { 13 | for(int i=0; i()); 15 | } 16 | } 17 | 18 | public void set(int index, int val) { 19 | //在index处放入此次版本更新的值 20 | TreeMap map = arr.get(index); 21 | map.put(snap, val); 22 | } 23 | 24 | public int snap() { 25 | return snap++; 26 | } 27 | 28 | public int get(int index, int snap_id) { 29 | TreeMap map = arr.get(index); 30 | //寻找snap_id版本前,最后一次更新的值 31 | Integer key = map.floorKey(snap_id); 32 | return key == null ? 0: map.get(key); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /2021-04-12/MergeTrees617.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class MergeTrees617 { 4 | /*Method: Iteration, Time: O(min(N1, N2)), Space:O(min(N1, N2))**/ 5 | public TreeNode mergeTrees(TreeNode root1, TreeNode root2) { 6 | if(root1 == null && root2 == null) { 7 | return null; 8 | } 9 | if(root1 == null || root2 == null) { 10 | return root1 == null ? root2: root1; 11 | } 12 | TreeNode root = new TreeNode(root1.val + root2.val); 13 | root.left = mergeTrees(root1.left, root2.left); 14 | root.right = mergeTrees(root1.right, root2.right); 15 | return root; 16 | } 17 | 18 | //Definition for a binary tree node. 19 | public class TreeNode { 20 | int val; 21 | TreeNode left; 22 | TreeNode right; 23 | TreeNode() {} 24 | TreeNode(int val) { this.val = val; } 25 | TreeNode(int val, TreeNode left, TreeNode right) { 26 | this.val = val; 27 | this.left = left; 28 | this.right = right; 29 | } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /2021-03-29/IsBalanced55.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class IsBalanced55 { 4 | /**Method:Recursion; Time:O(NLogN); Space:O(N) **/ 5 | public boolean isBalanced(TreeNode root) { // isBalanced(): 判断树 root 是否平衡 6 | if(root == null || (root.left == null && root.right == null)) { 7 | return true; 8 | } 9 | return Math.abs(getLength(root.left) - getLength(root.right)) <= 1 && isBalanced(root.left) && isBalanced(root.right); 10 | } 11 | 12 | private int getLength(TreeNode node) { // depth(): 计算树 root 的深度 13 | if(node == null) { 14 | return 0; 15 | } 16 | return Math.max(getLength(node.left), getLength(node.right)) +1; 17 | } 18 | 19 | public class TreeNode { 20 | int val; 21 | TreeNode left; 22 | TreeNode right; 23 | TreeNode() {} 24 | TreeNode(int val) { this.val = val; } 25 | TreeNode(int val, TreeNode left, TreeNode right) { 26 | this.val = val; 27 | this.left = left; 28 | this.right = right; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /2021-05-13/Convert6.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Convert6 { 7 | /*Method: Print by line, Time: O(N), Space:O(N)**/ 8 | /** 9 | 按顺序遍历字符串 s; 10 | res[i] += c: 把每个字符 c 填入对应行 s_i 11 | i += flag: 更新当前字符 c 对应的行索引; 12 | flag = - flag: 在达到 Z 字形转折点时,执行反向。 13 | **/ 14 | public String convert(String s, int numRows) { 15 | if(numRows < 2) { 16 | return s; 17 | } 18 | List rows = new ArrayList(); 19 | for(int i=0; i0) { 8 | fast = fast.next; 9 | } 10 | while(fast != null) { 11 | slow = slow.next; 12 | fast = fast.next; 13 | } 14 | return slow; 15 | } 16 | 17 | /** Method: Recursive; Space: O(1); Time: O(N); **/ 18 | int size; 19 | public ListNode getKthFromEnd2(ListNode head, int k) { 20 | if(head == null) { 21 | return null; 22 | } 23 | ListNode node = getKthFromEnd2(head.next, k); 24 | if (++size == k) { 25 | return head; 26 | } 27 | return node; 28 | } 29 | 30 | public class ListNode { 31 | int val; 32 | ListNode next; 33 | ListNode() {} 34 | ListNode(int val) { this.val = val; } 35 | ListNode(int val, ListNode next) { this.val = val; this.next = next; } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /2021-02-24/DeleteDuplicates82.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class DeleteDuplicates82 { 4 | 5 | /**Method: Iteration + dummy node; Time:O(N); Space: O(1) **/ 6 | public ListNode deleteDuplicates(ListNode head) { 7 | ListNode dummy = new ListNode(0); 8 | dummy.next = head; 9 | ListNode cur = dummy; 10 | while(cur.next != null && cur.next.next != null) { 11 | if(cur.next.val == cur.next.next.val) { 12 | ListNode temp = cur.next; 13 | while (temp != null && temp.next != null && temp.val == temp.next.val) { 14 | temp = temp.next; 15 | } 16 | cur.next = temp.next; 17 | } else { 18 | cur = cur.next; 19 | } 20 | } 21 | return dummy.next; 22 | } 23 | 24 | //Definition for singly-linked list. 25 | public class ListNode { 26 | int val; 27 | ListNode next; 28 | ListNode() {} 29 | ListNode(int val) { this.val = val; } 30 | ListNode(int val, ListNode next) { this.val = val; this.next = next; } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /2021-05-10/DailyTemperatures739.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.Deque; 4 | import java.util.LinkedList; 5 | 6 | public class DailyTemperatures739 { 7 | /** Method:Stack; Time: O(N); Space:O(N);**/ 8 | /** 9 | 维护一个存储下标的单调栈,从栈底到栈顶的下标对应的温度列表中的温度依次递减。 10 | 如果一个下标在单调栈里,则表示尚未找到下一次温度更高的下标。 11 | 正向遍历温度列表。 12 | 对于温度列表中的每个元素 T[i],如果栈为空,则直接将 i 进栈 13 | 如果栈不为空,则比较栈顶元素 prevIndex 对应的温度 T[prevIndex] 和当前温度 T[i] 14 | 如果 T[i] > T[prevIndex],则将 prevIndex 移除,并将 prevIndex 对应的等待天数赋为 i - prevIndex,重复上述操作直到栈为空或者栈顶元素对应的温度小于等于当前温度,然后将 i 进栈。 15 | **/ 16 | public int[] dailyTemperatures(int[] T) { 17 | int len = T.length; 18 | int[] ans = new int[len]; 19 | Deque stack = new LinkedList(); 20 | for(int i=0; i T[stack.peek()]) { 23 | int preIndex = stack.pop(); 24 | ans[preIndex] = i- preIndex; 25 | } 26 | stack.push(i); 27 | } 28 | return ans; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /2021-03-23/FindPeakElement162.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class FindPeakElement162 { 4 | /**Method: Binary search; Time: O(log(n)); Space: O(1) **/ 5 | public int findPeakElement(int[] nums) { 6 | int s = 0, e = nums.length-1; 7 | while(s nums[mid+1]) { // x和它的下一个值比较,判峰值是在左边还是右边 10 | e = mid; // mid可能就是峰值,所以e=mid 11 | } else { 12 | s = mid+1; 13 | } 14 | } 15 | return s; 16 | } 17 | 18 | /**Method2: Binary search with recursive; Time: O(log(n)); Space: O(log(n)) **/ 19 | public int findPeakElement2(int[] nums) { 20 | return binarySearch(nums, 0, nums.length -1); 21 | } 22 | 23 | private int binarySearch (int[] nums, int start, int end) { 24 | if(start == end) { 25 | return start; 26 | } 27 | int mid = start + (end - start)/2; 28 | if(nums[mid] > nums[mid +1]) { 29 | return binarySearch(nums, start, mid); 30 | } 31 | return binarySearch(nums, mid+1, end); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /2021-04-06/ValidPalindrome680.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class ValidPalindrome680 { 4 | /**Method: Greedy + Two pointers ; Time:O(N); Space: O(1) **/ 5 | /** 6 | 思路:定义左右指针,初始时分别指向字符串的第一个字符和最后一个字符,每次判断左右指针指向的字符是否相同: 7 | 如果相同,则将左右指针都往中间移动一位,直到左右指针相遇,则字符串是回文串。 8 | 如果两个指针指向的字符不同,则两个字符中必须有一个被删除:(因为允许最多删除一个字符) 9 | 1. 删除左指针对应的字符,留下子串 [l+1,h] 10 | 2. 删除右指针对应的字符,留下子串 [l+1,h-1] 11 | **/ 12 | public boolean validPalindrome(String s) { 13 | int l = 0,h=s.length()-1; 14 | while(l generateParenthesis(int n) { 12 | List res = new ArrayList(); 13 | backtrack(res, new StringBuilder(), 0, 0, n); 14 | return res; 15 | } 16 | 17 | public void backtrack(List res, StringBuilder cur, int open, int close, int max){ 18 | if(cur.length() == max*2) { 19 | res.add(cur.toString()); 20 | return; 21 | } 22 | if(open < max){ 23 | cur.append('('); 24 | backtrack(res, cur, open+1, close, max); 25 | cur.deleteCharAt(cur.length() -1); 26 | } 27 | if(close < open) { 28 | cur.append(')'); 29 | backtrack(res, cur, open, close+1, max); 30 | cur.deleteCharAt(cur.length()-1); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /2021-02-23/MaxPathSum124.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class MaxPathSum124 { 4 | /**Method: Recursion; Time:O(N); Space: O(N) **/ 5 | int maxSum = Integer.MIN_VALUE; 6 | public int maxPathSum(TreeNode root) { 7 | maxGain(root); 8 | return maxSum; 9 | } 10 | private int maxGain(TreeNode root) { 11 | if(root == null) { 12 | return 0; 13 | } 14 | int leftGain = Math.max(maxGain(root.left) , 0); 15 | int rightGain = Math.max(maxGain(root.right), 0); 16 | int curGain = root.val + leftGain + rightGain; 17 | maxSum = Math.max(maxSum, curGain); 18 | return root.val + Math.max(leftGain, rightGain); 19 | } 20 | 21 | //Definition for a binary tree node. 22 | public class TreeNode { 23 | int val; 24 | TreeNode left; 25 | TreeNode right; 26 | TreeNode() {} 27 | TreeNode(int val) { this.val = val; } 28 | TreeNode(int val, TreeNode left, TreeNode right) { 29 | this.val = val; 30 | this.left = left; 31 | this.right = right; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /2021-02-13/SortArrayHeapSort912.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class SortArrayHeapSort912 { 4 | /** 5 | * Method2: HeapSort; Average Time: O(NlogN), The Best Time: O(N), The Worst Time: O(N^2); Space: O(1) Stability: false 6 | **/ 7 | public int[] sortArray(int[] nums) { 8 | heapSortAsc(nums, nums.length); 9 | return nums; 10 | } 11 | private void heapSortAsc(int[] a, int n) { 12 | int i,tmp; 13 | for (i = n / 2 - 1; i >= 0; i--) {maxHeapDown(a, i, n-1);} 14 | for (i = n - 1; i > 0; i--) { 15 | tmp = a[0]; 16 | a[0] = a[i]; 17 | a[i] = tmp; 18 | maxHeapDown(a, 0, i-1); 19 | } 20 | } 21 | private void maxHeapDown(int[] a, int start, int end) { 22 | int c = start; 23 | int l = 2*c + 1; 24 | int tmp = a[c]; 25 | for (; l <= end; c=l,l=2*l+1) { 26 | if ( l < end && a[l] < a[l+1]) 27 | l++; 28 | if (tmp >= a[l]) 29 | break; 30 | else { 31 | a[c] = a[l]; 32 | a[l]= tmp; 33 | } 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /2021-02-19/FindPeakElement162.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class FindPeakElement162 { 4 | /**Method: Binary search; Time: O(log(n)); Space: O(1) **/ 5 | public int findPeakElement(int[] nums) { 6 | int start = 0; 7 | int end = nums.length -1; 8 | while (start < end) { 9 | int mid = start + (end - start) / 2; 10 | if(nums[mid] > nums[mid +1]) { 11 | end = mid; 12 | } else { 13 | start = mid + 1; 14 | } 15 | } 16 | return start; 17 | } 18 | 19 | /**Method2: Binary search with recursive; Time: O(log(n)); Space: O(log(n)) **/ 20 | public int findPeakElement2(int[] nums) { 21 | return binarySearch(nums, 0, nums.length -1); 22 | } 23 | 24 | private int binarySearch (int[] nums, int start, int end) { 25 | if(start == end) { 26 | return start; 27 | } 28 | int mid = start + (end - start)/2; 29 | if(nums[mid] > nums[mid +1]) { 30 | return binarySearch(nums, start, mid); 31 | } 32 | return binarySearch(nums, mid+1, end); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /2021-04-22/GoodNodes1448.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import Leetcode.BinTree.MaxPathSum124; 4 | 5 | 6 | public class GoodNodes1448 { 7 | 8 | /**Method: Recursion; Time:O(N); Space: O(H) **/ 9 | /** 10 | 引入辅助函数 countGoodNodes,逻辑为: 11 | 1.该函数保留当前节点前的路径上的最大值 maxValue 12 | 2.如果当前节点的值更大,计数并更新 maxValue,再继续向左、右节点递归 13 | 3.空节点递归终止 14 | **/ 15 | int cnt = 0; 16 | public int goodNodes(TreeNode root) { 17 | countGoodNodes(root, Integer.MIN_VALUE); 18 | return cnt; 19 | } 20 | private void countGoodNodes(TreeNode root, int maxValue) { 21 | if (root == null) return; 22 | if (root.val >= maxValue) { 23 | cnt++; 24 | maxValue = root.val; 25 | } 26 | countGoodNodes(root.left, maxValue); 27 | countGoodNodes(root.right, maxValue); 28 | } 29 | 30 | /** 31 | * Definition for a binary tree node. 32 | */ 33 | public class TreeNode { 34 | 35 | int val; 36 | TreeNode left; 37 | TreeNode right; 38 | 39 | TreeNode(int x) { 40 | val = x; 41 | } 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /2021-05-09/RomanToInt13.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class RomanToInt13 { 4 | 5 | /** Method: Traversal + Save Pre sum; Time: O(Len); Space:O(1);**/ 6 | /** 7 | 罗马数字由 I,V,X,L,C,D,M 构成; 8 | 当小值在大值的左边,则减小值,如 IV=5-1=4; 9 | 当小值在大值的右边,则加小值,如 VI=5+1=6; 10 | 由上可知,右值永远为正,因此最后一位必然为正。 11 | **/ 12 | public int romanToInt(String s) { 13 | int sum = 0; 14 | int preSum = getValue(s.charAt(0)); 15 | for(int i=1; i all = new PriorityQueue(intervals.length, (a,b) -> a-b); 21 | Arrays.sort(intervals, (a, b) -> a[0] - b[0]); 22 | all.add(intervals[0][1]); 23 | for(int i=1; i= all.peek()) { 25 | all.poll(); 26 | } 27 | all.add(intervals[i][1]); 28 | } 29 | return all.size(); 30 | } 31 | 32 | 33 | } 34 | -------------------------------------------------------------------------------- /2021-04-15/Rob213.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.Arrays; 4 | 5 | public class Rob213 { 6 | /**Method: DP; Time: O(N), Space: O(1) **/ 7 | /** 8 | 把此环状排列房间问题约化为两个单排排列房间子问题: 9 | 在不偷窃第一个房子的情况下(即 nums[1:],最大金额是 p1 10 | 在不偷窃最后一个房子的情况下(即 nums[:n-1]),最大金额是 p2 11 | 综合偷窃最大金额: 为以上两种情况的较大值,即 max(p1,p2) 12 | **/ 13 | public int rob(int[] nums) { 14 | int len = nums.length; 15 | if(len ==0) { 16 | return 0; 17 | } 18 | if(len == 1) { 19 | return nums[0]; 20 | } 21 | if(len == 2) { 22 | return Math.max(nums[0], nums[1]); 23 | } 24 | return Math.max(robRange(Arrays.copyOfRange(nums, 0, len-1)), robRange( 25 | Arrays.copyOfRange(nums, 1, len))); 26 | } 27 | private int robRange(int[] nums){ //dp[n] 只与 dp[n−1] 和 dp[n−2] 有关系,因此我们可以设两个变量 cur和 pre 交替记录,将空间复杂度降到 O(1)。 28 | int pre = 0; 29 | int cur =0; 30 | for(int num:nums) { 31 | int temp = cur; 32 | cur = Math.max(pre+num, temp); 33 | pre = temp; 34 | } 35 | return cur; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /2021-04-30/SimplifyPath71.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.Stack; 4 | 5 | public class SimplifyPath71 { 6 | 7 | /**Method: Stack; Time: O(N); Space: O(N) **/ 8 | /** 9 | 1.定义一个辅助栈; 10 | 2.先把字符串以"/"为分隔符分割成数组,此时数组有"路径"、""、"."、".."这四种情况; 11 | 3.遍历数组,当s[i].equals("..")并且栈不空时pop,当!s[i].equals("") && !s[i].equals(".") && !s[i].equals(".."),即s[i]是路径入栈; 12 | 4.栈空,返回"/",栈非空,StringBuilder返回; 13 | **/ 14 | public String simplifyPath(String path) { 15 | String[] s = path.split("/"); 16 | Stack stack = new Stack<>(); 17 | 18 | for (int i = 0; i < s.length; i++) { 19 | if (!stack.isEmpty() && s[i].equals("..")) 20 | stack.pop(); 21 | else if (!s[i].equals("") && !s[i].equals(".") && !s[i].equals("..")) 22 | stack.push(s[i]); 23 | } 24 | if (stack.isEmpty()) 25 | return "/"; 26 | 27 | StringBuffer res = new StringBuffer(); 28 | for (int i = 0; i < stack.size(); i++) { 29 | res.append("/" + stack.get(i)); 30 | } 31 | return res.toString(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /2021-03-01/Intersection349.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public class Intersection349 { 7 | /*Method : Two Sets, Time: O(M+N), Space:O(M+N)**/ 8 | public int[] intersection(int[] nums1, int[] nums2) { 9 | Set set1 = new HashSet(); 10 | Set set2 = new HashSet(); 11 | for(int num: nums1) { 12 | set1.add(num); 13 | } 14 | for(int num:nums2) { 15 | set2.add(num); 16 | } 17 | return intersection(set1, set2); 18 | } 19 | 20 | public int[] intersection(Set set1, Set set2) { 21 | if(set1.size() > set2.size()) { 22 | return intersection(set2, set1); 23 | } 24 | Set resSet = new HashSet<>(); 25 | for(int num: set1) { 26 | if(set2.contains(num)) { 27 | resSet.add(num); 28 | } 29 | } 30 | int[] res = new int[resSet.size()]; 31 | int index = 0; 32 | for (int num : resSet) { 33 | res[index++] = num; 34 | } 35 | return res; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /2021-03-27/DeleteDuplicates82.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class DeleteDuplicates82 { 4 | 5 | /**Method: Iteration + dummy node; Time:O(N); Space: O(1) **/ 6 | public ListNode deleteDuplicates(ListNode head) { 7 | ListNode dummy = new ListNode(-1); 8 | dummy.next = head; 9 | ListNode cur = dummy; // cur从dummy开始 10 | while(cur.next != null && cur.next.next != null) { // 是next 和 next.next对比 11 | if(cur.next.val == cur.next.next.val) { 12 | ListNode temp = cur.next; 13 | while(temp != null && temp.next != null && temp.val == temp.next.val) { 14 | temp = temp.next; 15 | } 16 | cur.next = temp.next; 17 | } else { 18 | cur = cur.next; 19 | } 20 | } 21 | return dummy.next; 22 | } 23 | 24 | //Definition for singly-linked list. 25 | public class ListNode { 26 | int val; 27 | ListNode next; 28 | ListNode() {} 29 | ListNode(int val) { this.val = val; } 30 | ListNode(int val, ListNode next) { this.val = val; this.next = next; } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /2021-04-20/Trap42.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class Trap42 { 4 | 5 | /**Method: Two Pointers; Time: O(N); Space:O(1);**/ 6 | /** 7 | 当两个指针没有相遇时,进行如下操作: 8 | 使用 height[left] 和 height[right]的值更新 leftMax和 rightMax 的值; 9 | 如果 height[left] 结果数组中最后区间的终止位置, 则不合并,直接将当前区间加入结果数组。 14 | 4. 反之将当前区间合并至结果数组的最后区间 15 | **/ 16 | public int[][] merge(int[][] intervals) { 17 | if(intervals == null ||intervals.length==0) { 18 | return new int[0][0]; 19 | } 20 | Arrays.sort(intervals, (v1, v2) -> v1[0] - v2[0]); 21 | List res = new ArrayList<>(); 22 | int idx = 0; 23 | for(int i=0; i< intervals.length; i++) { 24 | int start = intervals[i][0], end = intervals[i][1]; 25 | if(idx ==0 || res.get(idx-1)[1] < start) { 26 | res.add(new int[]{start, end}); 27 | idx++; 28 | } else{ 29 | res.get(idx-1)[1] = Math.max(end, res.get(idx-1)[1]); 30 | } 31 | } 32 | return res.toArray(new int[idx][]); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /2021-04-12/IsBalanced110.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | 4 | public class IsBalanced110 { 5 | /*Method : Recursive, Time: O(N^2), Space:O(N)**/ 6 | boolean result = true; //全局返回值 7 | public boolean isBalanced(TreeNode root) { 8 | if(root == null) { 9 | return true; //为null是balance的 10 | } 11 | getDepth(root); 12 | return result; 13 | } 14 | 15 | private int getDepth(TreeNode node) { 16 | if(node == null) { 17 | return 0; 18 | } 19 | int leftH = getDepth(node.left); 20 | int rightH = getDepth(node.right); 21 | if(Math.abs(leftH - rightH) > 1){ 22 | result = false; 23 | } 24 | return 1+ Math.max(leftH, rightH); 25 | } 26 | 27 | //Definition for a binary tree node. 28 | public class TreeNode { 29 | int val; 30 | TreeNode left; 31 | TreeNode right; 32 | TreeNode() {} 33 | TreeNode(int val) { this.val = val; } 34 | TreeNode(int val, TreeNode left, TreeNode right) { 35 | this.val = val; 36 | this.left = left; 37 | this.right = right; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /2021-05-11/Preorder589.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | import java.util.Stack; 7 | 8 | public class Preorder589 { 9 | /*Method: Iterator, Time: O(N), Space:O(H)**/ 10 | public List preorder(Node root) { 11 | List res=new ArrayList<>(); 12 | if(root == null) { 13 | return res; 14 | } 15 | Stack s = new Stack<>(); 16 | s.push(root); 17 | while(!s.isEmpty()) { 18 | Node node = s.pop(); 19 | res.add(node.val); 20 | Collections.reverse(node.children); 21 | for(Node child: node.children) { 22 | s.push(child); 23 | } 24 | 25 | } 26 | return res; 27 | } 28 | 29 | class Node { 30 | public int val; 31 | public List children; 32 | 33 | public Node() {} 34 | 35 | public Node(int _val) { 36 | val = _val; 37 | } 38 | 39 | public Node(int _val, List _children) { 40 | val = _val; 41 | children = _children; 42 | } 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /2021-05-11/ReverseParentheses1190.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class ReverseParentheses1190 { 4 | /*Method: Two Pointers, Time: O(N), Space:O(N)**/ 5 | public String reverseParentheses(String s) { 6 | char[] arr = s.toCharArray(); 7 | int r = 0, l, len = s.length(); 8 | while(r < len) { 9 | if(arr[r] != ')') { 10 | r += 1; 11 | continue; 12 | } else { 13 | l = r; 14 | while(arr[l] != '(') { 15 | l -= 1; 16 | } 17 | arr[l] = '0'; 18 | arr[r] = '0'; 19 | reverse(arr, l, r); 20 | } 21 | } 22 | StringBuilder res = new StringBuilder(); 23 | for(int i=0; i< len; i++) { 24 | if(arr[i] != '0') { 25 | res.append(arr[i]); 26 | } 27 | } 28 | return res.toString(); 29 | } 30 | 31 | public void reverse(char[] arr, int start, int end){ 32 | while(start < end){ 33 | char temp = arr[start]; 34 | arr[start] = arr[end]; 35 | arr[end] = temp; 36 | start += 1; 37 | end -= 1; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /2021-04-12/DiameterOfBinaryTree543.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class DiameterOfBinaryTree543 { 4 | /*Method: Iteration, Time: O(N), Space:O(H)**/ 5 | /** 6 | 直径 = 左子树高度 + 右子树高度;不包含当前节点,看示例是返回3 = 左边(2) +右边(1) 7 | **/ 8 | int maxD = 0; //全局变量 9 | public int diameterOfBinaryTree(TreeNode root) { 10 | getMaxDepth(root); 11 | return maxD; 12 | } 13 | 14 | private int getMaxDepth(TreeNode node) { 15 | if(node == null) { 16 | return 0; 17 | } 18 | int leftH = getMaxDepth(node.left); 19 | int rightH = getMaxDepth(node.right); 20 | maxD = Math.max(maxD, leftH+rightH); //直径 = 左子树高度 + 右子树高度; 21 | return Math.max(leftH, rightH) +1; 22 | } 23 | 24 | //Definition for a binary tree node. 25 | public class TreeNode { 26 | int val; 27 | TreeNode left; 28 | TreeNode right; 29 | TreeNode() {} 30 | TreeNode(int val) { this.val = val; } 31 | TreeNode(int val, TreeNode left, TreeNode right) { 32 | this.val = val; 33 | this.left = left; 34 | this.right = right; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /2021-03-26/MaxPathSum124.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class MaxPathSum124 { 4 | /**Method: Recursion; Time:O(N); Space: O(N) **/ 5 | int maxSum = Integer.MIN_VALUE; 6 | public int maxPathSum(TreeNode root) { 7 | maxGain(root); 8 | return maxSum; 9 | } 10 | 11 | 12 | private int maxGain(TreeNode node) { 13 | if(node == null) { 14 | return 0; 15 | } 16 | int leftGain = Math.max(maxGain(node.left), 0); //maxGain可能有node的和<0,所以要和0取最大值 17 | int rightGain = Math.max(maxGain(node.right), 0); 18 | int pathValue = node.val +leftGain + rightGain; 19 | maxSum = Math.max(pathValue, maxSum); 20 | return node.val + Math.max(leftGain, rightGain); 21 | } 22 | 23 | //Definition for a binary tree node. 24 | public class TreeNode { 25 | int val; 26 | TreeNode left; 27 | TreeNode right; 28 | TreeNode() {} 29 | TreeNode(int val) { this.val = val; } 30 | TreeNode(int val, TreeNode left, TreeNode right) { 31 | this.val = val; 32 | this.left = left; 33 | this.right = right; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /2021-05-05/AddTwoNumbers2.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class AddTwoNumbers2 { 4 | 5 | /**Method: Mock Add; Time:O(Max(M,N)); Space: O(1) **/ 6 | public ListNode addTwoNumbers(ListNode l1, ListNode l2) { 7 | int carry =0; 8 | ListNode dummy = new ListNode(); 9 | ListNode cur = dummy; 10 | while(l1 != null || l2 != null || carry !=0 ){ 11 | int x = l1 == null ? 0: l1.val; 12 | int y = l2 == null ? 0: l2.val; 13 | int sum=x+y+carry; 14 | ListNode node = new ListNode(sum %10); 15 | carry = sum /10; 16 | cur.next = node; 17 | cur = node; 18 | if(l1!=null) { //记住 l1, l2需要next 19 | l1=l1.next; 20 | } 21 | if(l2!=null) { 22 | l2=l2.next; 23 | } 24 | } 25 | return dummy.next; 26 | } 27 | 28 | //Definition for singly-linked list. 29 | public class ListNode { 30 | int val; 31 | ListNode next; 32 | ListNode() {} 33 | ListNode(int val) { this.val = val; } 34 | ListNode(int val, ListNode next) { this.val = val; this.next = next; } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /2021-02-26/RotateRight61.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import Leetcode.DetectCycle142.ListNode; 4 | 5 | public class RotateRight61 { 6 | /*Method : Two pointers, Time: O(N), Space:O(1)**/ 7 | public ListNode rotateRight(ListNode head, int k) { 8 | if(head == null) { 9 | return null; 10 | } 11 | if(head.next == null) { 12 | return head; 13 | } 14 | ListNode old_tail = head; 15 | int n = 1; 16 | while (old_tail.next != null) { 17 | old_tail = old_tail.next; 18 | n ++; 19 | } 20 | old_tail.next = head; 21 | ListNode new_tail = head; 22 | 23 | for(int i =0; i< n- k%n-1; i++) { 24 | new_tail = new_tail.next; 25 | } 26 | ListNode new_head = new_tail.next; 27 | new_tail.next = null; 28 | return new_head; 29 | } 30 | 31 | //Definition for singly-linked list. 32 | public class ListNode { 33 | int val; 34 | ListNode next; 35 | ListNode() {} 36 | ListNode(int val) { this.val = val; } 37 | ListNode(int val,ListNode next) { this.val = val; this.next = next; } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /2021-03-01/MedianLintCode80.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class MedianLintCode80 { 4 | /** 5 | * @param nums: A list of integers 6 | * @return: An integer denotes the middle number of the array 7 | */ 8 | /**Method: Partition of Quick Sort;Amortized Time: O(N); Space:O(1) **/ 9 | public int median(int[] nums) { 10 | return partition(nums, 0, nums.length-1, nums.length - nums.length/2); 11 | } 12 | 13 | private int partition(int[] nums, int start, int end, int k) { 14 | int i = start; 15 | int j = end; 16 | int pivot = nums[i]; 17 | while(i< j) { 18 | while(i= pivot ) { 19 | j--; 20 | } 21 | nums[i] = nums[j]; 22 | while(i k-1){ 32 | return partition(nums,start,i-1,k); 33 | } 34 | else { 35 | return partition(nums,i+1,end,k-(i-start+1)); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /2021-04-14/Merge56.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | public class Merge56 { 8 | 9 | /**Method: sort the start and merge; Time: O(NLogN); Space:O(N);**/ 10 | /** 11 | 1. 先按照区间起始位置排序 12 | 2. 遍历区间 13 | 3. 如果结果数组是空的,或者当前区间的起始位置 > 结果数组中最后区间的终止位置, 则不合并,直接将当前区间加入结果数组。 14 | 4. 反之将当前区间合并至结果数组的最后区间 15 | **/ 16 | public int[][] merge(int[][] intervals) { 17 | if(intervals.length == 0) { 18 | return new int[0][0]; 19 | } 20 | Arrays.sort(intervals, (v1, v2) -> v1[0] - v2[0]); //compare and sort 21 | List res= new ArrayList<>(); 22 | int idx = 0; 23 | for(int i = 0;i< intervals.length; i++) { 24 | int start = intervals[i][0], end = intervals[i][1]; 25 | if(idx==0 || res.get(idx-1)[1] int[] 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /2021-04-16/TopKFrequent347.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.PriorityQueue; 6 | 7 | public class TopKFrequent347 { 8 | /**Method: Heap Sort; Time: O(NLogK), Space: O(K) **/ 9 | public int[] topKFrequent(int[] nums, int k) { 10 | Map map = new HashMap<>(); 11 | for(int num: nums){ 12 | map.put(num, map.getOrDefault(num, 0) +1); 13 | } 14 | // int[] 的第一个元素代表数组的值,第二个元素代表了该值出现的次数 15 | PriorityQueue pq = new PriorityQueue<>((v1, v2) -> v1[1]-v2[1]); 16 | for(Map.Entry entry: map.entrySet()) { 17 | int key = entry.getKey(), val = entry.getValue(); 18 | if(pq.size() == k) { 19 | if(pq.peek()[1] < val) { 20 | pq.poll(); 21 | pq.offer(new int[]{key, val}); 22 | } 23 | 24 | } else { 25 | pq.offer(new int[]{key, val}); 26 | } 27 | } 28 | int[] res = new int[k]; 29 | for(int i=0; i> res = new ArrayList<>(); 10 | List list = new ArrayList<>(); 11 | public List> permuteUnique(int[] nums) { 12 | boolean[] visited = new boolean[nums.length]; 13 | Arrays.sort(nums); 14 | backtrack(nums, 0, visited); 15 | return res; 16 | } 17 | 18 | private void backtrack(int[] nums, int begin, boolean[] visited) { 19 | if(begin == nums.length) { 20 | res.add(new ArrayList<>(list)); 21 | return; 22 | } 23 | for(int i=0; i< nums.length; i++) { 24 | if(visited[i] || (i>0 && nums[i] == nums[i-1] && !visited[i-1])) { 25 | continue; 26 | } 27 | visited[i] = true; 28 | list.add(nums[i]); 29 | backtrack(nums, begin + 1, visited); 30 | visited[i] = false; 31 | list.remove(list.size() - 1); 32 | } 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /2021-04-13/MinDiffInBST783.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class MinDiffInBST783 { 4 | /**Method: Iteration by InOrder; Time: O(N), Space: O(N) **/ 5 | /** 6 | 思路:二叉查找树中序遍历有序 7 | 计算中序遍历中临近两节点之差的绝对值,取最小值 8 | **/ 9 | int minDiff = Integer.MAX_VALUE; 10 | TreeNode pre = null; // 用全局变量记录前一个节点 11 | public int minDiffInBST(TreeNode root) { 12 | inOrder(root); 13 | return minDiff; 14 | } 15 | private void inOrder(TreeNode node) { 16 | if(node == null) { 17 | return; 18 | } 19 | inOrder(node.left); 20 | if(pre != null) { 21 | minDiff = Math.min(Math.abs(node.val-pre.val), minDiff); 22 | } 23 | pre = node; 24 | inOrder(node.right); 25 | } 26 | 27 | //Definition for a binary tree node. 28 | public class TreeNode { 29 | int val; 30 | TreeNode left; 31 | TreeNode right; 32 | TreeNode() {} 33 | TreeNode(int val) { this.val = val; } 34 | TreeNode(int val, TreeNode left, TreeNode right) { 35 | this.val = val; 36 | this.left = left; 37 | this.right = right; 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /2021-03-13/ReverseBetween92.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class ReverseBetween92 { 4 | 5 | /** Method: Recursion; Times:O(N); Space:N(1) **/ 6 | /** 7 | * 使用三个指针: pre, cur, next 8 | * 先将 curr 的下一个节点记录为 next; 9 | * 执行操作 ①:把 curr 的下一个节点指向 next 的下一个节点; 10 | * 执行操作 ②:把 next 的下一个节点指向 pre 的下一个节点; 11 | * 执行操作 ③:把 pre 的下一个节点指向 next。 12 | */ 13 | public ListNode reverseBetween(ListNode head, int left, int right) { 14 | ListNode dummy = new ListNode(-1); 15 | dummy.next = head; 16 | ListNode pre = dummy; 17 | for(int i = 0; i< left-1; i++) { 18 | pre = pre.next; 19 | } 20 | ListNode cur = pre.next; 21 | for(int i=left; i spiralOrder(int[][] matrix) { 9 | List res = new ArrayList<>(); 10 | if(matrix == null || matrix.length ==0 || matrix[0].length ==0) { 11 | return res; 12 | } 13 | int rs = matrix.length, cs = matrix[0].length; 14 | int l = 0, r=cs-1, t=0,b=rs-1; //b=rs-1 15 | while(l<=r && t<=b){ 16 | for(int col = l; col<=r; col++) { 17 | res.add(matrix[t][col]); 18 | } 19 | for(int row = t+1; row<=b;row++) { 20 | res.add(matrix[row][r]); 21 | } 22 | if(l l; col--) { 24 | res.add(matrix[b][col]); 25 | } 26 | for(int row = b; row > t; row--) { 27 | res.add(matrix[row][l]); 28 | } 29 | } 30 | l++; 31 | r--; 32 | t++; 33 | b--; 34 | } 35 | return res; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /2021-02-22/InsertNodeBstLintcode85.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class InsertNodeBstLintcode85 { 4 | /* 5 | * @param root: The root of the binary search tree. 6 | * @param node: insert this node into the binary search tree 7 | * @return: The root of the new binary search tree. 8 | */ 9 | /**Method: Recursive; Time:O(H); Space: O(H) **/ 10 | public TreeNode insertNode(TreeNode root, TreeNode node) { 11 | // write your code here 12 | if(root == null) { 13 | return node; 14 | } 15 | if(node.val < root.val) { 16 | root.left = insertNode(root.left, node); 17 | } else if (node.val > root.val) { 18 | root.right = insertNode(root.right, node); 19 | } 20 | return root; 21 | } 22 | 23 | //Definition for a binary tree node. 24 | public class TreeNode { 25 | int val; 26 | TreeNode left; 27 | TreeNode right; 28 | TreeNode() {} 29 | TreeNode(int val) { this.val = val; } 30 | TreeNode(int val, TreeNode left, TreeNode right) { 31 | this.val = val; 32 | this.left = left; 33 | this.right = right; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /2021-03-18/isNumberNewCode20.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class isNumberNewCode20 { 4 | /**Time: O(N), Space: O(1) **/ 5 | public boolean isNumber(String s) { 6 | if(s == null || s.length() ==0) { 7 | return false; 8 | } 9 | s = s.trim(); //1. 去空格 10 | boolean numFlag = false; 11 | boolean dotFlag = false; 12 | boolean eFlag = false; 13 | for(int i =0; i= '0' && s.charAt(i) <= '9') { // 2.比较数字 15 | numFlag = true; 16 | } else if(s.charAt(i) == '.' && !dotFlag && !eFlag) { // 3. '.'之前不能有E/e 17 | dotFlag = true; 18 | } else if(s.charAt(i) == '+' || s.charAt(i) == '-') { // 4. '+'/'-' 只能出现在首位或者E/e后面 19 | if(i!=0 && (i-1 >=0 && (s.charAt(i-1) != 'e' &&s.charAt(i-1) != 'E'))) { 20 | return false; 21 | } 22 | } else if((s.charAt(i) == 'e' || s.charAt(i) == 'E') && numFlag&& !eFlag) { // 5. 当前为E/e,之前没出现过,并且 之前要有数字 23 | eFlag = true; 24 | numFlag= false; //防止e结尾 25 | } else { 26 | return false; 27 | } 28 | } 29 | return numFlag; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /2021-03-21/SortArrayHeapSort912.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class SortArrayHeapSort912 { 4 | /** 5 | * Method2: HeapSort; Average Time: O(NlogN), The Best Time: O(N), The Worst Time: O(N^2); Space: O(1) Stability: false 6 | **/ 7 | public int[] sortArray(int[] nums) { 8 | int len = nums.length; 9 | for(int i=len/2-1; i>=0;i--) { 10 | maxHeapDown(nums, i, len-1); 11 | } 12 | for(int i=len-1;i>0;i--) { 13 | swap(nums, 0, i); 14 | maxHeapDown(nums, 0, i-1); 15 | } 16 | return nums; 17 | } 18 | 19 | private void maxHeapDown(int[] nums, int start, int end) { 20 | int c = start; 21 | int l=2*c+1; 22 | int temp = nums[c]; 23 | for(; l<=end; c=l, l=2*l+1) { 24 | if(l= nums[l]) { //如果高层值大于低层,就跳过 28 | break; 29 | } 30 | nums[c] = nums[l]; 31 | nums[l]= temp; // 这里是temp下沉 32 | } 33 | } 34 | 35 | private void swap(int[] nums , int a, int b) { 36 | int temp = nums[a]; 37 | nums[a] = nums[b]; 38 | nums[b] = temp; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /2021-04-12/SortedArrayToBST108.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | 4 | public class SortedArrayToBST108 { 5 | /*Method: In order, Time: O(N), Space:O(N)**/ 6 | /** 7 | 中序遍历,总是选择中间位置左边的数字作为根节点 8 | 选择中间位置左边的数字作为根节点,则根节点的下标为 mid = (left + right) / 2,此处的除法为整数除法。 9 | **/ 10 | public TreeNode sortedArrayToBST(int[] nums) { 11 | return toBST(nums, 0, nums.length - 1); 12 | } 13 | private TreeNode toBST(int[] nums, int left, int right) { 14 | if (left > right) { 15 | return null; 16 | } 17 | // 总是选择中间位置左边的数字作为根节点 18 | int mid = (left + right) / 2; 19 | TreeNode root = new TreeNode(nums[mid]); 20 | root.left = toBST(nums, left, mid - 1); 21 | root.right = toBST(nums, mid + 1, right); 22 | return root; 23 | } 24 | 25 | //Definition for a binary tree node. 26 | public class TreeNode { 27 | int val; 28 | TreeNode left; 29 | TreeNode right; 30 | TreeNode() {} 31 | TreeNode(int val) { this.val = val; } 32 | TreeNode(int val, TreeNode left, TreeNode right) { 33 | this.val = val; 34 | this.left = left; 35 | this.right = right; 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /2021-04-18/MinDistance72.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class MinDistance72 { 4 | /**Method: DP; Time: O(m*n); Space: O(m*n) **/ 5 | /** 6 | dp[i][j] 代表 word1 到 i 位置转换成 word2 到 j 位置需要最少步数 7 | 当 word1[i] == word2[j],dp[i][j] = dp[i-1][j-1]; 8 | 当 word1[i] != word2[j],dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1 9 | 其中,dp[i-1][j-1] 表示替换操作,dp[i-1][j] 表示删除操作,dp[i][j-1] 表示插入操作。 10 | **/ 11 | public int minDistance(String word1, String word2) { 12 | if(word1 == null || word2 == null) { 13 | return 0; 14 | } 15 | int m = word1.length(); 16 | int n = word2.length(); 17 | int[][] dp = new int[m+1][n+1]; 18 | for(int i=0; i<=m; i++) { 19 | dp[i][0] = i; 20 | } 21 | for(int j=0; j<=n;j++) { 22 | dp[0][j] = j; 23 | } 24 | for(int i=1;i<=m; i++) { 25 | for(int j=1; j<=n; j++) { 26 | if(word1.charAt(i-1)==word2.charAt(j-1)){ 27 | dp[i][j] = dp[i-1][j-1]; 28 | }else{ 29 | dp[i][j] = Math.min(dp[i-1][j-1],Math.min(dp[i-1][j],dp[i][j-1]))+1; 30 | } 31 | } 32 | } 33 | return dp[m][n]; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /2021-04-01/FindContinuousSequence57.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class FindContinuousSequence57 { 7 | /*Method: Two Pointers, Time: O(target), Space:O(1)**/ 8 | /** 9 | 初始化: 左边界 i = 1,右边界 j = 2,元素和 s = 3,结果列表 res;循环; 当i≥j 时跳出; 10 | 当 s > target 时: 向右移动左边界 i = i + 1,并更新元素和 s ; 11 | 当 s < target 时: 向右移动右边界 j = j + 1,并更新元素和 s ; 12 | 当 s = target时: 记录连续整数序列,并向右移动左边界 i = i + 1; 13 | 返回值: 返回结果列表 res; 14 | **/ 15 | public int[][] findContinuousSequence(int target) { 16 | int i = 1, j =2, s = 3; // 初始化的值 17 | List res = new ArrayList<>(); 18 | while(i= target 30 | s-=i; // need minus to i firstly, then i++; 31 | i++; 32 | } 33 | } 34 | return res.toArray(new int[res.size()][]); // to array 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /2021-02-20/FindDuplicate287.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.Arrays; 4 | 5 | public class FindDuplicate287 { 6 | 7 | /**Method1: Binary search; Time: O(Nlog(N))); Space: O(1) **/ 8 | public int findDuplicate(int[] nums) { 9 | int n = nums.length; 10 | int start = 0; 11 | int end = n-1; 12 | int res = -1; 13 | while(start <= end) { 14 | int mid = start + (end - start) /2; 15 | int cnt = 0; 16 | for(int i = 0; i= nums[i]) { 18 | cnt ++; 19 | } 20 | } 21 | if(cnt <= mid) { 22 | start = mid + 1; 23 | } else { 24 | end = mid -1; 25 | res = mid; 26 | } 27 | } 28 | return res; 29 | } 30 | 31 | /**Method2: Two pointers; Time: O(N)); Space: O(1) **/ 32 | public int findDuplicate2(int[] nums) { 33 | int slow = 0, fast= 0; 34 | do { 35 | slow = nums[slow]; 36 | fast = nums[nums[fast]]; 37 | 38 | } while(slow != fast); 39 | slow = 0; 40 | while (slow != fast) { 41 | slow = nums[slow]; 42 | fast = nums[fast]; 43 | } 44 | return slow; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /2021-04-12/PathSum437.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | 4 | public class PathSum437 { 5 | /*Method: Iteration, Time: O(NLogN), Space:O(1)**/ 6 | /**路径不一定以root开头,也不一定以leaf结尾,但一定连续 **/ 7 | public int pathSum(TreeNode root, int sum) { 8 | if(root == null) { 9 | return 0; 10 | } 11 | return pathSumStartWithRoot(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum); // 左右子树是pathSum方法,因为可以从左右子树开始,或者是左右子树的子树开始 12 | } 13 | private int pathSumStartWithRoot(TreeNode root, int sum) { 14 | if(root == null) { 15 | return 0; 16 | } 17 | int res = 0; 18 | if(root.val == sum){ 19 | res = 1; 20 | } 21 | res += pathSumStartWithRoot(root.left, sum-root.val) + pathSumStartWithRoot(root.right, sum-root.val); 22 | return res; 23 | } 24 | 25 | //Definition for a binary tree node. 26 | public class TreeNode { 27 | int val; 28 | TreeNode left; 29 | TreeNode right; 30 | TreeNode() {} 31 | TreeNode(int val) { this.val = val; } 32 | TreeNode(int val, TreeNode left, TreeNode right) { 33 | this.val = val; 34 | this.left = left; 35 | this.right = right; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /2021-02-15/SortArrayMergeSort912.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class SortArrayMergeSort912 { 4 | /** Method6: Merge Sort; Average Time: O(NlogN), The Best Time: O(NlogN), The Worst Time: O(NlogN); Space: O(1) Stability: true **/ 5 | public int[] sortArray(int[] nums) { 6 | mergeSort(nums, 0, nums.length-1); 7 | return nums; 8 | } 9 | private void mergeSort(int[] a, int start, int end) { 10 | if(a == null || start >= end) { return; } 11 | int mid = (start + end) /2; 12 | mergeSort(a, start, mid); 13 | mergeSort(a, mid + 1, end); 14 | merge(a, start, mid, end); 15 | } 16 | private void merge(int[] a, int start, int mid, int end) { 17 | int[] temp = new int[end - start + 1]; 18 | int i = start; 19 | int j = mid +1; 20 | int k =0; 21 | while(i <= mid && j <= end) { 22 | if(a[i] <= a[j]) { 23 | temp[k++] = a[i++]; 24 | } else { 25 | temp[k++] = a[j++]; 26 | } 27 | } 28 | while(i<=mid) { temp[k++] = a[i++]; } 29 | while(j <= end) { temp[k++] = a[j++]; } 30 | for(i = 0; i < k; i++) { 31 | a[start + i] = temp[i]; 32 | } 33 | temp=null; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /2021-04-21/NextPermutation31.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class NextPermutation31 { 4 | /**Method: Two scan; Time: O(N), Space: O(1) **/ 5 | /** 6 | 1. 需要将一个左边的「较小数」与一个右边的「较大数」交换,以能够让当前排列变大,从而得到下一个排列。 7 | 2. 同时要让这个「较小数」尽量靠右,而「较大数」尽可能小。 8 | 3. 当交换完成后,「较大数」右边的数需要按照升序重新排列。这样可以在保证新排列大于原来排列的情况下,使变大的幅度尽可能小。 9 | **/ 10 | public void nextPermutation(int[] nums) { 11 | if(nums == null || nums.length ==0) { 12 | return; 13 | } 14 | int len = nums.length; 15 | int i=len-2; // i从len-2开始比较 16 | while(i>=0 && nums[i] >= nums[i+1]) { 17 | i--; 18 | } 19 | if(i>=0) { 20 | int j=len-1; 21 | while(j>=0 && nums[i] >= nums[j]){ 22 | j--; 23 | } 24 | swap(nums, i, j); 25 | } 26 | reverse(nums, i+1, len-1); 27 | } 28 | 29 | public void swap(int[] nums, int i, int j) { 30 | int temp = nums[i]; 31 | nums[i] = nums[j]; 32 | nums[j] = temp; 33 | } 34 | 35 | public void reverse(int[] nums, int start, int end) { 36 | int left = start, right = end; 37 | while (left < right) { 38 | swap(nums, left, right); 39 | left++; 40 | right--; 41 | } 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /2021-03-22/SortArrayMergeSort912.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class SortArrayMergeSort912 { 4 | /** Method6: Merge Sort; Average Time: O(NlogN), The Best Time: O(NlogN), The Worst Time: O(NlogN); Space: O(1) Stability: true **/ 5 | public int[] sortArray(int[] nums) { 6 | mergeSort(nums, 0, nums.length-1); 7 | return nums; 8 | } 9 | 10 | private void mergeSort(int[] nums, int s, int e) { 11 | if(nums==null || s>=e) { 12 | return; 13 | } 14 | int mid = s+ (e-s)/2; //先递归merge子数组,再merge大的数组 15 | mergeSort(nums, s, mid); 16 | mergeSort(nums, mid+1, e); 17 | merge(nums, s, e, mid); 18 | } 19 | 20 | private void merge(int[] nums, int s, int e, int mid) { 21 | int[] temp = new int[e-s+1]; //申请临时数组 22 | int i=s, j=mid+1, k=0; 23 | while(i<=mid && j<=e) { 24 | if(nums[i] <= nums[j]) { 25 | temp[k++] = nums[i++]; 26 | } else { 27 | temp[k++] = nums[j++]; 28 | } 29 | } 30 | while(i<=mid) { 31 | temp[k++] = nums[i++]; 32 | } 33 | while(j<=e) { 34 | temp[k++] = nums[j++]; 35 | } 36 | for (i=0; i< k; i++) { 37 | nums[s+i] = temp[i]; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /2021-05-03/Candy135.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.Arrays; 4 | 5 | public class Candy135 { 6 | /**Method:Greeday; Time:O(N); Space: O(N) **/ 7 | /** 8 | 先从左至右遍历学生成绩 ratings,按照以下规则给糖,并记录在 left 中: 9 | 先给所有学生 1 颗糖; 10 | 若 ratings[i] > ratings[i-1],则第 ii 名学生糖比第 i - 1i−1 名学生多 11 个。 11 | 若 ratings[i] >= ratings[i-1],则第 ii 名学生糖数量不变。(交由从右向左遍历时处理。) 12 | 经过此规则分配后,可以保证所有学生糖数量 满足左规则 。 13 | 同理,在此规则下从右至左遍历学生成绩并记录在 right 中,可以保证所有学生糖数量 满足右规则 。 14 | 最终,取以上 2 轮遍历 left 和 right 对应学生糖果数的 最大值 ,这样则 同时满足左规则和右规则 ,即得到每个同学的最少糖果数量。 15 | **/ 16 | public int candy(int[] ratings) { 17 | int len = ratings.length; 18 | int[] left = new int[len]; 19 | int[] right = new int[len]; 20 | Arrays.fill(left, 1); 21 | Arrays.fill(right, 1); 22 | for(int i=1; i ratings[i-1]) { 24 | left[i] = left[i-1] +1; 25 | } 26 | } 27 | 28 | int count = left[len-1]; //最后一个位置能确定。 29 | for(int i=len-2; i>=0; i--){ 30 | if(ratings[i] > ratings[i+1]) { 31 | right[i] = right[i+1]+1; 32 | } 33 | count += Math.max(left[i], right[i]); 34 | } 35 | return count; 36 | } 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /2021-03-07/CombinationSum40.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.Collections; 6 | import java.util.List; 7 | 8 | public class CombinationSum40 { 9 | 10 | /*Method: BackTrack, Time: O(N*2^N), Space:O(Target)**/ 11 | List> res = new ArrayList<>(); 12 | List list = new ArrayList<>(); 13 | 14 | public List> combinationSum2(int[] candidates, int target) { 15 | if(candidates == null || candidates.length ==0 || target == 0) { 16 | return res; 17 | } 18 | Arrays.sort(candidates); 19 | backtrack(candidates, 0, target); 20 | return res; 21 | } 22 | 23 | private void backtrack(int[] candidates, int begin, int target) { 24 | if(target == 0) { 25 | res.add(new ArrayList(list)); 26 | return; 27 | } 28 | for(int i=begin; i< candidates.length && target - candidates[i] >= 0; i++) { 29 | if(i> begin && candidates[i] == candidates[i-1]) { 30 | continue; 31 | } 32 | list.add(candidates[i]); 33 | backtrack(candidates, i+1, target - candidates[i]); 34 | list.remove(list.size() - 1); 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /2021-05-17/EvalRPN150.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.Deque; 4 | import java.util.LinkedList; 5 | 6 | public class EvalRPN150 { 7 | /*Method: Stack, Time: O(N), Space:O(N)**/ 8 | public int evalRPN(String[] tokens) { 9 | Deque stack = new LinkedList(); 10 | int n=tokens.length; 11 | for(int i=0; i employeeFreeTime(List> schedule) { 11 | int open =0, close =1; 12 | List events = new ArrayList<>(); 13 | for(List e: schedule) { 14 | for(Interval i: e) { 15 | events.add(new int[]{i.start, open}); 16 | events.add(new int[]{i.end, close}); 17 | } 18 | } 19 | Collections.sort(events, (a,b) -> a[0] == b[0] ? a[1] -b[1] : a[0] -b[0]); 20 | List ans = new ArrayList<>(); 21 | 22 | int pre = -1, bal=0; 23 | for(int[] event : events) { 24 | if(bal ==0 && pre >0) { 25 | ans.add(new Interval(pre, event[0])); 26 | } 27 | bal += event[1] ==open?1:-1; 28 | pre = event[0]; 29 | } 30 | 31 | return ans; 32 | } 33 | 34 | class Interval { 35 | public int start; 36 | public int end; 37 | 38 | public Interval() {} 39 | 40 | public Interval(int _start, int _end) { 41 | start = _start; 42 | end = _end; 43 | } 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /2021-02-27/CopyRandomList138.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class CopyRandomList138 { 4 | 5 | /*Method : Two pointers, Time: O(N), Space:O(1)**/ 6 | public Node copyRandomList(Node head) { 7 | if(head == null) { 8 | return null; 9 | } 10 | Node cur = head; 11 | 12 | while(cur != null) { 13 | Node copyNode = new Node(cur.val); 14 | copyNode.next = cur.next; 15 | cur.next = copyNode; 16 | cur = copyNode.next; 17 | } 18 | cur = head; 19 | while(cur != null) { 20 | cur.next.random = cur.random == null? null : cur.random.next; 21 | cur = cur.next.next; 22 | } 23 | 24 | Node newHead = head.next; 25 | 26 | Node newCur = newHead; 27 | Node oldCur = head; 28 | while(oldCur != null) { 29 | oldCur.next = oldCur.next.next; 30 | newCur.next = newCur.next == null ? null : newCur.next.next; 31 | oldCur = oldCur.next; 32 | newCur = newCur.next; 33 | } 34 | return newHead; 35 | } 36 | 37 | // Definition for a Node. 38 | class Node { 39 | int val; 40 | Node next; 41 | Node random; 42 | 43 | public Node(int val) { 44 | this.val = val; 45 | this.next = null; 46 | this.random = null; 47 | } 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /2021-04-11/TreeToDoublyList36.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class TreeToDoublyList36 { 4 | /*Method: DFS, Time: O(N), Space:O(N)**/ 5 | /** 6 | 思路:构建链表: 7 | 当 pre 为空时: 代表正在访问链表头节点,记为 head ; 8 | 当 pre 不为空时: 修改双向节点引用,即 pre.right = cur ,cur.left = pre ; 9 | 保存 cur : 更新 pre = cur ,即节点 cur 是后继节点的 pre ; 10 | 递归右子树,即 dfs(cur.right) ; 11 | **/ 12 | Node pre, head; 13 | public Node treeToDoublyList(Node root) { 14 | if(root == null) { 15 | return null; 16 | } 17 | dfs(root); 18 | head.left = pre; 19 | pre.right = head; 20 | return head; 21 | } 22 | void dfs(Node cur) { 23 | if(cur == null) { 24 | return; 25 | } 26 | dfs(cur.left); 27 | if(pre != null) { 28 | pre.right = cur; 29 | } else { 30 | head = cur; 31 | } 32 | cur.left = pre; 33 | pre = cur; 34 | dfs(cur.right); 35 | } 36 | 37 | // Definition for a Node. 38 | class Node { 39 | public int val; 40 | public Node left; 41 | public Node right; 42 | 43 | public Node() {} 44 | 45 | public Node(int _val) { 46 | val = _val; 47 | } 48 | 49 | public Node(int _val,Node _left,Node _right) { 50 | val = _val; 51 | left = _left; 52 | right = _right; 53 | } 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /2021-02-14/SortArrayBubbleSort912.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class SortArrayBubbleSort912 { 4 | 5 | /** 6 | * Method3: Bubble Sort - V1; Average Time: O(NlogN), The Best Time: O(N), The Worst Time: O(N^2); Space: O(1) Stability: true 7 | **/ 8 | public int[] sortArray(int[] nums) { 9 | bubbleSort(nums, nums.length); 10 | return nums; 11 | } 12 | private void bubbleSort(int[] a, int n) { 13 | for (int i = n -1; i>0; i--) { 14 | for (int j = 0; j < i; j++) { 15 | if (a[j] > a[j + 1]) { 16 | int tmp = a[j]; 17 | a[j] = a[j + 1]; 18 | a[j + 1] = tmp; 19 | } 20 | } 21 | } 22 | } 23 | 24 | /** 25 | * Method3: Bubble Sort - V2; Average Time: O(NlogN), The Best Time: O(N), The Worst Time: O(N^2); Space: O(1) Stability: true 26 | **/ 27 | private void bubbleSort2(int[] a, int n) { 28 | boolean flag = false; 29 | for (int i = n -1; i>0; i--) { 30 | flag = false; 31 | for (int j = 0; j < i; j++) { 32 | if (a[j] > a[j + 1]) { 33 | int tmp = a[j]; 34 | a[j] = a[j + 1]; 35 | a[j + 1] = tmp; 36 | flag = true; 37 | } 38 | } 39 | if(!flag) { 40 | break; 41 | } 42 | } 43 | } 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /2021-03-21/SortArrayBubbleSort912.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class SortArrayBubbleSort912 { 4 | 5 | /** 6 | * Method3: Bubble Sort - V1; Average Time: O(NlogN), The Best Time: O(N), The Worst Time: O(N^2); Space: O(1) Stability: true 7 | **/ 8 | public int[] sortArray(int[] nums) { 9 | int len = nums.length; 10 | for(int i =len-1;i>=0;i--) { 11 | for(int j=0; j nums[j+1]) { 13 | swap(nums, j, j+1); 14 | } 15 | } 16 | } 17 | return nums; 18 | } 19 | 20 | private void swap(int[] nums , int a, int b) { 21 | int temp = nums[a]; 22 | nums[a] = nums[b]; 23 | nums[b] = temp; 24 | } 25 | 26 | /** 27 | * Method3: Bubble Sort - V2; Average Time: O(NlogN), The Best Time: O(N), The Worst Time: O(N^2); Space: O(1) Stability: true 28 | **/ 29 | public int[] sortArray2(int[] nums) { 30 | int len = nums.length; 31 | boolean flag = false; 32 | for(int i =len-1;i>=0;i--) { 33 | flag = false; 34 | for(int j=0; j nums[j+1]) { 36 | swap(nums, j, j+1); 37 | flag = true; 38 | } 39 | } 40 | if(!flag) { 41 | break; 42 | } 43 | } 44 | return nums; 45 | } 46 | 47 | 48 | } 49 | -------------------------------------------------------------------------------- /2021-04-04/isNumberNewCode20.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class isNumberNewCode20 { 4 | /**Time: O(N), Space: O(1) **/ 5 | /** 6 | 思路: 7 | 1. 去空格 8 | 2. 数字处理 9 | 3. '.'之前不能有E/e 10 | 4. '+'/'-' 只能出现在首位或者E/e后面 11 | 5. 当前为E/e,之前没出现过,并且 之前要有数字 &&&& //防止e结尾 -》 numFlag= false 12 | **/ 13 | public boolean isNumber(String s) { 14 | if(s == null || s.length() ==0) { 15 | return false; 16 | } 17 | s = s.trim(); //1. 去空格 18 | boolean numFlag = false; 19 | boolean dotFlag = false; 20 | boolean eFlag = false; 21 | for(int i =0; i= '0' && s.charAt(i) <= '9') { // 2.比较数字 23 | numFlag = true; 24 | } else if(s.charAt(i) == '.' && !dotFlag && !eFlag) { // 3. '.'之前不能有E/e 25 | dotFlag = true; 26 | } else if(s.charAt(i) == '+' || s.charAt(i) == '-') { // 4. '+'/'-' 只能出现在首位或者E/e后面 27 | if(i!=0 && (s.charAt(i-1) != 'e' &&s.charAt(i-1) != 'E')) { 28 | return false; 29 | } 30 | } else if((s.charAt(i) == 'e' || s.charAt(i) == 'E') && numFlag&& !eFlag) { // 5. 当前为E/e,之前没出现过,并且 之前要有数字 31 | eFlag = true; 32 | numFlag= false; //防止e结尾 33 | } else { 34 | return false; 35 | } 36 | } 37 | return numFlag; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /2021-02-04/Rand470.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import Leetcode.SolBase; 4 | 5 | public class Rand470 extends SolBase { 6 | 7 | /**Method1: Rejection Sampling; Time:O(1) - O(∞); Space:O(1) **/ 8 | public int rand10_1() { 9 | int row, col, res; 10 | do { 11 | row = rand7(); 12 | col = rand7(); 13 | res = (row -1) * 7 + col; 14 | } while(res > 40); 15 | return (res -1) % 10 + 1; 16 | } 17 | 18 | /**Method2: Rejection Sampling By Use Rejection Sampling; Time:O(1) - O(∞); Space:O(1) **/ 19 | public int rand10_2() { 20 | int row, col, res; 21 | while(true) { 22 | row = rand7(); 23 | col = rand7(); 24 | res = (row -1) * 7 + col; 25 | if (res <= 40) { 26 | return (res -1) % 10 + 1; 27 | } 28 | 29 | row = res - 40; 30 | col = rand7(); 31 | // get uniform dist from 1 - 63 32 | res = (row - 1) * 7 + col; 33 | if (res <= 60) { 34 | return (res -1) % 10 + 1; 35 | } 36 | 37 | row = res - 60; 38 | col = rand7(); 39 | // get uniform dist from 1 - 21 40 | res = (row - 1) * 7 + col; 41 | if (res <= 20) { 42 | return (res -1) % 10 + 1; 43 | } 44 | } 45 | } 46 | } 47 | 48 | class SolBase { 49 | int rand7() { 50 | return 0; //TODO 51 | }; 52 | } 53 | -------------------------------------------------------------------------------- /2021-03-27/MergeTwoLists21.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | 4 | public class MergeTwoLists21 { 5 | /** Method 1:Recursion, Time: O(N+M), Space:O(N+M)**/ 6 | public ListNode mergeTwoLists(ListNode l1, ListNode l2) { 7 | if(l1 == null) { 8 | return l2; 9 | } else if(l2 == null) { 10 | return l1; 11 | } else if(l1.val < l2.val) { 12 | l1.next = mergeTwoLists(l1.next, l2); 13 | return l1; 14 | } else { 15 | l2.next = mergeTwoLists(l1, l2.next); 16 | return l2; 17 | } 18 | } 19 | 20 | /** Method 2:Iteration + Dummy Node, Time: O(N+M), Space:O(N+M)**/ 21 | public ListNode mergeTwoLists2(ListNode l1, ListNode l2) { 22 | ListNode dummy = new ListNode(-1); 23 | ListNode pre = dummy; 24 | while(l1 != null && l2 != null) { 25 | if(l1.val < l2.val) { 26 | pre.next = l1; 27 | l1 = l1.next; 28 | } else { 29 | pre.next = l2; 30 | l2 = l2.next; 31 | } 32 | pre = pre.next; 33 | } 34 | pre.next = l1 == null? l2: l1; 35 | return dummy.next; 36 | } 37 | 38 | public class ListNode { 39 | int val; 40 | ListNode next; 41 | ListNode() {} 42 | ListNode(int val) { this.val = val; } 43 | ListNode(int val, ListNode next) { this.val = val; this.next = next; } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /2021-04-17/ContainsNearbyAlmostDuplicate220.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class ContainsNearbyAlmostDuplicate220 { 7 | /** Method: Bucket Sort, Time: O(N); Space: O(min(N,K))**/ 8 | /** 9 | 思想: 按照元素的大小进行分桶,维护一个滑动窗口内的元素对应的元素。 10 | 对于元素 xx,其影响的区间为 [x - t, x + t]。于是我们可以设定桶的大小为 t + 1。 11 | 如果两个元素同属一个桶,那么这两个元素必然符合条件。 12 | **/ 13 | public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) { 14 | int len = nums.length; 15 | Map map = new HashMap(); 16 | long w = (long) t + 1; 17 | for (int i = 0; i < len; i++) { 18 | long id = getID(nums[i], w); 19 | if (map.containsKey(id)) { 20 | return true; 21 | } 22 | if (map.containsKey(id - 1) && Math.abs(nums[i] - map.get(id - 1)) < w) { 23 | return true; 24 | } 25 | if (map.containsKey(id + 1) && Math.abs(nums[i] - map.get(id + 1)) < w) { 26 | return true; 27 | } 28 | map.put(id, (long) nums[i]); 29 | if (i >= k) { 30 | map.remove(getID(nums[i - k], w)); 31 | } 32 | } 33 | return false; 34 | } 35 | 36 | public long getID(long x, long w) { 37 | if (x >= 0) { 38 | return x / w; 39 | } 40 | return (x + 1) / w - 1; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /2021-05-05/Exist12.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class Exist12 { 4 | /**Method: DFS; Time:O(MN * 3^K); Space: O(K) **/ 5 | /** 6 | 深度优先搜索(DFS)+ 剪枝 7 | 标记当前矩阵元素: 将 board[i][j] 修改为 空字符 '' ,代表此元素已访问过,防止之后搜索时重复访问。 8 | 搜索下一单元格: 朝当前元素的 上、下、左、右 四个方向开启下层递归,使用 或 连接 (代表只需找到一条可行路径就直接返回,不再做后续 DFS ),并记录结果至 res 。 9 | 还原当前矩阵元素: 将 board[i][j] 元素还原至初始值,即 word[k] 。 10 | **/ 11 | public boolean exist(char[][] board, String word) { 12 | char[] words = word.toCharArray(); 13 | for(int i=0; i=board.length || j<0 || j >= board[0].length || board[i][j] != word[index] ) { 25 | return false; 26 | } 27 | if(index == word.length -1) { 28 | return true; 29 | } 30 | board[i][j] = '\0'; //board[i][j] = '0/' 来防止 ”走回头路“ 31 | boolean res = dfs(board, word, i+1, j, index+1) || dfs(board, word, i-1, j, index+1) || 32 | dfs(board, word, i, j+1, index+1) || dfs(board, word, i, j-1, index+1); 33 | board[i][j] = word[index]; 34 | return res; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /2021-03-10/AddTwoNumbers445.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | 4 | import java.util.Stack; 5 | 6 | public class AddTwoNumbers445 { 7 | /**Method: Stack + Big Data Sum; Time:O(N); Space: O(1) **/ 8 | public ListNode addTwoNumbers(ListNode l1, ListNode l2) { 9 | Stack stack1 = buildStack(l1); 10 | Stack stack2 = buildStack(l2); 11 | int carry = 0; 12 | ListNode head = new ListNode(-1); 13 | while(!stack1.isEmpty() || ! stack2.isEmpty() || carry != 0 ) { 14 | int x = stack1.isEmpty() ? 0 : stack1.pop(); 15 | int y = stack2.isEmpty() ? 0 : stack2.pop(); 16 | int sum = x+y+carry; 17 | ListNode cur = new ListNode(sum % 10); 18 | cur.next = head.next; 19 | head.next = cur; 20 | carry = sum / 10; 21 | } 22 | return head.next; 23 | } 24 | 25 | private Stack buildStack(ListNode node){ 26 | Stack stack = new Stack<>(); 27 | while(node != null) { 28 | stack.push(node.val); 29 | node =node.next; 30 | } 31 | return stack; 32 | } 33 | 34 | //Definition for singly-linked list. 35 | public class ListNode { 36 | int val; 37 | ListNode next; 38 | ListNode() {} 39 | ListNode(int val) { this.val = val; } 40 | ListNode(int val, ListNode next) { this.val = val; this.next = next; } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /2021-03-03/SpiralOrder54.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class SpiralOrder54 { 7 | 8 | /* Method: Traversal by layer , Time: O(M*N), Space:O(1)**/ 9 | public List spiralOrder(int[][] matrix) { 10 | List res = new ArrayList<>(); 11 | if(matrix.length == 0 || matrix[0].length == 0) { 12 | return res; 13 | } 14 | int left = 0; 15 | int right = matrix[0].length - 1; 16 | int up = 0; 17 | int down = matrix.length - 1; 18 | while(true) { 19 | for(int col = left; col <= right; col ++) { 20 | res.add(matrix[up][col]); 21 | } 22 | up++; 23 | if(up>down) { 24 | break; 25 | } 26 | for(int row = up; row <= down; row ++) { 27 | res.add(matrix[row][right]); 28 | } 29 | right--; 30 | if(right= left; col -- ) { 34 | res.add(matrix[down][col]); 35 | } 36 | down--; 37 | if(down < up) { 38 | break; 39 | } 40 | for(int row = down; row >= up; row --) { 41 | res.add(matrix[row][left]); 42 | } 43 | left++; 44 | if(left>right) { 45 | break; 46 | } 47 | } 48 | return res; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /2021-04-25/LargestBSTSubtree333.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | 4 | public class LargestBSTSubtree333 { 5 | 6 | /**Method: InOrder; Time: O(N); Space: O(H) **/ 7 | /** 8 | 根据二叉搜索树的性质我们分左右两个子树递归下去,即对于左子树,检查 valid(root−>left,l,root−>val) 9 | 因为左子树里所有节点的值均小于它的根节点的值,所以我们要把范围从 (l,r) 改为 (l,root−>val) 10 | 同理对于右子树我们递归检查 valid(root->right,root->val,r)即可, 11 | **/ 12 | public int largestBSTSubtree(TreeNode root) { 13 | if(root == null ){ 14 | return 0; 15 | } 16 | if(valid(root, Integer.MIN_VALUE, Integer.MAX_VALUE)) { 17 | return cnt(root); 18 | } 19 | return Math.max(largestBSTSubtree(root.left), largestBSTSubtree(root.right)); 20 | } 21 | 22 | private int cnt(TreeNode root){ 23 | return root != null? cnt(root.left) + cnt(root.right) + 1: 0; 24 | } 25 | 26 | private boolean valid(TreeNode root,int l, int r) { 27 | if(root == null) { 28 | return true; 29 | } 30 | if(root.val <= l || root.val >= r) { 31 | return false; 32 | } 33 | return valid(root.left, l, root.val) && valid(root.right, root.val, r); 34 | } 35 | 36 | /** 37 | * Definition for a binary tree node. 38 | */ 39 | public class TreeNode { 40 | 41 | int val; 42 | TreeNode left; 43 | TreeNode right; 44 | 45 | TreeNode(int x) { 46 | val = x; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /2021-03-19/SpiralOrder29.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class SpiralOrder29 { 4 | /* Method: Traversal by layer , Time: O(M*N), Space:O(1)**/ 5 | public int[] spiralOrder(int[][] matrix) { 6 | if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { 7 | return new int[0]; 8 | } 9 | 10 | int[] res = new int[matrix[0].length * matrix.length ]; 11 | int left = 0; 12 | int right = matrix[0].length - 1; 13 | int up = 0; 14 | int down = matrix.length - 1; 15 | int index = 0; 16 | while(true) { 17 | for(int col = left; col <= right; col ++) { 18 | res[index++] =matrix[up][col]; 19 | } 20 | up++; 21 | if(up>down) { 22 | break; 23 | } 24 | for(int row = up; row <= down; row ++) { 25 | res[index++] =matrix[row][right]; 26 | } 27 | right--; 28 | if(right= left; col -- ) { 32 | res[index++] = matrix[down][col]; 33 | } 34 | down--; 35 | if(down < up) { 36 | break; 37 | } 38 | for(int row = down; row >= up; row --) { 39 | res[index++] = matrix[row][left]; 40 | } 41 | left++; 42 | if(left>right) { 43 | break; 44 | } 45 | } 46 | return res; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /2021-04-13/SortedListToBST109.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | 4 | import Leetcode.RemoveNthFromEnd19.ListNode; 5 | 6 | public class SortedListToBST109 { 7 | /*Method : Divide and conquer, Time: O(NLogN), Space:O(LogN)**/ 8 | /** 9 | 1. 用快慢指针找出中间节点的前一个节点, 10 | 2. 再以中间节点为界,分开处理 11 | **/ 12 | public TreeNode sortedListToBST(ListNode head) { 13 | if(head == null){ 14 | return null; 15 | } 16 | if(head.next == null) { 17 | return new TreeNode(head.val); 18 | } 19 | ListNode preMid = getPreMid(head); 20 | TreeNode root = new TreeNode(head.val); 21 | root.left = sortedListToBST(preMid); 22 | root.right = sortedListToBST(preMid.next); 23 | return root; 24 | } 25 | 26 | private ListNode getPreMid(ListNode node) { 27 | ListNode slow = node; 28 | ListNode fast = node.next;//找mid的pre 29 | while(fast != null && fast.next != null) { 30 | slow = slow.next; 31 | fast = fast.next.next; 32 | } 33 | return slow; 34 | } 35 | 36 | //Definition for a binary tree node. 37 | public class TreeNode { 38 | int val; 39 | TreeNode left; 40 | TreeNode right; 41 | TreeNode() {} 42 | TreeNode(int val) { this.val = val; } 43 | TreeNode(int val, TreeNode left, TreeNode right) { 44 | this.val = val; 45 | this.left = left; 46 | this.right = right; 47 | } 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /2021-02-24/MergeTwoLists21.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | 4 | public class MergeTwoLists21 { 5 | /** Method 1:Recursion, Time: O(N+M), Space:O(N+M)**/ 6 | public ListNode mergeTwoLists(ListNode l1, ListNode l2) { 7 | if(l1 == null) { 8 | return l2; 9 | } else if(l2 == null) { 10 | return l1; 11 | } else if(l1.val < l2.val) { 12 | l1.next = mergeTwoLists(l1.next, l2); 13 | return l1; 14 | } else { 15 | l2.next = mergeTwoLists(l1, l2.next); 16 | return l2; 17 | } 18 | } 19 | 20 | /** Method 2:Iteration + Dummy Node, Time: O(N+M), Space:O(N+M)**/ 21 | public ListNode mergeTwoLists2(ListNode l1, ListNode l2) { 22 | ListNode dummy = new ListNode(0); 23 | ListNode pre = dummy; 24 | ListNode cur1 = l1; 25 | ListNode cur2 = l2; 26 | while (cur1 != null && cur2 != null) { 27 | if(cur1.val < cur2.val) { 28 | pre.next = cur1; 29 | cur1 = cur1.next; 30 | } else { 31 | pre.next = cur2; 32 | cur2 = cur2.next; 33 | } 34 | pre = pre.next; 35 | } 36 | pre.next = cur1 == null ? cur2 : cur1; 37 | return dummy.next; 38 | } 39 | 40 | public class ListNode { 41 | int val; 42 | ListNode next; 43 | ListNode() {} 44 | ListNode(int val) { this.val = val; } 45 | ListNode(int val, ListNode next) { this.val = val; this.next = next; } 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /2021-04-03/ReorderList143.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import Leetcode.RemoveNthFromEnd19.ListNode; 4 | 5 | public class ReorderList143 { 6 | 7 | /**Method: reverse mid, then mergep; Time: O(N); Space:O(1)**/ 8 | public void reorderList(ListNode head) { 9 | if(head == null) { 10 | return; 11 | } 12 | ListNode mid = getMid(head); // 1. 获取mid 13 | ListNode l1 = head; 14 | ListNode l2 = mid.next; 15 | mid.next= null; 16 | 17 | l2 = reverseList(l2); // 2. reverse l2 18 | merge(l1, l2); //3. merge l1 & l2 (不是大小合并,而是逐个合并两个链表) 19 | } 20 | 21 | private void merge(ListNode l1, ListNode l2){ 22 | ListNode t1; 23 | ListNode t2; 24 | while(l1 != null & l2!=null) { 25 | t1 = l1.next; 26 | t2 = l2.next; 27 | 28 | l1.next =l2; 29 | l1 = t1; 30 | 31 | l2.next = l1; 32 | l2 = t2; 33 | } 34 | } 35 | 36 | private ListNode getMid(ListNode head) { 37 | ListNode s = head, f = head; 38 | while(f.next != null && f.next.next != null) { 39 | s = s.next; 40 | f = f.next.next; 41 | } 42 | return s; 43 | } 44 | 45 | private ListNode reverseList(ListNode head) { 46 | ListNode pre = null; 47 | ListNode cur = head; 48 | while(cur != null) { 49 | ListNode np = cur.next; 50 | cur.next = pre; 51 | pre = cur; 52 | cur = np; 53 | } 54 | return pre; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /2021-05-12/BackspaceCompare844.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class BackspaceCompare844 { 4 | /*Method:Two Pointer, Time: O(M+N), Space:O(1)**/ 5 | /** 6 | 一个字符是否会被删掉,只取决于该字符后面的退格符,而与该字符前面的退格符无关。因此当我们逆序地遍历字符串,就可以立即确定当前字符是否会被删掉。 7 | 我们定义 Skip 表示当前待删除的字符的数量。每次我们遍历到一个字符: 8 | 若该字符为退格符,则我们需要多删除一个普通字符,我们让 kip 加 1; 9 | 若该字符为普通字符: 10 | 若 skip 为 0,则说明当前字符不需要删去; 11 | 若 skip 不为 0,则说明当前字符需要删去,我们让 skip 减 1。 12 | **/ 13 | public boolean backspaceCompare(String s, String t) { 14 | int i=s.length()-1, j=t.length()-1; 15 | int skipS = 0, skipT =0; 16 | while(i >= 0 || j >= 0) { 17 | while(i >= 0) { 18 | if (s.charAt(i) == '#') { 19 | skipS++; 20 | i--; 21 | } else if (skipS > 0) { 22 | skipS--; 23 | i--; 24 | } else { 25 | break; 26 | } 27 | } 28 | while (j >= 0) { 29 | if (t.charAt(j) == '#') { 30 | skipT++; 31 | j--; 32 | } else if (skipT > 0) { 33 | skipT--; 34 | j--; 35 | } else { 36 | break; 37 | } 38 | } 39 | if (i >= 0 && j >= 0) { 40 | if (s.charAt(i) != t.charAt(j)) { 41 | return false; 42 | } 43 | } else { 44 | if (i >= 0 || j >= 0) { 45 | return false; 46 | } 47 | } 48 | i--; 49 | j--; 50 | } 51 | return true; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /2021-03-06/ThreeSum54.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | 6 | public class ThreeSum54 { 7 | /*Method: Two pointers, Time: O(NLogN), Space:O(1)**/ 8 | public ArrayList> threeSum(int[] num) { 9 | ArrayList> res = new ArrayList<>(); 10 | if (num == null || num.length < 3) { 11 | return res; 12 | } 13 | Arrays.sort(num); 14 | for (int i = 0; i < num.length - 2; i++) { 15 | if (num[i] > 0) { 16 | break; 17 | } 18 | if (i > 0 && num[i] == num[i - 1]) { 19 | continue; 20 | } 21 | int left = i + 1; 22 | int right = num.length - 1; 23 | while (left < right) { 24 | int sum = num[i] + num[right] + num[left]; 25 | if (sum == 0) { 26 | ArrayList list = new ArrayList<>(); 27 | list.add(num[i]); 28 | list.add(num[left]); 29 | list.add(num[right]); 30 | res.add(list); 31 | while (left < right && num[left] == num[left + 1]) { 32 | left++; 33 | } 34 | while (left < right && num[right] == num[right - 1]) { 35 | right--; 36 | } 37 | left++; 38 | right--; 39 | } else if (sum > 0) { 40 | right--; 41 | } else { 42 | left++; 43 | } 44 | } 45 | } 46 | return res; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /2021-05-13/Partition131.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Partition131 { 7 | /*Method:DFS + Back Tracing, Time: O(N * 2^N), Space:O(N^2)**/ 8 | /** 9 | 假设我们当前搜索到字符串的第 i 个字符,且 [0..i−1] 位置的所有字符已经被分割成若干个回文串,并且分割结果被放入了答案数组 ans 中,那么我们就需要枚举下一个回文串的右边界 j,使得 s[i..j] 是一个回文串。 10 | **/ 11 | int[][] dp; 12 | List> res = new ArrayList>(); 13 | List list = new ArrayList(); 14 | int n; 15 | public List> partition(String s) { 16 | n = s.length(); 17 | dp = new int[n][n]; 18 | 19 | dfs(s, 0); 20 | return res; 21 | } 22 | 23 | public void dfs(String s, int i) { 24 | if (i == n) { 25 | res.add(new ArrayList(list)); 26 | return; 27 | } 28 | for (int j = i; j < n; ++j) { 29 | if (isPalindrome(s, i, j) == 1) { 30 | list.add(s.substring(i, j + 1)); 31 | dfs(s, j + 1); 32 | list.remove(list.size() - 1); 33 | } 34 | } 35 | } 36 | // 记忆化搜索中,f[i][j] = 0 表示未搜索,1 表示是回文串,-1 表示不是回文串 37 | public int isPalindrome(String s, int i, int j) { 38 | if (dp[i][j] != 0) { 39 | return dp[i][j]; 40 | } 41 | if (i >= j) { 42 | dp[i][j] = 1; 43 | } else if (s.charAt(i) == s.charAt(j)) { 44 | dp[i][j] = isPalindrome(s, i + 1, j - 1); 45 | } else { 46 | dp[i][j] = -1; 47 | } 48 | return dp[i][j]; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /2021-03-25/GenerateTreesBst95.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | 7 | public class GenerateTreesBst95 { 8 | /**Method: Recursive; Time:O(nG(n)); Space: O(nG(n)), G(n) is Catalan number **/ 9 | public List generateTrees(int n) { 10 | if(n == 0) { 11 | return new LinkedList<>(); 12 | } 13 | return createTrees(1, n); 14 | } 15 | private List createTrees(int start, int end) { 16 | List tree = new LinkedList<>(); 17 | if(start>end) { 18 | tree.add(null); 19 | return tree; 20 | } 21 | for(int i = start; i<= end; i++) { // 以i分开,分为左右 22 | List leftTrees = createTrees(start, i-1); 23 | List rightTrees = createTrees(i+1, end); 24 | for(TreeNode l : leftTrees) { 25 | for(TreeNode r: rightTrees) { 26 | TreeNode node = new TreeNode(i); 27 | node.left = l; 28 | node.right = r; 29 | tree.add(node); 30 | } 31 | } 32 | } 33 | return tree; 34 | } 35 | 36 | //Definition for a binary tree node. 37 | public class TreeNode { 38 | int val; 39 | TreeNode left; 40 | TreeNode right; 41 | TreeNode() {} 42 | TreeNode(int val) { this.val = val; } 43 | TreeNode(int val, TreeNode left, TreeNode right) { 44 | this.val = val; 45 | this.left = left; 46 | this.right = right; 47 | } 48 | } 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /2021-02-22/GenerateTreesBst95.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | 7 | public class GenerateTreesBst95 { 8 | /**Method: Recursive; Time:O(nG(n)); Space: O(nG(n)), G(n) is Catalan number **/ 9 | public List generateTrees(int n) { 10 | if(n == 0) { 11 | return new LinkedList<>(); 12 | } 13 | return createTrees(1, n); 14 | } 15 | private List createTrees(int start, int end) { 16 | List trees = new LinkedList<>(); 17 | if(start > end) { 18 | trees.add(null); 19 | return trees; 20 | } 21 | for(int i = start; i<= end; i++) { 22 | List leftTrees = createTrees(start, i-1); 23 | List rightTrees = createTrees(i+1, end); 24 | for(TreeNode left: leftTrees) { 25 | for(TreeNode right: rightTrees) { 26 | TreeNode node = new TreeNode(i); 27 | node.left = left; 28 | node.right = right; 29 | trees.add(node); 30 | } 31 | } 32 | } 33 | return trees; 34 | } 35 | 36 | //Definition for a binary tree node. 37 | public class TreeNode { 38 | int val; 39 | TreeNode left; 40 | TreeNode right; 41 | TreeNode() {} 42 | TreeNode(int val) { this.val = val; } 43 | TreeNode(int val, TreeNode left, TreeNode right) { 44 | this.val = val; 45 | this.left = left; 46 | this.right = right; 47 | } 48 | } 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /2021-04-13/GenerateTreesBst95.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | 4 | import java.util.ArrayList; 5 | import java.util.LinkedList; 6 | import java.util.List; 7 | 8 | public class GenerateTreesBst95 { 9 | /**Method: Recursive; Time:O(nG(n)); Space: O(nG(n)), G(n) is Catalan number **/ 10 | public List generateTrees(int n) { 11 | if(n==0) { 12 | return new ArrayList(); 13 | } 14 | return generateTrees(1, n); 15 | } 16 | private List generateTrees(int s, int e) { 17 | List tree = new ArrayList<>(); 18 | if(s>e) { 19 | tree.add(null);//这里为空,加入node 链表 20 | return tree; 21 | } 22 | for(int i=s;i<=e;i++) { 23 | List left = generateTrees(s, i-1); // 分为左右子树的数组 24 | List right = generateTrees(i+1, e); 25 | for(TreeNode l: left) { 26 | for(TreeNode r: right) { 27 | TreeNode node = new TreeNode(i); 28 | node.left = l; 29 | node.right = r; 30 | tree.add(node); 31 | } 32 | } 33 | } 34 | return tree; 35 | } 36 | 37 | //Definition for a binary tree node. 38 | public class TreeNode { 39 | int val; 40 | TreeNode left; 41 | TreeNode right; 42 | TreeNode() {} 43 | TreeNode(int val) { this.val = val; } 44 | TreeNode(int val, TreeNode left, TreeNode right) { 45 | this.val = val; 46 | this.left = left; 47 | this.right = right; 48 | } 49 | } 50 | 51 | 52 | } 53 | -------------------------------------------------------------------------------- /2021-05-01/IsMatch10Re.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class IsMatch10Re { 4 | /**Method:DP; Time: O(MN); Space:O(MN) **/ 5 | /** 6 | 用 f[i][j] 表示 s 的前 i 个字符与 p 中的前 j 个字符是否能够匹配 7 | 1. 如果p[j]是一个小写字母; 如果 s[i]与 p[j]不相同,那么无法进行匹配;否则我们可以匹配两个字符串的最后一个字符,完整的匹配结果取决于两个字符串前面的部分。 8 | 2. 如果p[j]是 *,那么就表示我们可以对 p 的第 j-1 个字符匹配任意自然数次。 9 | 3. 在任意情况下,只要 p[j] 是 .,那么 p[j] 一定成功匹配 s 中的任意一个小写字母。 10 | **/ 11 | public boolean isMatch(String s, String p) { 12 | int m = s.length(); 13 | int n= p.length(); 14 | 15 | boolean[][] dp = new boolean[m+1][n+1]; 16 | dp[0][0] = true; 17 | 18 | for(int i=0; i<= m; i++) { 19 | for(int j=1; j<=n; j++) { 20 | if(p.charAt(j-1) == '*') { //如果当前 j 指向的字符为 '*',把类似 'a*', 'b*' 等的当成整体看待。 21 | 22 | dp[i][j] = dp[i][j-2]; 23 | if(matches(s, p, i, j-1)) { 24 | dp[i][j] = dp[i][j] || dp[i-1][j]; 25 | // 1. 可以只把 i 前移一位,而不丢弃 'b*', 转化为子问题 f[i-1][j]; 26 | // 2.也可以选择让 'b*' 不再进行匹配,把 'b*' 丢弃。转化为子问题 f[i][j-2]; 27 | } 28 | } else { 29 | if(matches(s,p,i,j)) { 30 | dp[i][j] = dp[i-1][j-1]; 31 | } 32 | } 33 | } 34 | } 35 | return dp[m][n]; 36 | } 37 | 38 | private boolean matches(String s, String p, int i, int j) { 39 | if(i==0){ 40 | return false; 41 | } 42 | if(p.charAt(j-1) == '.') { 43 | return true; 44 | } 45 | return s.charAt(i-1) == p.charAt(j-1); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /2021-02-22/SearchRangeLintcode11.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import Leetcode.TreeNode; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | import java.util.Stack; 7 | 8 | public class SearchRangeLintcode11 { 9 | 10 | /** 11 | * @param root: param root: The root of the binary search tree 12 | * @param k1: An integer 13 | * @param k2: An integer 14 | * @return: return: Return all keys that k1<=key<=k2 in ascending order 15 | */ 16 | public List searchRange(TreeNode root, int k1, int k2) { 17 | // write your code here 18 | List res = new ArrayList<>(); 19 | if(root == null) { 20 | return res; 21 | } 22 | Stack stack = new Stack<>(); 23 | TreeNode cur = root; 24 | while(cur != null || !stack.isEmpty()) { 25 | while (cur != null) { 26 | stack.push(cur); 27 | cur = cur.left; 28 | } 29 | if(!stack.isEmpty()) { 30 | cur = stack.pop(); 31 | if(cur.val >= k1 && cur.val <= k2) { 32 | res.add(cur.val); 33 | } 34 | } 35 | cur = cur.right; 36 | } 37 | return res; 38 | } 39 | 40 | //Definition for a binary tree node. 41 | public class TreeNode { 42 | int val; 43 | TreeNode left; 44 | TreeNode right; 45 | TreeNode() {} 46 | TreeNode(int val) { this.val = val; } 47 | TreeNode(int val, TreeNode left, TreeNode right) { 48 | this.val = val; 49 | this.left = left; 50 | this.right = right; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /2021-04-04/DecodeString394.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.Stack; 4 | 5 | public class DecodeString394 { 6 | 7 | /**Method: Stacks; Time: O(N), Space: O(1) **/ 8 | /** 9 | 思路: 两个栈分别保存遇到']'之前的值 10 | stack1保存: 此前的临时string结果 res 至栈 11 | stack2保存: 此前的临时次数结果 multi 至栈 12 | 当 c 为数字时,将数字字符转化为数字 multi,用于后续倍数计算; 13 | 当 c 为字母时,在 res 尾部添加 c; 14 | 当 c 为 [ 时,将当前 multi 和 res 入栈,并分别置空置 0: 15 | 当 c 为 ] 时,stack 出栈,拼接字符串 res = last_res + cur_multi * res 16 | **/ 17 | public String decodeString(String s) { 18 | StringBuilder res = new StringBuilder(); 19 | int multi = 0; 20 | Stack multiStack = new Stack<>(); //stack1 store the previous times 21 | Stack resStack = new Stack<>(); //stack2 store the previous String 22 | for(Character c: s.toCharArray()) { //注意:s.toCharArray() 23 | if(c.equals('[')) { 24 | resStack.push(res.toString()); 25 | multiStack.add(multi); 26 | multi = 0; 27 | res = new StringBuilder(); 28 | } else if(c.equals(']')){ 29 | int curMulti = multiStack.pop(); 30 | StringBuilder temp = new StringBuilder(); 31 | for(int i=0; i< curMulti;i++) { 32 | temp.append(res); 33 | } 34 | res = new StringBuilder(resStack.pop() + temp.toString()); //注意: 这里把新老值都更新到res 35 | } else if(c>='0' && c <='9') { 36 | multi = multi * 10 + (c-'0'); 37 | } else { 38 | res.append(c); 39 | } 40 | } 41 | return res.toString(); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /2021-03-12/Rand470.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import Leetcode.SolBase; 4 | 5 | public class Rand470 extends SolBase { 6 | 7 | /**Method1: Rejection Sampling; Time:O(1) - O(∞); Space:O(1) **/ 8 | /* 9 | 10 | 为什么? (rand7()−1)∗7+rand7() 11 | 12 | 1. 首先 rand7()-1得到的数的集合为 { 0,1,2,3,4,5,6} 13 | 14 | 2. 再乘 7 后得到的集合 A 为 { 0,7,14,21,28,35,42} 15 | 16 | 3. 后面 rand7() 得到的集合B为 { 1,2,3,4,5,6,7} 17 | */ 18 | public int rand10_1() { 19 | int row, col, res; 20 | do { 21 | row = rand7(); 22 | col = rand7(); 23 | res = (row -1) * 7 + col; 24 | } while(res > 40); 25 | return (res -1) % 10 + 1; 26 | } 27 | 28 | /**Method2: Rejection Sampling By Use Rejection Sampling; Time:O(1) - O(∞); Space:O(1) **/ 29 | public int rand10_2() { 30 | int row, col, res; 31 | while(true) { 32 | row = rand7(); 33 | col = rand7(); 34 | res = (row -1) * 7 + col; 35 | if (res <= 40) { 36 | return (res -1) % 10 + 1; 37 | } 38 | 39 | row = res - 40; 40 | col = rand7(); 41 | // get uniform dist from 1 - 63 42 | res = (row - 1) * 7 + col; 43 | if (res <= 60) { 44 | return (res -1) % 10 + 1; 45 | } 46 | 47 | row = res - 60; 48 | col = rand7(); 49 | // get uniform dist from 1 - 21 50 | res = (row - 1) * 7 + col; 51 | if (res <= 20) { 52 | return (res -1) % 10 + 1; 53 | } 54 | } 55 | } 56 | } 57 | 58 | class SolBase { 59 | int rand7() { 60 | return 0; //TODO 61 | }; 62 | } 63 | -------------------------------------------------------------------------------- /2021-04-21/LowestCommonAncestor235.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import Leetcode.IsSymmetric803.TreeNode; 4 | 5 | public class LowestCommonAncestor235 { 6 | 7 | 8 | /**Method: recursion; Time: O(N), Space: O(H) **/ 9 | /** 10 | 我们从根节点开始遍历; 11 | 如果当前节点的值大于 pp 和 qq 的值,说明 pp 和 qq 应该在当前节点的左子树,因此将当前节点移动到它的左子节点; 12 | 如果当前节点的值小于 pp 和 qq 的值,说明 pp 和 qq 应该在当前节点的右子树,因此将当前节点移动到它的右子节点; 13 | 如果当前节点的值不满足上述两条要求,那么说明当前节点就是「分岔点」。此时,pp 和 qq 要么在当前节点的不同的子树中,要么其中一个就是当前节点。 14 | **/ 15 | public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { 16 | if(root.val < p.val && root.val < q.val) return lowestCommonAncestor(root.right, p, q); 17 | if(root.val > p.val && root.val > q.val) return lowestCommonAncestor(root.left, p, q); 18 | return root; 19 | } 20 | 21 | /**Method: Loop; Time: O(N), Space: O(1) **/ 22 | /** 23 | 我们从根节点开始遍历; 24 | 如果当前节点的值大于 pp 和 qq 的值,说明 pp 和 qq 应该在当前节点的左子树,因此将当前节点移动到它的左子节点; 25 | 如果当前节点的值小于 pp 和 qq 的值,说明 pp 和 qq 应该在当前节点的右子树,因此将当前节点移动到它的右子节点; 26 | 如果当前节点的值不满足上述两条要求,那么说明当前节点就是「分岔点」。此时,pp 和 qq 要么在当前节点的不同的子树中,要么其中一个就是当前节点。 27 | **/ 28 | public TreeNode lowestCommonAncestor2(TreeNode root, TreeNode p, TreeNode q) { 29 | TreeNode parent = root; 30 | while (true) { 31 | if (p.val < parent.val && q.val < parent.val) { 32 | parent = parent.left; 33 | } else if (p.val > parent.val && q.val > parent.val) { 34 | parent = parent.right; 35 | } else { 36 | break; 37 | } 38 | } 39 | return parent; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /2021-03-31/ReverseKGroup25.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class ReverseKGroup25 { 4 | /*Method: Pointers, Time: O(n∗K), Space:O(1)**/ 5 | public ListNode reverseKGroup(ListNode head, int k) { 6 | if(head == null || head.next == null) { 7 | return head; 8 | } 9 | ListNode dummy = new ListNode(-1); 10 | dummy.next = head; 11 | //初始需要两个变量 pre 和 end,pre 代表待翻转链表的前驱,end 代表待翻转链表的末尾 12 | ListNode pre = dummy; 13 | ListNode end = dummy; 14 | while(end.next != null) { 15 | for(int i=0; i< k && end != null; i++) { 16 | end = end.next; 17 | } 18 | if(end == null) { 19 | break; 20 | } 21 | ListNode start = pre.next; 22 | ListNode np = end.next; //经过k此循环,end 到达末尾,记录待翻转链表的后继 np = end.next 23 | end.next = null; 24 | pre.next = reverse(start); 25 | 26 | start.next = np; 27 | pre = start; 28 | end = pre; 29 | 30 | } 31 | return dummy.next; 32 | } 33 | 34 | private ListNode reverse(ListNode head) { 35 | ListNode pre = null; 36 | ListNode cur = head; 37 | while(cur != null) { 38 | ListNode np = cur.next; 39 | cur.next = pre; 40 | pre = cur; 41 | cur = np; 42 | } 43 | return pre; 44 | } 45 | 46 | 47 | //Definition for singly-linked list. 48 | public class ListNode { 49 | int val; 50 | ListNode next; 51 | ListNode() {} 52 | ListNode(int val) { this.val = val; } 53 | ListNode(int val, ListNode next) { this.val = val; this.next = next; } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /2021-02-22/DeleteNodeBst450.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | public class DeleteNodeBst450 { 4 | /**Method: Recursive; Time:O(H); Space: O(H) **/ 5 | public TreeNode deleteNode(TreeNode root, int key) { 6 | if(root == null) { 7 | return null; 8 | } 9 | if(root.val > key) { 10 | root.left = deleteNode(root.left, key); 11 | } else if (root.val < key) { 12 | root.right = deleteNode(root.right, key); 13 | } else { 14 | if (root.left == null && root.right == null) { 15 | root = null; 16 | } else if (root.right != null) { 17 | root.val = successor(root); 18 | root.right = deleteNode(root.right, root.val); 19 | } else { 20 | root.val = predecessor(root); 21 | root.left = deleteNode(root.left, root.val); 22 | } 23 | } 24 | return root; 25 | } 26 | private int successor(TreeNode root) { 27 | root = root.right; 28 | while(root.left != null) root = root.left; 29 | return root.val; 30 | } 31 | private int predecessor(TreeNode root) { 32 | root = root.left; 33 | while(root.right != null) root = root.right; 34 | return root.val; 35 | } 36 | 37 | //Definition for a binary tree node. 38 | public class TreeNode { 39 | int val; 40 | TreeNode left; 41 | TreeNode right; 42 | TreeNode() {} 43 | TreeNode(int val) { this.val = val; } 44 | TreeNode(int val, TreeNode left, TreeNode right) { 45 | this.val = val; 46 | this.left = left; 47 | this.right = right; 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /2021-04-23/LengthOfLIS300.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.Arrays; 4 | 5 | public class LengthOfLIS300 { 6 | /**Method:DP; Time:O(N^2); Space:O(N) **/ 7 | public int lengthOfLIS(int[] nums) { 8 | if(nums == null) { 9 | return 0; 10 | } 11 | int len = nums.length; 12 | int[] dp = new int[len]; //dp[i] 表示:以 nums[i] 结尾 的「上升子序列」的长度。 13 | Arrays.fill(dp, 1); 14 | int res = 1; 15 | for(int i=0;i nums[j] ) { 18 | dp[i] = Math.max(dp[i], dp[j]+1); //只要 nums[i] 严格大于在它位置之前的某个数,那么 nums[i] 就可以接在这个数后面形成一个更长的上升子序列。 19 | } 20 | } 21 | res= Math.max(res, dp[i]); 22 | } 23 | return res; 24 | } 25 | 26 | /** Method2: Greedy + BinSearch; Time:O(NLogN); Space: O(N) **/ 27 | /** 28 | 维护一个数组 tails[i] ,表示长度为 i 的最长上升子序列的末尾元素的最小值 29 | 设当前已求出的最长上升子序列的长度为len(初始时为 11),从前往后遍历数组nums,在遍历到nums[i] 时: 30 | 如果 nums[i]>tails[len] ,则直接加入到 tails 数组末尾,并更新 len=len+1; 31 | 否则,在 tails 数组中二分查找,找到第一个比nums[i] 小的数 d[k] ,并更新 tails[k + 1] = nums[i]。 32 | **/ 33 | public int lengthOfLIS2(int[] nums) { 34 | int[] tails = new int[nums.length]; 35 | int res = 0; 36 | for(int num:nums){ 37 | int i=0, j = res; 38 | while(i(Arrays.asList(data.split(",")))); 27 | } 28 | private TreeNode deserialize(List data) { 29 | if(data.get(0).equals("None")) { 30 | data.remove(0); 31 | return null; 32 | } 33 | TreeNode cur = new TreeNode(Integer.valueOf(data.get(0))); 34 | data.remove(0); 35 | cur.left = deserialize(data); 36 | cur.right = deserialize(data); 37 | return cur; 38 | } 39 | 40 | //Definition for a binary tree node. 41 | public class TreeNode { 42 | int val; 43 | TreeNode left; 44 | TreeNode right; 45 | TreeNode() {} 46 | TreeNode(int val) { this.val = val; } 47 | TreeNode(int val, TreeNode left, TreeNode right) { 48 | this.val = val; 49 | this.left = left; 50 | this.right = right; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /2021-03-26/SerializeBTree297.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | import java.util.Arrays; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | 7 | public class SerializeBTree297 { 8 | /**Method: DFS; Time:O(N); Space: O(N) **/ 9 | 10 | // Encodes a tree to a single string. 11 | public String serialize(TreeNode root) { 12 | return serialize(root, ""); 13 | } 14 | private String serialize(TreeNode root, String str) { 15 | if(root == null) { 16 | str += "None,"; 17 | } else { 18 | str += String.valueOf(root.val) + ","; 19 | str = serialize(root.left, str); 20 | str = serialize(root.right, str); 21 | } 22 | return str; 23 | } 24 | // Decodes your encoded data to tree. 25 | public TreeNode deserialize(String data) { 26 | return deserialize(new LinkedList<>(Arrays.asList(data.split(",")))); //需要new list 27 | } 28 | private TreeNode deserialize(List data) { 29 | if(data.get(0).equals("None")) { 30 | data.remove(0); 31 | return null; //移除并返回节点 32 | } 33 | TreeNode node=new TreeNode(Integer.valueOf(data.get(0))); 34 | data.remove(0); 35 | node.left = deserialize(data); 36 | node.right = deserialize(data); 37 | return node; 38 | } 39 | 40 | //Definition for a binary tree node. 41 | public class TreeNode { 42 | int val; 43 | TreeNode left; 44 | TreeNode right; 45 | TreeNode() {} 46 | TreeNode(int val) { this.val = val; } 47 | TreeNode(int val, TreeNode left, TreeNode right) { 48 | this.val = val; 49 | this.left = left; 50 | this.right = right; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /2021-02-22/IsValidBST98.java: -------------------------------------------------------------------------------- 1 | package Leetcode; 2 | 3 | 4 | import java.util.Deque; 5 | import java.util.LinkedList; 6 | 7 | public class IsValidBST98 { 8 | 9 | /**Method 1: Recursive; Time:O(N); Space: O(N) **/ 10 | public boolean isValidBST1(TreeNode root) { 11 | return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE); 12 | } 13 | public boolean isValidBST(TreeNode node, long lower, long upper) { 14 | if(node == null) { 15 | return true; 16 | } 17 | if(node.val <= lower || node.val >= upper) { 18 | return false; 19 | } 20 | return isValidBST(node.left, lower, node.val) && isValidBST(node.right, node.val, upper); 21 | } 22 | 23 | /**Method 2: Iteration; Time:O(N); Space: O(N) **/ 24 | public boolean isValidBST2(TreeNode root) { 25 | Deque stack = new LinkedList<>(); 26 | double lastVal = -Double.MAX_VALUE; 27 | TreeNode cur = root; 28 | while(!stack.isEmpty() || cur!=null) { 29 | while(cur != null) { 30 | stack.push(cur); 31 | cur = cur.left; 32 | } 33 | cur = stack.pop(); 34 | if(cur.val <= lastVal ) { 35 | return false; 36 | } 37 | lastVal = cur.val; 38 | cur = cur.right; 39 | } 40 | return true; 41 | } 42 | 43 | //Definition for a binary tree node. 44 | public class TreeNode { 45 | int val; 46 | TreeNode left; 47 | TreeNode right; 48 | TreeNode() {} 49 | TreeNode(int val) { this.val = val; } 50 | TreeNode(int val, TreeNode left, TreeNode right) { 51 | this.val = val; 52 | this.left = left; 53 | this.right = right; 54 | } 55 | } 56 | 57 | } 58 | --------------------------------------------------------------------------------