Leetcode CookBook算法 算法集合的网站
https://leetcode.cn/leetbook/read/leetcode-cookbook
数组 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution { public int [] twoSum(int [] nums, int target) { int [] result = new int [2 ]; for (int i = 0 ; i < nums.length; i++) { boolean isHaveResult = false ; for (int j = 0 ; j < nums.length; j++) { if (i == j) { continue ; } if (nums[i] + nums[j] == target) { isHaveResult = true ; result[0 ] = i; result[1 ] = j; } } if (isHaveResult) { break ; } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public int [] twoSum(int [] nums, int target) { HashMap<Integer, Integer> map = new HashMap <>(); int [] result = new int [2 ]; for (int i = 0 ; i < nums.length; i++) { if (map.containsKey(target - nums[i])) { result[0 ] = i; result[1 ] = map.get(target - nums[i]); break ; } map.put(nums[i], i); } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public double findMedianSortedArrays (int [] nums1, int [] nums2) { int [] nums = new int [nums1.length + nums2.length]; int i = 0 , j = 0 , k = 0 ; while (i < nums1.length && j < nums2.length) { if (nums1[i] <= nums2[j]) { nums[k++] = nums1[i++]; } else { nums[k++] = nums2[j++]; } } while (i < nums1.length) { nums[k++] = nums1[i++]; } while (j < nums2.length) { nums[k++] = nums2[j++]; } if (nums.length % 2 == 0 ) { return ((double ) (nums[nums.length / 2 ] + nums[(nums.length - 1 ) / 2 ])) / 2 ; } else { return (double ) (nums[nums.length / 2 ]); } } }
优化写法,有空再看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution { public int maxArea (int [] height) { int l = 0 , r = height.length - 1 , result = 0 ; while (l < r) { result = Math.max(Math.min(height[l], height[r]) * (r - l), result); if (height[l] < height[r]) { l++; } else { r--; } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 class Solution { public List<List<Integer>> threeSum (int [] nums) { Arrays.sort(nums); List<List<Integer>> result = new ArrayList <>(); for (int i = 0 ; i < nums.length; i++) { if (nums[i] > 0 ) { break ; } if (i != 0 && nums[i] == nums[i - 1 ]) { continue ; } int l = i + 1 , r = nums.length - 1 ; while (l < r) { int temp = nums[i] + nums[l] + nums[r]; if (temp < 0 ) { l++; } else if (temp > 0 ) { r--; } else { result.add(Arrays.asList(nums[i], nums[l], nums[r])); l++; while (l < r && nums[l] == nums[l - 1 ]) { l++; } r--; } } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 class Solution { public int threeSumClosest (int [] nums, int target) { int result = Integer.MAX_VALUE; int lastTemp = Math.abs(result - target); Arrays.sort(nums); for (int i = 0 ; i < nums.length; i++) { if (i > 0 && nums[i] == nums[i - 1 ]) { continue ; } int l = i + 1 , r = nums.length - 1 ; while (l < r) { int sum = nums[i] + nums[l] + nums[r]; if (sum == target) { return target; } int temp = Math.abs(sum - target); if (temp < lastTemp) { result = sum; lastTemp = temp; } if (sum > target) { r--; } else { l++; } } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 class Solution { public List<List<Integer>> fourSum (int [] nums, int target) { List<List<Integer>> result = new ArrayList <>(); Arrays.sort(nums); for (int i = 0 ; i < nums.length; i++) { if (nums[i] >= 0 && nums[i] > target) { break ; } if (i > 0 && nums[i] == nums[i - 1 ]) { continue ; } for (int j = i + 1 ; j < nums.length; j++) { if (nums[i] + nums[j] >= 0 && nums[i] + nums[j] > target) { break ; } if (j > i + 1 && nums[j] == nums[j - 1 ]) { continue ; } int left = j + 1 ; int right = nums.length - 1 ; while (left < right) { long sum = (long ) nums[i] + nums[j] + nums[left] + nums[right]; if (sum < target) { left++; } else if (sum > target) { right--; } else { result.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right])); left++; right--; while (left < right && nums[left] == nums[left - 1 ]) { left++; } while (left < right && nums[right] == nums[right + 1 ]) { right--; } } } } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public int removeDuplicates (int [] nums) { int cur = 0 , i = 0 , len = nums.length; while (i < nums.length) { nums[cur++] = nums[i++]; while (i < len && nums[i] == nums[i - 1 ]) { i++; } } return cur; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public int removeElement (int [] nums, int val) { int cur = 0 , i = 0 , len = nums.length; while (i < len) { if (nums[i] == val) { i++; continue ; } nums[cur++] = nums[i++]; } return cur; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution { public int searchInsert (int [] nums, int target) { int left = 0 , right = nums.length - 1 ; while (left <= right) { int mid = (left + right) >> 1 ; if (nums[mid] > target) { right = mid - 1 ; } else if (nums[mid] < target) { left = mid + 1 ; } else { return mid; } } return left; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public List<List<Integer>> combinationSum (int [] candidates, int target) { Arrays.sort(candidates); List<List<Integer>> result = new ArrayList <>(); dfs(result, new ArrayList <>(), candidates, target, 0 ); return result; } public void dfs (List<List<Integer>> result, List<Integer> temp, int [] candidates, int balance, int index) { if (balance == 0 ) { result.add(new ArrayList <>(temp)); return ; } for (int i = index; i < candidates.length; i++) { if (candidates[i] > balance) { break ; } temp.add(candidates[i]); dfs(result, temp, candidates, balance - candidates[i], i); temp.remove(temp.size() - 1 ); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Solution { public List<List<Integer>> combinationSum2 (int [] candidates, int target) { Arrays.sort(candidates); List<List<Integer>> result = new ArrayList <>(); dfs(result, new ArrayList <>(), candidates, new boolean [candidates.length], 0 , target); return result; } public void dfs (List<List<Integer>> result, List<Integer> temp, int [] candidates, boolean [] isVisted, int index, int balance) { if (balance == 0 ) { result.add(new ArrayList <>(temp)); return ; } for (int i = index; i < candidates.length; i++) { if (candidates[i] > balance) { break ; } if (i > 0 && candidates[i - 1 ] == candidates[i] && !isVisted[i - 1 ]) { continue ; } temp.add(candidates[i]); isVisted[i] = true ; dfs(result, temp, candidates, isVisted, i + 1 , balance - candidates[i]); temp.remove(temp.size() - 1 ); isVisted[i] = false ; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { public void rotate (int [][] matrix) { int n = matrix.length - 1 ; for (int i = 0 ; i < n; i++) { for (int j = i + 1 ; j <= n; j++) { int temp = matrix[i][j]; matrix[i][j] = matrix[j][i]; matrix[j][i] = temp; } } for (int i = 0 ; i <= n; i++) { for (int j = 0 ; j < (n + 1 ) / 2 ; j++) { int temp = matrix[i][j]; matrix[i][j] = matrix[i][n - j]; matrix[i][n - j] = temp; } } } }
1 2 3 4 5 6 7 8 9 10 11 12 class Solution { public int maxSubArray (int [] nums) { int result = nums[0 ], temp = nums[0 ]; for (int i = 1 ; i < nums.length; i++) { temp = Math.max(nums[i], temp + nums[i]); result = Math.max(result, temp); } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 class Solution { public List<Integer> spiralOrder (int [][] matrix) { List<Integer> result = new ArrayList <>(); int top = 0 , bottom = matrix.length - 1 , left = 0 , right = matrix[0 ].length - 1 ; while (top <= bottom && left <= right) { for (int j = left; j <= right; j++) { result.add(matrix[top][j]); } top++; for (int i = top; i <= bottom; i++) { result.add(matrix[i][right]); } right--; if (top <= bottom) { for (int j = right; j >= left; j--) { result.add(matrix[bottom][j]); } bottom--; } if (left <= right) { for (int i = bottom; i >= top; i--) { result.add(matrix[i][left]); } left++; } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public boolean canJump (int [] nums) { int balance = 0 ; for (int i = 0 ; i < nums.length; i++) { if (i <= balance) { balance = Math.max(balance, i + nums[i]); if (balance >= nums.length - 1 ) { return true ; } } } return false ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 class Solution { public int [][] generateMatrix(int n) { int [][] result = new int [n][n]; int temp = 1 , top = 0 , bottom = n - 1 , left = 0 , right = n - 1 ; while (top <= bottom && left <= right) { for (int j = left; j <= right; j++) { result[top][j] = temp; temp++; } top++; for (int i = top; i <= bottom; i++) { result[i][right] = temp; temp++; } right--; if (top <= bottom) { for (int j = right; j >= left; j--) { result[bottom][j] = temp; temp++; } bottom--; } if (left <= right) { for (int i = bottom; i >= top; i--) { result[i][left] = temp; temp++; } left++; } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public int uniquePaths (int m, int n) { int [] dp = new int [n]; Arrays.fill(dp, 1 ); for (int i = 1 ; i < m; i++) { for (int j = 1 ; j < n; j++) { dp[j] += dp[j - 1 ]; } } return dp[n - 1 ]; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { public int uniquePathsWithObstacles (int [][] obstacleGrid) { int m = obstacleGrid.length, n = obstacleGrid[0 ].length; int [][] dp = new int [m][n]; dp[0 ][0 ] = obstacleGrid[0 ][0 ] == 1 ? 0 : 1 ; for (int j = 1 ; j < n; j++) { dp[0 ][j] = obstacleGrid[0 ][j] == 1 ? 0 : dp[0 ][j - 1 ]; } for (int i = 1 ; i < m; i++) { dp[i][0 ] = obstacleGrid[i][0 ] == 1 ? 0 : dp[i - 1 ][0 ]; } for (int i = 1 ; i < m; i++) { for (int j = 1 ; j < n; j++) { dp[i][j] = obstacleGrid[i][j] == 1 ? 0 : dp[i - 1 ][j] + dp[i][j - 1 ]; } } return dp[m - 1 ][n - 1 ]; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { public int minPathSum (int [][] grid) { int [] dp = new int [grid[0 ].length]; dp[0 ] = grid[0 ][0 ]; for (int j = 1 ; j < grid[0 ].length; j++) { dp[j] = dp[j - 1 ] + grid[0 ][j]; } for (int i = 1 ; i < grid.length; i++) { for (int j = 0 ; j < grid[0 ].length; j++) { if (j != 0 ) { dp[j] = Math.min(dp[j], dp[j - 1 ]) + grid[i][j]; } else { dp[j] += grid[i][j]; } } } return dp[grid[0 ].length - 1 ]; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution { public int [] plusOne(int [] digits) { int carry = 1 ; int len = digits.length; for (int i = len - 1 ; i >= 0 ; i--) { digits[i] += carry; carry = digits[i] / 10 ; digits[i] = digits[i] % 10 ; } if (carry == 0 ) { return digits; } else { int [] result = new int [len + 1 ]; result[0 ] = carry; for (int i = 0 ; i < len; i++) { result[i + 1 ] = digits[i]; } return result; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution { public boolean searchMatrix (int [][] matrix, int target) { int m = matrix.length, n = matrix[0 ].length, len = m * n, left = 0 , right = len - 1 ; while (left <= right) { int mid = (left + right) >> 1 ; int i = mid / n, j = mid % n; if (matrix[i][j] > target) { right = mid - 1 ; } else if (matrix[i][j] < target) { left = mid + 1 ; } else { return true ; } } return false ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { public List<List<Integer>> subsets (int [] nums) { List<List<Integer>> result = new ArrayList <>(); dfs(result, new ArrayList <>(), nums, 0 ); return result; } public void dfs (List<List<Integer>> result, List<Integer> temp, int [] nums, int index) { result.add(new ArrayList <>(temp)); for (int i = index; i < nums.length; i++) { temp.add(nums[i]); dfs(result, temp, nums, i + 1 ); temp.remove(temp.size() - 1 ); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 class Solution { public boolean exist (char [][] board, String word) { if (board.length * board[0 ].length < word.length()) { return false ; } int [][] dirs = new int [][] { { 1 , 0 }, { -1 , 0 }, { 0 , -1 }, { 0 , 1 } }; StringBuilder builder = new StringBuilder (); boolean [][] isVisited = new boolean [board.length][board[0 ].length]; for (int i = 0 ; i < board.length; i++) { for (int j = 0 ; j < board[0 ].length; j++) { if (board[i][j] == word.charAt(0 )) { builder.append(board[i][j]); isVisited[i][j] = true ; if (dfs(board, word, dirs, builder, isVisited, i, j)) { return true ; } builder.deleteCharAt(builder.length() - 1 ); isVisited[i][j] = false ; } } } return false ; } public boolean dfs (char [][] board, String word, int [][] dirs, StringBuilder builder, boolean [][] isVisited, int i, int j) { if (builder.length() == word.length()) { return word.equals(builder.toString()); } boolean result = false ; for (int [] dir : dirs) { int newI = i + dir[0 ], newJ = j + dir[1 ]; if (newI >= 0 && newI < board.length && newJ >= 0 && newJ < board[0 ].length && !isVisited[newI][newJ] && board[newI][newJ] == word.charAt(builder.length())) { isVisited[newI][newJ] = true ; builder.append(board[newI][newJ]); result = result || dfs(board, word, dirs, builder, isVisited, newI, newJ); if (result) { return true ; } isVisited[newI][newJ] = false ; builder.deleteCharAt(builder.length() - 1 ); } } return result; } }
时间花费很高,后面看看怎么优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 class Solution { public static int [][] dirs = new int [][] { { -1 , 0 }, { 1 , 0 }, { 0 , -1 }, { 0 , 1 } }; public boolean exist (char [][] board, String word) { boolean [][] isVisited = new boolean [board.length][board[0 ].length]; for (int i = 0 ; i < board.length; i++) { for (int j = 0 ; j < board[0 ].length; j++) { if (dfs(board, word, isVisited, 0 , i, j)) { return true ; } } } return false ; } public boolean dfs (char [][] board, String word, boolean [][] isVisited, int index, int i, int j) { if (index == word.length() - 1 ) { return board[i][j] == word.charAt(word.length() - 1 ); } if (board[i][j] == word.charAt(index)) { isVisited[i][j] = true ; for (int [] dir : dirs) { int newI = i + dir[0 ], newJ = j + dir[1 ]; if (newI >= 0 && newI < board.length && newJ >= 0 && newJ < board[0 ].length && !isVisited[newI][newJ]) { if (dfs(board, word, isVisited, index + 1 , newI, newJ)) { return true ; } } } isVisited[i][j] = false ; } return false ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution { public int removeDuplicates (int [] nums) { int count = 1 , cur = 1 ; for (int i = 1 ; i < nums.length; i++) { if (nums[i] == nums[i - 1 ]) { count++; if (count <= 2 ) { nums[cur++] = nums[i]; } } else { count = 1 ; nums[cur++] = nums[i]; } } return cur; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution { public void merge (int [] nums1, int m, int [] nums2, int n) { int [] temp = new int [m + n]; int i = 0 , j = 0 , cur = 0 ; while (i < m && j < n) { if (nums1[i] <= nums2[j]) { temp[cur++] = nums1[i++]; } else { temp[cur++] = nums2[j++]; } } while (i < m) { temp[cur++] = nums1[i++]; } while (j < n) { temp[cur++] = nums2[j++]; } for (i = 0 ; i < m + n; i++) { nums1[i] = temp[i]; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution { public void merge (int [] nums1, int m, int [] nums2, int n) { int i = m - 1 , j = n - 1 , cur = m + n - 1 ; while (i >= 0 && j >= 0 ) { if (nums1[i] >= nums2[j]) { nums1[cur--] = nums1[i--]; } else { nums1[cur--] = nums2[j--]; } } while (i >= 0 ) { nums1[cur--] = nums1[i--]; } while (j >= 0 ) { nums1[cur--] = nums2[j--]; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public List<List<Integer>> subsetsWithDup (int [] nums) { Arrays.sort(nums); List<List<Integer>> result = new ArrayList <>(); dfs(result, nums, -1 , new boolean [nums.length], new ArrayList <>()); return result; } public void dfs (List<List<Integer>> result, int [] nums, int curIndex, boolean [] isVisited, List<Integer> temp) { result.add(new ArrayList <>(temp)); for (int i = curIndex + 1 ; i < nums.length; i++) { if (i == 0 || (!isVisited[i - 1 ] && nums[i - 1 ] != nums[i]) || isVisited[i - 1 ]) { temp.add(nums[i]); isVisited[i] = true ; dfs(result, nums, i, isVisited, temp); temp.remove(temp.size() - 1 ); isVisited[i] = false ; } } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public TreeNode buildTree (int [] preorder, int [] inorder) { return build(preorder, inorder, 0 , preorder.length - 1 , 0 , inorder.length - 1 ); } public TreeNode build (int [] preorder, int [] inorder, int preL, int preR, int inL, int inR) { if (preL > preR) { return null ; } TreeNode head = new TreeNode (preorder[preL]); for (int i = inL; i <= inR; i++) { if (inorder[i] == preorder[preL]) { int lCount = i - inL, rCount = inR - i; head.left = build(preorder, inorder, preL + 1 , preL + lCount, inL, i - 1 ); head.right = build(preorder, inorder, preL + lCount + 1 , preR, i + 1 , inR); break ; } } return head; } }
题解说可以优化到O(n),后看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { public TreeNode buildTree (int [] inorder, int [] postorder) { return build(inorder, postorder, 0 , inorder.length - 1 , 0 , postorder.length - 1 ); } public TreeNode build (int [] inorder, int [] postorder, int inL, int inR, int postL, int postR) { if (postL > postR) { return null ; } TreeNode head = new TreeNode (postorder[postR]); for (int i = inL; i <= inR; i++) { if (inorder[i] == postorder[postR]) { int lCount = i - inL, rCount = inR - i; head.left = build(inorder, postorder, inL, inL + lCount - 1 , postL, postL + lCount - 1 ); head.right = build(inorder, postorder, i + 1 , inR, postR - rCount, postR - 1 ); break ; } } return head; } }
一样,后续有时间再优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution { public List<List<Integer>> generate (int numRows) { List<List<Integer>> result = new ArrayList <>(); for (int num = 0 ; num < numRows; num++) { List<Integer> temp = new ArrayList <>(); for (int i = 0 ; i <= num; i++) { int cur = 0 ; if (num == 0 ) { cur = 1 ; } else { if (i - 1 >= 0 ) { cur += result.get(num - 1 ).get(i - 1 ); } if (i < num) { cur += result.get(num - 1 ).get(i); } } temp.add(cur); } result.add(temp); } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution { public int minimumTotal (List<List<Integer>> triangle) { for (int i = 1 ; i < triangle.size(); i++) { for (int j = 0 ; j < triangle.get(i).size(); j++) { int t = triangle.get(i).get(j); if (j == 0 ) { triangle.get(i).set(j, t + triangle.get(i - 1 ).get(j)); } else if (j == triangle.get(i).size() - 1 ) { triangle.get(i).set(j, t + triangle.get(i - 1 ).get(j - 1 )); } else { triangle.get(i).set(j, Math.min( t + triangle.get(i - 1 ).get(j - 1 ), t + triangle.get(i - 1 ).get(j))); } } } int min = Integer.MAX_VALUE; for (int i : triangle.get(triangle.size() - 1 )) { min = Math.min(min, i); } return min; } }
看起来时间复杂度是一样的,不知道为什么对集合操作过多耗时就是多,看下面dp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution { public int minimumTotal (List<List<Integer>> triangle) { int [] dp = new int [triangle.size()]; for (int i = 0 ; i < triangle.size(); i++) { for (int j = i; j >= 0 ; j--) { if (j == 0 ) { dp[j] += triangle.get(i).get(j); } else if (j == i) { dp[j] = dp[j - 1 ] + triangle.get(i).get(j); } else { dp[j] = triangle.get(i).get(j) + Math.min(dp[j], dp[j - 1 ]); } } } int min = Integer.MAX_VALUE; for (int i : dp) { min = Math.min(i, min); } return min; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { public int majorityElement (int [] nums) { int t = 0 , result = 0 ; for (int i : nums) { if (t == 0 ) { t = 1 ; result = i; continue ; } if (i != result) { t--; } else { t++; } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution { public int minSubArrayLen (int target, int [] nums) { int result = Integer.MAX_VALUE, left = 0 , right = 0 , temp = nums[0 ]; while (right <= nums.length) { if (temp < target) { right++; if (right < nums.length) { temp += nums[right]; } } else { result = Math.min(result, right - left + 1 ); temp -= nums[left]; left++; if (left > right) { break ; } } } return result == Integer.MAX_VALUE ? 0 : result; } }
以前提交的,代码优雅不少
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { public int minSubArrayLen (int target, int [] nums) { int result = Integer.MAX_VALUE; int sum = 0 ; int left = 0 ; for (int right = 0 ; right < nums.length; right++) { sum += nums[right]; while (sum >= target) { result = Math.min(result, right - left + 1 ); sum -= nums[left++]; } } return result == Integer.MAX_VALUE ? 0 : result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public List<List<Integer>> combinationSum3 (int k, int n) { List<List<Integer>> result = new ArrayList <>(); List<Integer> temp = new ArrayList <>(); dfs(result, temp, k, n, 0 , 1 ); return result; } public void dfs (List<List<Integer>> result, List<Integer> temp, int k, int n, int curSum, int cur) { if (k == 0 ) { if (curSum == n) { result.add(new ArrayList <>(temp)); } return ; } for (int i = cur; i <= 9 ; i++) { if (curSum + i > n) { break ; } temp.add(i); dfs(result, temp, k - 1 , n, curSum + i, i + 1 ); temp.remove(temp.size() - 1 ); } } }
1 2 3 4 5 6 7 8 9 10 11 class Solution { public boolean containsDuplicate (int [] nums) { HashSet<Integer> set = new HashSet <>(); for (int i : nums) { if (!set.add(i)) { return true ; } } return false ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public boolean containsNearbyDuplicate (int [] nums, int k) { HashMap<Integer, Integer> map = new HashMap <>(); for (int i = 0 ; i < nums.length; i++) { int last = map.getOrDefault(nums[i], -1 ); if (last != -1 && i - last <= k) { return true ; } map.put(nums[i], i); } return false ; } }
换种思路,维护少点元素,降低空间复杂度的同时花费时间也少了点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution { public boolean containsNearbyDuplicate (int [] nums, int k) { HashSet<Integer> set = new HashSet <>(); for (int i = 0 ; i < nums.length; i++) { if (!set.add(nums[i])) { return true ; } if (i >= k) { set.remove(nums[i - k]); } } return false ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public void moveZeroes (int [] nums) { int cur = 0 ; for (int i = 0 ; i < nums.length; i++) { if (nums[i] != 0 ) { nums[cur++] = nums[i]; } } while (cur < nums.length) { nums[cur++] = 0 ; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution { public int thirdMax (int [] nums) { Arrays.sort(nums); int t = 0 , i = nums.length - 1 ; while (i >= 0 ) { int j = i - 1 ; t++; if (t == 3 ) { return nums[i]; } while (j >= 0 && nums[j] == nums[i]) { j--; } i = j; } return nums[nums.length - 1 ]; } }
用特定数据结构,但时间花费更多的,只是一种思路,忽略数据结构内部实现就是O(n)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public int thirdMax (int [] nums) { TreeSet<Integer> set = new TreeSet <>(); for (int i : nums) { set.add(i); if (set.size() > 3 ) { set.remove(set.first()); } } return set.size() == 3 ? set.first() : set.last(); } }
模拟,简单题不要想太多了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { public int thirdMax (int [] nums) { long first = Long.MIN_VALUE, second = Long.MIN_VALUE, third = Long.MIN_VALUE; for (long i : nums) { if (i > first) { third = second; second = first; first = i; } else if (i < first && i > second) { third = second; second = i; } else if (i < second && i > third) { third = i; } } return third == Long.MIN_VALUE ? (int ) first : (int ) third; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public List<Integer> findDisappearedNumbers (int [] nums) { int [] temp = new int [nums.length + 1 ]; for (int i : nums) { temp[i] = i; } List<Integer> result = new ArrayList <>(); for (int i = 1 ; i <= nums.length; i++) { if (temp[i] != i) { result.add(i); } } return result; } }
思路真的很牛
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { public List<Integer> findDisappearedNumbers (int [] nums) { int n = nums.length; for (int i : nums) { int x = (i - 1 ) % n; if (nums[x] <= n) { nums[x] += n; } } List<Integer> result = new ArrayList <>(); for (int i = 0 ; i < n; i++) { if (nums[i] <= n) { result.add(i + 1 ); } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { public int fourSumCount (int [] nums1, int [] nums2, int [] nums3, int [] nums4) { HashMap<Integer, Integer> map = new HashMap <>(); for (int i : nums1) { for (int j : nums2) { map.put(i + j, map.getOrDefault(i + j, 0 ) + 1 ); } } int count = 0 ; for (int i : nums3) { for (int j : nums4) { count += map.getOrDefault(-i - j, 0 ); } } return count; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { public int islandPerimeter (int [][] grid) { int [][] dirs = new int [][] { { -1 , 0 }, { 1 , 0 }, { 0 , -1 }, { 0 , 1 } }; int result = 0 ; for (int i = 0 ; i < grid.length; i++) { for (int j = 0 ; j < grid[0 ].length; j++) { if (grid[i][j] == 1 ) { for (int [] dir : dirs) { int newI = i + dir[0 ], newJ = j + dir[1 ]; if (newI < 0 || newI == grid.length || newJ < 0 || newJ == grid[0 ].length || grid[newI][newJ] == 0 ) { result++; } } } } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public int findMaxConsecutiveOnes (int [] nums) { int max = 0 , temp = 0 ; for (int i = 0 ; i < nums.length; i++) { if (nums[i] == 1 ) { temp++; } else { max = Math.max(max, temp); temp = 0 ; } } max = Math.max(max, temp); return max; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 class Solution { public int [] findDiagonalOrder(int [][] mat) { int m = mat.length, n = mat[0 ].length, i = 0 , j = 0 , cur = 0 ; int [] result = new int [m * n]; boolean isToRightTop = true ; while (cur != m * n) { boolean isOver = i < 0 || j < 0 || i == m || j == n; if (!isOver) { result[cur++] = mat[i][j]; } if (isToRightTop) { i -= 1 ; j += 1 ; } else { i += 1 ; j -= 1 ; } if (isOver) { continue ; } if (i < 0 || j < 0 || i == m || j == n) { int newI = i + 1 , newJ = j + 1 ; if (newJ == 0 || newJ == n + 1 ) { i = newI; } else { j = newJ; } isToRightTop = !isToRightTop; } } return result; } }
待优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public int fib (int n) { if (n <= 1 ) { return n; } int first = 0 , second = 1 ; for (int i = 2 ; i <= n; i++) { int temp = first + second; first = second; second = temp; } return second; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { public int maxAreaOfIsland (int [][] grid) { int result = 0 ; for (int i = 0 ; i < grid.length; i++) { for (int j = 0 ; j < grid[0 ].length; j++) { result = Math.max(result, getMax(grid, i, j)); } } return result; } public int getMax (int [][] grid, int i, int j) { if (i < 0 || i >= grid.length || j < 0 || j >= grid[0 ].length || grid[i][j] == 0 ) { return 0 ; } grid[i][j] = 0 ; return 1 + getMax(grid, i - 1 , j) + getMax(grid, i + 1 , j) + getMax(grid, i, j - 1 ) + getMax(grid, i, j + 1 ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { public int [][] imageSmoother(int [][] img) { int [][] dirs = new int [][] { { -1 , -1 }, { -1 , 0 }, { -1 , 1 }, { 0 , -1 }, { 0 , 1 }, { 1 , -1 }, { 1 , 0 }, { 1 , 1 } }, result = new int [img.length][img[0 ].length]; for (int i = 0 ; i < img.length; i++) { for (int j = 0 ; j < img[0 ].length; j++) { int cur = img[i][j], count = 1 ; for (int [] dir : dirs) { int newI = i + dir[0 ], newj = j + dir[1 ]; if (newI >= 0 && newI < img.length && newj >= 0 && newj < img[0 ].length) { cur += img[newI][newj]; count++; } } result[i][j] = cur / count; } } return result; } }
前缀和,加多外围一圈就可以处理越界的情况了,还有最后处理范围的部分也比较巧妙
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution { public int [][] imageSmoother(int [][] img) { int m = img.length, n = img[0 ].length; int [][] preSum = new int [m + 1 ][n + 1 ]; for (int i = 1 ; i <= m; i++) { for (int j = 1 ; j <= n; j++) { preSum[i][j] = img[i - 1 ][j - 1 ] + preSum[i - 1 ][j] + preSum[i][j - 1 ] - preSum[i - 1 ][j - 1 ]; } } int [][] reuslt = new int [m][n]; for (int i = 0 ; i < m; i++) { for (int j = 0 ; j < n; j++) { int a = Math.max(0 , i - 1 ), b = Math.max(0 , j - 1 ), c = Math.min(m - 1 , i + 1 ), d = Math.min(n - 1 , j + 1 ); int count = (c - a + 1 ) * (d - b + 1 ); int total = preSum[c + 1 ][d + 1 ] + preSum[a][b] - preSum[c + 1 ][b] - preSum[a][d + 1 ]; reuslt[i][j] = total / count; } } return reuslt; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution { public int findShortestSubArray (int [] nums) { HashMap<Integer, Integer> firstAppearMap = new HashMap <>(); HashMap<Integer, Integer> countMap = new HashMap <>(); int result = Integer.MAX_VALUE, maxNum = 0 ; for (int i = 0 ; i < nums.length; i++) { int temp = countMap.getOrDefault(nums[i], 0 ) + 1 ; countMap.put(nums[i], temp); if (temp >= maxNum) { int len = i - firstAppearMap.getOrDefault(nums[i], 0 ) + 1 ; if (temp > maxNum) { maxNum = temp; result = len; } else { result = Math.min(result, len); } } if (!firstAppearMap.containsKey(nums[i])) { firstAppearMap.put(nums[i], i); } } return result; } }
根据题目范围取巧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution { public int findShortestSubArray (int [] nums) { int result = Integer.MAX_VALUE, maxAppearCount = 0 ; int [] firstAppearIndex = new int [50000 ], appearCount = new int [50000 ]; Arrays.fill(firstAppearIndex, -1 ); for (int i = 0 ; i < nums.length; i++) { if (firstAppearIndex[nums[i]] == -1 ) { firstAppearIndex[nums[i]] = i; } int temp = appearCount[nums[i]] + 1 ; appearCount[nums[i]]++; int len = i - firstAppearIndex[nums[i]] + 1 ; if (temp > maxAppearCount) { maxAppearCount = temp; result = len; } else if (temp == maxAppearCount) { result = Math.min(result, len); } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution { public boolean isOneBitCharacter (int [] bits) { int cur = 0 ; while (cur < bits.length){ if (bits[cur] == 0 ){ cur++; if (cur == bits.length){ return true ; } }else { cur+=2 ; } } return false ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { public int pivotIndex (int [] nums) { for (int i = 1 ; i < nums.length; i++) { nums[i] += nums[i - 1 ]; } for (int i = 0 ; i < nums.length; i++) { if (i == 0 ){ if (nums[nums.length-1 ] - nums[0 ] == 0 ){ return 0 ; } }else { if (nums[i-1 ] == nums[nums.length-1 ] - nums[i]){ return i; } } } return -1 ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution { public int minCostClimbingStairs (int [] cost) { int first = 0 , second = Math.min(cost[0 ], cost[1 ]); for (int i = 3 ; i <= cost.length; i++) { int t1 = second + cost[i - 1 ], t2 = first + cost[i - 2 ]; first = second; if (t1 < t2) { second = t1; } else { second = t2; } } return second; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution { public boolean isToeplitzMatrix (int [][] matrix) { for (int i = 1 ; i < matrix.length; i++) { for (int j = 1 ; j < matrix[0 ].length; j++) { if (matrix[i-1 ][j-1 ] !=matrix[i][j]){ return false ; } } } return true ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution { public int [][] flipAndInvertImage(int [][] image) { for (int [] ints : image) { int l = 0 , r = ints.length - 1 ; while (l <= r) { int temp = ints[l]; ints[l] = ints[r]; ints[r] = temp; if (ints[l] == 0 ) { ints[l] = 1 ; } else { ints[l] = 0 ; } if (l != r) { if (ints[r] == 0 ) { ints[r] = 1 ; } else { ints[r] = 0 ; } } l++; r--; } } return image; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import java.util.HashMap;import java.util.HashSet;class Solution { public int [] fairCandySwap(int [] aliceSizes, int [] bobSizes) { int sum1 = 0 , sum2 = 0 ; HashSet<Integer> set = new HashSet <>(); for (int i : aliceSizes) { sum1 += i; } for (int i : bobSizes) { sum2 += i; set.add(i); } int [] result = new int [2 ]; for (int i : aliceSizes) { int t = (sum2 - sum1 + 2 * i) / 2 ; if (set.contains(t)) { result[0 ] = i; result[1 ] = t; break ; } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution { public boolean isMonotonic (int [] nums) { if (nums.length == 1 ) { return true ; } else { int i = 1 ; while (i< nums.length && nums[i] <= nums[i-1 ]){ i++; } if (i == nums.length){ return true ; } i = 1 ; while (i< nums.length && nums[i] >= nums[i-1 ]){ i++; } if (i == nums.length){ return true ; } return false ; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Solution { public int [] sortedSquares(int [] nums) { int [] result = new int [nums.length]; int l = 0 , r = nums.length - 1 , t = r; while (l <= r) { int l1 = nums[l] * nums[l], r1 = nums[r] * nums[r]; if (l1 < r1) { result[t--] = r1; r--; } else { result[t--] = l1; l++; } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 import java.util.ArrayList;import java.util.Arrays;import java.util.HashMap;import java.util.List;class Solution { public List<String> commonChars (String[] words) { int [] curHash = new int [26 ], minHash = new int [26 ]; Arrays.fill(minHash, Integer.MAX_VALUE); for (int i = 0 ; i < words.length; i++) { for (int j = 0 ; j < words[i].length(); j++) { curHash[words[i].charAt(j) - 'a' ]++; } for (int j = 0 ; j < 26 ; j++) { minHash[j] = Math.min(minHash[j], curHash[j]); curHash[j] = 0 ; } } List<String> result = new ArrayList <>(); for (int i = 0 ; i < 26 ; i++) { for (int j = 0 ; j < minHash[i]; j++) { result.add(String.valueOf((char ) ('a' + i))); } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { public int heightChecker (int [] heights) { int [] sortList = new int [101 ]; for (int height : heights) { sortList[height]++; } int result = 0 , curIndex = 0 ; for (int i = 1 ; i <= 100 ; i++) { int cur = sortList[i]; while (cur > 0 ) { if (heights[curIndex] != i) { result++; } curIndex++; cur--; } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import java.util.Arrays;class Solution { public int heightChecker (int [] heights) { int [] t = new int [heights.length]; for (int i = 0 ; i < heights.length; i++) { t[i] = heights[i]; } Arrays.sort(t); int result = 0 ; for (int i = 0 ; i < heights.length; i++) { if (t[i] != heights[i]){ result++; } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 class Solution { public void duplicateZeros (int [] arr) { int curLen = 0 , len = arr.length, i = 0 ; while (curLen < len) { if (arr[i] == 0 ) { curLen += 2 ; } else { curLen++; } if (curLen < len) { i++; } } if (curLen > len) { arr[len - 1 ] = 0 ; curLen -= 3 ; i--; } else { curLen--; } while (i >= 0 ) { if (arr[i] == 0 ) { arr[curLen--] = 0 ; arr[curLen--] = 0 ; } else { arr[curLen--] = arr[i]; } i--; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public int numEquivDominoPairs (int [][] dominoes) { int [] hash = new int [100 ]; int result = 0 ; for (int [] dominoe : dominoes) { int i = dominoe[0 ] * 10 + dominoe[1 ], j = dominoe[1 ] * 10 + dominoe[0 ]; result += (i == j ? hash[i] : hash[i] + hash[j]); hash[i]++; } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Solution { public int countCharacters (String[] words, String chars) { int [] hash = new int [26 ], temp = new int [26 ]; for (int i = 0 ; i < chars.length(); i++) { hash[chars.charAt(i) - 'a' ]++; temp[chars.charAt(i) - 'a' ]++; } int result = 0 ; for (String s : words) { for (int i = 0 ; i < 26 ; i++) { hash[i] = temp[i]; } boolean isLegal = true ; for (int i = 0 ; i < s.length(); i++) { hash[s.charAt(i) - 'a' ]--; if (hash[s.charAt(i) - 'a' ] < 0 ) { isLegal = false ; break ; } } if (isLegal) { result += s.length(); } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 class Solution { public int [] numSmallerByFrequency(String[] queries, String[] words) { int [] result = new int [queries.length]; int [] wHash = new int [words.length]; for (int i = 0 ; i < words.length; i++) { int [] hash = new int [26 ]; for (char c : words[i].toCharArray()) { hash[c - 'a' ]++; } for (int j = 0 ; j < 26 ; j++) { if (hash[j] != 0 ) { wHash[i] = hash[j]; break ; } } } for (int i = 0 ; i < queries.length; i++) { int [] hash = new int [26 ]; for (char c : queries[i].toCharArray()) { hash[c - 'a' ]++; } for (int j = 0 ; j < 26 ; j++) { if (hash[j] != 0 ) { for (int w : wHash) { if (hash[j] < w) { result[i]++; } } break ; } } } return result; } }
优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Solution { public int [] numSmallerByFrequency(String[] queries, String[] words) { int [] count = new int [12 ]; for (String s : words) { count[f(s)]++; } for (int i = 9 ; i >= 1 ; i--) { count[i] += count[i + 1 ]; } int [] result = new int [queries.length]; for (int i = 0 ; i < queries.length; i++) { result[i] = count[f(queries[i]) + 1 ]; } return result; } public int f (String s) { int t = 0 ; char min = 'z' ; for (char c : s.toCharArray()) { if (c < min) { min = c; t = 1 ; } else if (c == min) { t++; } } return t; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public int distanceBetweenBusStops (int [] distance, int start, int destination) { int temp1 = 0 , temp2 = 0 , i = start, j = start, n = distance.length; while (i != destination) { temp1 += distance[i]; i = (i + 1 ) % n; } while (j != destination) { int last = (j - 1 + n) % n; temp2 += distance[last]; j = last; } return Math.min(temp1, temp2); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public int distanceBetweenBusStops (int [] distance, int start, int destination) { int temp = 0 , n = distance.length, sum = 0 ; for (int d : distance) { sum += d; } while (start != destination) { temp += distance[start]; start = (start + 1 ) % n; } return Math.min(temp, sum - temp); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 class Solution { public String dayOfTheWeek (int day, int month, int year) { int needDays = 0 ; for (int i = 1971 ; i < year; i++) { needDays += isLeapYear(i) ? 366 : 365 ; } for (int i = 1 ; i < month; i++) { needDays += getMonthDays(i, year); } needDays += day - 1 ; return getResult(needDays % 7 ); } public boolean isLeapYear (int year) { return (year % 4 == 0 && year % 100 != 0 ) || (year % 400 == 0 ); } public int getMonthDays (int month, int year) { if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 ) { return 31 ; } else if (month == 2 ) { return isLeapYear(year) ? 29 : 28 ; } else { return 30 ; } } public String getResult (int day) { switch (day) { case 0 : return "Friday" ; case 1 : return "Saturday" ; case 2 : return "Sunday" ; case 3 : return "Monday" ; case 4 : return "Tuesday" ; case 5 : return "Wednesday" ; case 6 : return "Thursday" ; default : return "" ; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public int minCostToMoveChips (int [] position) { int odd = 0 ; for (int i : position) { if (i % 2 != 0 ) { odd++; } } return Math.min(odd, position.length - odd); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public boolean checkStraightLine (int [][] coordinates) { double k = 0 , b = 0 ; if (coordinates[0 ][0 ] != coordinates[1 ][0 ] && coordinates[0 ][1 ] != coordinates[1 ][1 ]) { k = (double ) (coordinates[1 ][1 ] - coordinates[0 ][1 ]) / (coordinates[1 ][0 ] - coordinates[0 ][0 ]); b = coordinates[0 ][1 ] - k * coordinates[0 ][0 ]; } for (int i = 2 ; i < coordinates.length; i++) { if (coordinates[0 ][0 ] == coordinates[1 ][0 ]) { if (coordinates[0 ][0 ] != coordinates[i][0 ]) { return false ; } } else if (coordinates[0 ][1 ] == coordinates[1 ][1 ]) { if (coordinates[0 ][1 ] != coordinates[i][1 ]) { return false ; } } else { if (coordinates[i][1 ] != k * coordinates[i][0 ] + b) { return false ; } } } return true ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 class Solution { public List<List<Integer>> shiftGrid (int [][] grid, int k) { int m = grid.length, n = grid[0 ].length; for (int i = 0 ; i < k; i++) { int [] t = new int [m]; for (int j = 0 ; j < m; j++) { t[j] = grid[j][n - 1 ]; } for (int j = 0 ; j < m; j++) { for (int z = n - 2 ; z >= 0 ; z--) { grid[j][z + 1 ] = grid[j][z]; } } int temp = t[m - 1 ]; for (int j = m - 2 ; j >= 0 ; j--) { t[j + 1 ] = t[j]; } t[0 ] = temp; for (int j = 0 ; j < m; j++) { grid[j][0 ] = t[j]; } } List<List<Integer>> result = new ArrayList <>(); for (int [] t : grid) { List<Integer> temp = new ArrayList <>(); for (int i : t) { temp.add(i); } result.add(temp); } return result; } }
TODO 优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { public int minTimeToVisitAllPoints (int [][] points) { int result = 0 ; int [] last = points[0 ]; for (int i = 1 ; i < points.length; i++) { int [] temp = points[i]; if (temp[0 ] == last[0 ]) { result += Math.abs(temp[1 ] - last[1 ]); } else if (temp[1 ] == last[1 ]) { result += Math.abs(temp[0 ] - last[0 ]); } else { result += Math.max(Math.abs(temp[0 ] - last[0 ]), Math.abs(temp[1 ] - last[1 ])); } last = temp; } return result; } }
压缩思路,简化代码
1 2 3 4 5 6 7 8 9 10 class Solution { public int minTimeToVisitAllPoints (int [][] points) { int result = 0 ; for (int i = 1 ; i < points.length; i++) { result += Math.max(Math.abs(points[i][0 ] - points[i - 1 ][0 ]), Math.abs(points[i][1 ] - points[i - 1 ][1 ])); } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class Solution { public String tictactoe (int [][] moves) { String[][] board = new String [3 ][3 ]; boolean isA = true ; for (int [] t : moves) { if (isA) { board[t[0 ]][t[1 ]] = "A" ; } else { board[t[0 ]][t[1 ]] = "B" ; } isA = !isA; } for (int i = 0 ; i < 3 ; i++) { if (board[i][0 ] != null && board[i][1 ] != null && board[i][2 ] != null && board[i][0 ].equals(board[i][1 ]) && board[i][0 ].equals(board[i][2 ])) { return board[i][0 ]; } } for (int j = 0 ; j < 3 ; j++) { if (board[0 ][j] != null && board[1 ][j] != null && board[2 ][j] != null && board[0 ][j].equals(board[1 ][j]) && board[0 ][j].equals(board[2 ][j])) { return board[0 ][j]; } } if (board[0 ][0 ] != null && board[1 ][1 ] != null && board[2 ][2 ] != null && board[0 ][0 ].equals(board[1 ][1 ]) && board[0 ][0 ].equals(board[2 ][2 ])) { return board[0 ][0 ]; } if (board[0 ][2 ] != null && board[1 ][1 ] != null && board[2 ][0 ] != null && board[0 ][2 ].equals(board[1 ][1 ]) && board[0 ][2 ].equals(board[2 ][0 ])) { return board[0 ][2 ]; } return moves.length == 9 ? "Draw" : "Pending" ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution { public int findSpecialInteger (int [] arr) { int [] hash = new int [100001 ]; int len = arr.length / 4 ; for (int i : arr) { hash[i]++; } for (int i = 0 ; i < hash.length; i++) { if (hash[i] > len) { return i; } } return -1 ; } }
上面没思路随便写的,下面优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Solution { public int findSpecialInteger (int [] arr) { int threshold = arr.length / 4 , temp = 0 , lastVal = -1 ; for (int i = 0 ; i < arr.length; i++) { if (arr[i] == lastVal) { temp++; } else { temp = 1 ; lastVal = arr[i]; } if (temp > threshold) { break ; } } return lastVal; } }
更优秀思路,由于已经非递减有序了,所以只需要判断 arr[i] == arr[i+n/4] 是否相等即可,也就是连续的长度超过1/4长度才满足该条件
1 2 3 4 5 6 7 8 9 10 11 class Solution { public int findSpecialInteger (int [] arr) { int len = arr.length; for (int i = 0 ; i < len - len / 4 ; i++) { if (arr[i] == arr[i + len / 4 ]) { return arr[i]; } } return -1 ; } }
1 2 3 4 5 6 7 8 9 10 11 12 class Solution { public int findNumbers (int [] nums) { int result = 0 ; for (int num : nums) { if ((num >= 10 && num < 100 ) || (num >= 1000 && num < 10000 ) || (num >= 100000 && num < 1000000 )) { result++; } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public int [] replaceElements(int [] arr) { int max = -1 ; for (int i = arr.length - 1 ; i >= 0 ; i--) { int t = arr[i]; arr[i] = max; if (t > max) { max = t; } } return arr; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public int [] sumZero(int n) { int [] result = new int [n]; int start = n % 2 == 0 ? 1 : 0 , t = 0 ; if (start == 0 ) { result[t++] = 0 ; start++; } while (t < n - 1 ) { result[t++] = start; result[t++] = -start; start++; } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution { public boolean canReach (int [] arr, int start) { boolean [] isVisited = new boolean [arr.length]; return isLegal(arr, isVisited, start); } public boolean isLegal (int [] arr, boolean [] isVisited, int cur) { if (arr[cur] == 0 ) { return true ; } int i = cur - arr[cur], j = cur + arr[cur]; boolean result = false ; if (i >= 0 && !isVisited[i]) { isVisited[i] = true ; result = result || isLegal(arr, isVisited, i); } if (result) { return result; } if (j < arr.length && !isVisited[j]) { isVisited[j] = true ; result = result || isLegal(arr, isVisited, j); } return result; } }
1 2 3 4 5 6 7 8 9 10 11 class Solution { public boolean canReach (int [] arr, int start) { if (start >= 0 && start < arr.length && arr[start] < arr.length) { int t = arr[start]; arr[start] += arr.length; return t == 0 || canReach(arr, start - t) || canReach(arr, start + t); } return false ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public int [] decompressRLElist(int [] nums) { List<Integer> result = new ArrayList <>(); int index = 0 ; for (int i = 0 ; i < nums.length; i += 2 ) { int t = i + 1 ; for (int j = 0 ; j < nums[i]; j++) { result.add(nums[t]); } } int [] arr = new int [result.size()]; for (int i = 0 ; i < result.size(); i++) { arr[i] = result.get(i); } return arr; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution { public int [] getNoZeroIntegers(int n) { int [] result = new int [2 ]; for (int i = 1 ; i <= n / 2 ; i++) { if (!isHaveZero(i) && !isHaveZero(n - i)) { result[0 ] = i; result[1 ] = n - i; break ; } } return result; } public boolean isHaveZero (int n) { while (n != 0 ) { if (n % 10 == 0 ) { return true ; } n /= 10 ; } return false ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 class Solution { public List<Integer> luckyNumbers (int [][] matrix) { List<Integer> result = new ArrayList <>(); int m = matrix.length, n = matrix[0 ].length; int [] min = new int [m]; for (int i = 0 ; i < m; i++) { int t = 0 ; for (int j = 1 ; j < n; j++) { if (matrix[i][j] < matrix[i][t]) { t = j; } } min[i] = t; } int [] max = new int [n]; for (int j = 0 ; j < n; j++) { int t = 0 ; for (int i = 1 ; i < m; i++) { if (matrix[i][j] > matrix[t][j]) { t = i; } } max[j] = t; } for (int i = 0 ; i < m; i++) { if (max[min[i]] == i) { result.add(matrix[i][min[i]]); } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution { public List<Integer> luckyNumbers (int [][] matrix) { List<Integer> result = new LinkedList <>(); int m = matrix.length, n = matrix[0 ].length; for (int i = 0 ; i < m; i++) { int t = 0 ; for (int j = 1 ; j < n; j++) { if (matrix[i][j] < matrix[i][t]) { t = j; } } int p = 0 ; for (int i1 = 1 ; i1 < m; i1++) { if (matrix[i1][t] > matrix[p][t]) { p = i1; } } if (p == i) { result.add(matrix[i][t]); } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import java.util.Arrays;class Solution { public int findTheDistanceValue (int [] arr1, int [] arr2, int d) { int result = 0 ; for (int arr1Num : arr1) { boolean isLegal = true ; for (int arr2Num : arr2) { if (Math.abs(arr1Num - arr2Num) <= d) { isLegal = false ; break ; } } if (isLegal) { result++; } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Solution { public int [] createTargetArray(int [] nums, int [] index) { int [] target = new int [nums.length]; Arrays.fill(target, -1 ); for (int i = 0 ; i < nums.length; i++) { if (target[index[i]] != -1 ) { for (int j = i; j > index[i]; j--) { target[j] = target[j - 1 ]; } } target[index[i]] = nums[i]; } return target; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Solution { public int maxProduct (int [] nums) { int [] tempNums = new int [1001 ]; for (int num : nums) { tempNums[num]++; } int first = 0 , second = 0 ; for (int i = 1000 ; i >= 1 ; i--) { if (tempNums[i] != 0 ) { if (first == 0 ) { first = i; tempNums[i]--; } else if (second == 0 ) { second = i; break ; } } if (tempNums[i] != 0 ) { if (second == 0 ) { second = i; break ; } } } return (first - 1 ) * (second - 1 ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public int maxProduct (int [] nums) { int max1 = 0 , max2 = 0 ; for (int num : nums) { if (num >= max1) { max2 = max1; max1 = num; } else if (num < max1 && num > max2) { max2 = num; } } return (max1 - 1 ) * (max2 - 1 ); } }
1 2 3 4 5 6 7 8 9 10 11 12 class Solution { public int [] shuffle(int [] nums, int n) { int [] result = new int [nums.length]; int t = 0 ; for (int i = 0 ; i < n; i++) { result[t++] = nums[i]; result[t++] = nums[i + n]; } return result; } }
字符串 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution { public int romanToInt (String s) { HashMap<Character, Integer> map = new HashMap <>(); map.put('I' , 1 ); map.put('V' , 5 ); map.put('X' , 10 ); map.put('L' , 50 ); map.put('C' , 100 ); map.put('D' , 500 ); map.put('M' , 1000 ); int result = 0 ; for (int i = 0 ; i < s.length(); i++) { int cur = map.get(s.charAt(i)); if (i + 1 < s.length()) { int temp = map.get(s.charAt(i + 1 )); if (cur < temp) { result -= cur; } else { result += cur; } } else { result += cur; } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Solution { public int strStr (String haystack, String needle) { int len = needle.length(); int [] next = new int [len]; next[0 ] = 0 ; int j = 0 ; for (int i = 1 ; i < len; i++) { while (j > 0 && needle.charAt(i) != needle.charAt(j)) { j = next[j - 1 ]; } if (needle.charAt(i) == needle.charAt(j)) { j++; } next[i] = j; } int p = 0 ; for (int s = 0 ; s < haystack.length(); s++) { while (p > 0 && needle.charAt(p) != haystack.charAt(s)) { p = next[p - 1 ]; } if (needle.charAt(p) == haystack.charAt(s)) { p++; } if (p == len) { return s - len + 1 ; } } return -1 ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 class Solution { public String addBinary (String a, String b) { int len1 = a.length(), len2 = b.length(); int [] result = new int [Math.max(len1, len2) + 1 ]; int t = 0 , i = len1 - 1 , j = len2 - 1 , index = result.length - 1 ; while (i >= 0 && j >= 0 ) { int temp = t + (int ) (a.charAt(i) - '0' ) + (int ) (b.charAt(j) - '0' ); t = temp / 2 ; result[inde x] = temp % 2 ; i--; j--; index--; } while (i >= 0 ) { int temp = t + (int ) (a.charAt(i) - '0' ); t = temp / 2 ; result[index] = temp % 2 ; i--; index--; } while (j >= 0 ) { int temp = t + (int ) (b.charAt(j) - '0' ); t = temp / 2 ; result[index] = temp % 2 ; j--; index--; } if (t != 0 ) { result[index] = t; index--; } StringBuilder builder = new StringBuilder (); for (t = index + 1 ; t < result.length; t++) { builder.append(String.valueOf(result[t])); } return builder.toString(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class Solution { public boolean isPalindrome (String s) { int start = 0 , end = s.length() - 1 ; while (start < end) { while (start < end && !isLetter(s.charAt(start))) { start++; } while (start < end && !isLetter(s.charAt(end))) { end--; } if (start < end && !isLegal(s.charAt(start), s.charAt(end))) { return false ; } start++; end--; } return true ; } public boolean isLetter (char c) { return (c >= 'a' && c <= 'z' ) || (c >= 'A' && c <= 'Z' ) || (c >= '0' && c <= '9' ); } public boolean isLegal (char c1, char c2) { if (c1 >= '0' && c1 <= '9' && c2 >= '0' && c2 <= '9' ) { return c1 == c2; } else if (((c1 >= 'a' && c1 <= 'z' ) || (c1 >= 'A' && c1 <= 'Z' )) && ((c2 >= 'a' && c2 <= 'z' ) || (c2 >= 'A' && c2 <= 'Z' ))) { if (c1 >= 'A' && c1 <= 'Z' ) { c1 = (char ) ((int ) c1 - (int ) ('A' ) + (int ) ('a' )); } if (c2 >= 'A' && c2 <= 'Z' ) { c2 = (char ) ((int ) c2 - (int ) ('A' ) + (int ) ('a' )); } return c1 == c2; } return false ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { public boolean isIsomorphic (String s, String t) { HashMap<Character, Character> map = new HashMap <>(); HashSet<Character> set = new HashSet <>(); for (int i = 0 ; i < s.length(); i++) { if (map.containsKey(s.charAt(i))) { if (map.get(s.charAt(i)) != t.charAt(i)) { return false ; } } else { if (set.contains(t.charAt(i))) { return false ; } map.put(s.charAt(i), t.charAt(i)); } set.add(t.charAt(i)); } return true ; } }
前面发现单向映射出错,那其实调用两次就行,如果正反向都能映射肯定没问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { public boolean isIsomorphic (String s, String t) { return isIsomorphic1(s, t) && isIsomorphic1(t, s); } public boolean isIsomorphic1 (String s, String t) { HashMap<Character, Character> map = new HashMap <>(); for (int i = 0 ; i < s.length(); i++) { if (map.containsKey(s.charAt(i))) { if (map.get(s.charAt(i)) != t.charAt(i)) { return false ; } } else { map.put(s.charAt(i), t.charAt(i)); } } return true ; } }
1 2 3 4 5 6 7 8 9 10 class Solution { public void reverseString (char [] s) { int left = 0 , right = s.length - 1 ; while (left < right) { char c = s[left]; s[left++] = s[right]; s[right--] = c; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution { public String reverseVowels (String s) { char [] temp = s.toCharArray(); int left = 0 , right = temp.length - 1 ; while (left < right) { while (left < right && !isLegal(temp[left])) { left++; } while (left < right && !isLegal(temp[right])) { right--; } if (left < right) { char t = temp[left]; temp[left++] = temp[right]; temp[right--] = t; } } return new String (temp); } public boolean isLegal (char c) { return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U' ; } }
根据简单题目给定的范围取巧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution { public int firstUniqChar (String s) { int [] t = new int [26 ]; Arrays.fill(t, -1 ); for (int i = s.length() - 1 ; i >= 0 ; i--) { int index = (int ) (s.charAt(i) - 'a' ); if (t[index] == -1 ) { t[index] = i; } else { t[index] = s.length(); } } int result = -1 ; for (int i = 0 ; i < 26 ; i++) { if (t[i] != -1 && t[i] != s.length()) { if (result != -1 ) { result = Math.min(result, t[i]); } else { result = t[i]; } } } return result; } }
正常思路
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public int firstUniqChar (String s) { int [] t = new int [26 ]; for (int i = 0 ; i < s.length(); i++) { t[(int ) (s.charAt(i) - 'a' )]++; } for (int i = 0 ; i < s.length(); i++) { if (t[(int ) (s.charAt(i) - 'a' )] == 1 ) { return i; } } return -1 ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution { public int longestPalindrome (String s) { int result = 0 ; int [] t1 = new int [26 ], t2 = new int [26 ]; boolean isHave = false ; for (int i = 0 ; i < s.length(); i++) { char c = s.charAt(i); if (c >= 'a' && c <= 'z' ) { t1[c - 'a' ]++; } else { t2[c - 'A' ]++; } } for (int i = 0 ; i < 26 ; i++) { if (t1[i] % 2 == 0 ) { result += t1[i]; } else { result += (t1[i] - 1 ); isHave = true ; } if (t2[i] % 2 == 0 ) { result += t2[i]; } else { result += (t2[i] - 1 ); isHave = true ; } } return isHave ? result + 1 : result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Solution { public List<String> fizzBuzz (int n) { List<String> result = new ArrayList <>(); String s1 = "FizzBuzz" , s2 = "Fizz" , s3 = "Buzz" ; for (int i = 1 ; i <= n; i++) { if (i % 3 == 0 && i % 5 == 0 ) { result.add(s1); } else if (i % 3 == 0 ) { result.add(s2); } else if (i % 5 == 0 ) { result.add(s3); } else { result.add(String.valueOf(i)); } } return result; } }
暴力解决
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public boolean repeatedSubstringPattern (String s) { int len = s.length(); for (int i = 1 ; i * 2 <= len; i++) { if (len % i == 0 ) { boolean isCurrent = true ; for (int j = i; j < len; j++) { if (s.charAt(j) != s.charAt(j - i)) { isCurrent = false ; break ; } } if (isCurrent) { return true ; } } } return false ; } }
移动匹配(字符串匹配)
借助系统函数,不用系统函数就去掉头尾然后判断s是否在s+s中,因为不去掉搜索会搜到s+s最开始的s,没什么意义
1 2 3 4 5 6 class Solution { public boolean repeatedSubstringPattern (String s) { return (s + s).indexOf(s, 1 ) != s.length(); } }
KMP
前缀表:当出现两个位置的字符不相等的时候,需要找到当前不相等位置的前面的所有字符的后缀的相等前缀的后一个字符进行匹配,那么就要知道某个字符串的最长相等前后缀(前后缀可以有多个)
前缀:包含首字母,不包含尾字母的所有子串
后缀:包含尾字母,不包含首字母的所有子串
最长相等前后缀:aabaa,最长就是2呗,aa和aa相等(长度刚好就是下次匹配的下标,很巧妙),前缀表在最后个a位置记录2,从2位置继续匹配(这里前缀表不进行任何偏移)
next数组、prefix数组:其实存放的都是前缀表,但代码实现上可能有些区别罢了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution { public boolean repeatedSubstringPattern (String s) { int len = s.length(); int [] next = new int [len]; int j = 0 ; next[0 ] = 0 ; for (int i = 1 ; i < len; i++) { while (j > 0 && s.charAt(i) != s.charAt(j)) { j = next[j - 1 ]; } if (s.charAt(i) == s.charAt(j)) { j++; } next[i] = j; } if (next[len - 1 ] > 0 && len % (len - next[len - 1 ]) == 0 ) { return true ; } else { return false ; } } }
为什么需要减去,减的部分可以按下面这个理解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 class Solution { public String[] findWords(String[] words) { List<String> temp = new ArrayList <>(); HashSet<Character> set1 = new HashSet <>(); getHashSet(set1, "qwertyuiopQWERTYUIOP" ); HashSet<Character> set2 = new HashSet <>(); getHashSet(set2, "asdfghjklASDFGHJKL" ); HashSet<Character> set3 = new HashSet <>(); getHashSet(set3, "zxcvbnmZXCVBNM" ); for (String word : words) { int t = 0 ; if (set1.contains(word.charAt(0 ))) { t = 0 ; } else if (set2.contains(word.charAt(0 ))) { t = 1 ; } else { t = 2 ; } boolean isLegal = true ; for (int i = 1 ; i < word.length(); i++) { if (t == 0 ) { if (!set1.contains(word.charAt(i))) { isLegal = false ; break ; } } else if (t == 1 ) { if (!set2.contains(word.charAt(i))) { isLegal = false ; break ; } } else { if (!set3.contains(word.charAt(i))) { isLegal = false ; break ; } } } if (isLegal) { temp.add(word); } } String[] result = new String [temp.size()]; int t = 0 ; for (String s : temp) { result[t++] = s; } return result; } public void getHashSet (HashSet<Character> set, String str) { for (int i = 0 ; i < str.length(); i++) { set.add(str.charAt(i)); } } }
优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Solution { public String[] findWords(String[] words) { int [] hash = new int [26 ]; String[] ss = new String [] { "qwertyuiop" , "asdfghjkl" , "zxcvbnm" }; for (int j = 0 ; j < ss.length; j++) { String s = ss[j]; for (int i = 0 ; i < s.length(); i++) { hash[s.charAt(i) - 'a' ] = j; } } List<String> temp = new ArrayList <>(); outer: for (String s : words) { int t = -1 ; for (int i = 0 ; i < s.length(); i++) { char c = Character.toLowerCase(s.charAt(i)); if (t == -1 ) { t = hash[c - 'a' ]; } else if (t != hash[c - 'a' ]) { continue outer; } } temp.add(s); } return temp.toArray(new String [temp.size()]); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Solution { public String reverseStr (String s, int k) { char [] temp = s.toCharArray(); int step = 2 * k; int t = temp.length / step; for (int i = 0 ; i < t; i++) { reverse(temp, i * step, i * step + k - 1 ); } int balance = temp.length - t * step; if (balance < k) { reverse(temp, t * step, temp.length - 1 ); } else { reverse(temp, t * step, t * step + k - 1 ); } return new String (temp); } public void reverse (char [] temp, int start, int end) { while (start < end) { char c = temp[start]; temp[start] = temp[end]; temp[end] = c; start++; end--; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 class Solution { public String shortestCompletingWord (String licensePlate, String[] words) { int min = Integer.MAX_VALUE; String result = "" ; int [] hash = getHash(licensePlate); for (String s : words) { int [] temp = getHash(s); int i = 0 ; while (i < 26 ) { if (temp[i] < hash[i]) { break ; } i++; } if (i == 26 && s.length() < min) { min = s.length(); result = s; } } return result; } public int [] getHash(String s) { int [] hash = new int [26 ]; for (int i = 0 ; i < s.length(); i++) { char c = s.charAt(i); if ((c >= 'a' && c <= 'z' ) || (c >= 'A' && c <= 'Z' )) { hash[Character.toLowerCase(c) - 'a' ]++; } } return hash; } }
也可以用HashSet,也可以用内置方法看是否在String是否存在某个元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution { public int numJewelsInStones (String jewels, String stones) { int [] smallLetter = new int [26 ], bigLetter = new int [26 ]; for (int i = 0 ; i < jewels.length(); i++) { char c = jewels.charAt(i); if (c >= 'a' && c <= 'z' ) { smallLetter[c - 'a' ]++; } else { bigLetter[c - 'A' ]++; } } int count = 0 ; for (int i = 0 ; i < stones.length(); i++) { char c = stones.charAt(i); if (c >= 'a' && c <= 'z' ) { if (smallLetter[c - 'a' ] != 0 ) { count++; } } else { if (bigLetter[c - 'A' ] != 0 ) { count++; } } } return count; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 class Solution { public String mostCommonWord (String paragraph, String[] banned) { paragraph = transToLower(paragraph); for (int i = 0 ; i < banned.length; i++) { banned[i] = transToLower(banned[i]); } HashMap<String, Integer> map = new HashMap <>(); int l = 0 , r = 0 ; while (l < paragraph.length()) { while (l < paragraph.length() && !isLetter(paragraph.charAt(l))) { l++; } if (l >= paragraph.length()) { break ; } r = l; while (r < paragraph.length() && isLetter(paragraph.charAt(r))) { r++; } String word = paragraph.substring(l, r); word = transToLower(word); map.put(word, map.getOrDefault(word, 0 ) + 1 ); l = r; } String result = "" ; int max = 0 ; for (String s : banned) { if (map.containsKey(s)) { map.put(s, 0 ); } } for (Map.Entry<String, Integer> entry : map.entrySet()) { if (entry.getValue() > max) { result = entry.getKey(); max = entry.getValue(); } } return result; } public String transToLower (String word) { char [] temp = word.toCharArray(); for (int i = 0 ; i < temp.length; i++) { if (temp[i] >= 'A' && temp[i] <= 'Z' ) { temp[i] = Character.toLowerCase(temp[i]); } } return new String (temp); } public boolean isLetter (char c) { return ((c >= 'a' ) && (c <= 'z' )) || ((c > 'A' ) && (c <= 'Z' )); } }
待优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution { public boolean isLongPressedName (String name, String typed) { int j = 0 ; for (int i = 0 ; i < name.length(); i++) { if (i != 0 && name.charAt(i) != name.charAt(i - 1 )) { while (j < typed.length() && typed.charAt(j) == typed.charAt(j - 1 )) { j++; } } if (j >= typed.length() || name.charAt(i) != typed.charAt(j)) { return false ; } j++; } while (j < typed.length()) { if (typed.charAt(j) != typed.charAt(j - 1 )) { return false ; } j++; } return true ; } }
待优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public int [] diStringMatch(String s) { int [] reuslt = new int [s.length() + 1 ]; int maxNum = s.length(), minNum = 0 , index = 0 ; for (int i = 0 ; i < s.length(); i++) { if (s.charAt(i) == 'I' ) { reuslt[index++] = minNum; minNum++; } else { reuslt[index++] = maxNum; maxNum--; } } reuslt[index] = minNum; return reuslt; } }
待优化,待思考
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution { public String[] findOcurrences(String text, String first, String second) { List<String> result = new ArrayList <>(); String lastFirst = "" , lastSecond = "" , lastThird = "" ; int len = text.length(), left = 0 , right = 0 , flag = 0 ; while (left < len) { while (right < len && text.charAt(right) != ' ' ) { right++; } flag++; lastFirst = lastSecond; lastSecond = lastThird; lastThird = text.substring(left, right); left = right + 1 ; right = left; if (flag >= 3 ) { if (lastFirst.equals(first) && lastSecond.equals(second)) { result.add(lastThird); } } } return result.toArray(new String [0 ]); } }
系统方法优化
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution { public String[] findOcurrences(String text, String first, String second) { String[] temp = text.split(" " ); ArrayList<String> result = new ArrayList <>(); for (int i = 2 ; i < temp.length; i++) { if (temp[i - 2 ].equals(first) && temp[i - 1 ].equals(second)) { result.add(temp[i]); } } return result.toArray(new String [0 ]); } }
最基础的就是自己分割出来列表,然后跟下面一样操作,不写了,直接系统方法了
!!!注意转义,因为传入的是正则,单个点代表任意字符了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public String defangIPaddr (String address) { String[] temp = address.split("\\." ); StringBuilder builder = new StringBuilder (); for (int i = 0 ; i < temp.length; i++) { builder.append(temp[i]); if (i != temp.length - 1 ) { builder.append("[.]" ); } } return builder.toString(); } }
更简单的系统方法
1 2 3 4 5 class Solution { public String defangIPaddr (String address) { return address.replace("." , "[.]" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution { public int maxNumberOfBalloons (String text) { int [] hash = new int [26 ]; for (char c : text.toCharArray()) { hash[c - 'a' ]++; } int bNum = hash['b' - 'a' ], aNum = hash['a' - 'a' ], lNum = hash['l' - 'a' ] / 2 , oNum = hash['o' - 'a' ] / 2 , nNum = hash['n' - 'a' ]; return Math.min(nNum, Math.min(oNum, Math.min(lNum, Math.min(bNum, aNum)))); } }
避免重复代码也可以直接用2287. 重排字符形成目标字符串 的写法即可,类似题目
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public int balancedStringSplit (String s) { int result = 0 , lNum = 0 , rNum = 0 ; for (char c : s.toCharArray()) { if (c == 'L' ) { lNum++; } else { rNum++; } if (lNum == rNum) { result++; } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 class Solution { public int isPrefixOfWord (String sentence, String searchWord) { String[] s = sentence.split(" " ); for (int i = 0 ; i < s.length; i++) { if (s[i].startsWith(searchWord)) { return i + 1 ; } } return -1 ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { public int rearrangeCharacters (String s, String target) { int [] hash = new int [26 ]; for (char c : s.toCharArray()) { hash[c - 'a' ]++; } int [] targetHash = new int [26 ]; for (char c : target.toCharArray()) { targetHash[c - 'a' ]++; } int result = Integer.MAX_VALUE; for (int i = 0 ; i < 26 ; i++) { if (targetHash[i] != 0 ) { result = Math.min(result, hash[i] / targetHash[i]); } } return result == Integer.MAX_VALUE ? 0 : result; } }
滑动窗口和双指针 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { public int lengthOfLongestSubstring (String s) { if (s.length() == 0 ) { return 0 ; } HashMap<Character, Integer> map = new HashMap <>(); char [] chars = s.toCharArray(); int result = 0 , start = 0 ; for (int i = 0 ; i < s.length(); i++) { int t = map.getOrDefault(chars[i], -1 ); if (t >= 0 ) { result = Math.max(Math.min(i - t, i - start + 1 ), result); start = Math.max(start, t + 1 ); } else { result = Math.max(result, i - start + 1 ); } map.put(chars[i], i); } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 class Solution { public String minWindow (String s, String t) { int sLen = s.length(), tLen = t.length(); if (sLen < tLen) { return "" ; } HashMap<Character, Integer> map = new HashMap <>(); for (int i = 0 ; i < tLen; i++) { char c = t.charAt(i); map.put(c, map.getOrDefault(c, 0 ) + 1 ); } int l = 0 , r = sLen, lastL = 0 ; for (int i = 0 ; i < sLen; i++) { char c = s.charAt(i); if (map.containsKey(c)) { map.put(c, map.get(c) - 1 ); while (lastL <= i && isLegal(map)) { if (i - lastL < r - l) { l = lastL; r = i; } char cR = s.charAt(lastL); if (map.containsKey(cR)) { map.put(cR, map.get(cR) + 1 ); } lastL++; } } } return r == sLen ? "" : s.substring(l, r + 1 ); } public boolean isLegal (HashMap<Character, Integer> map) { for (Map.Entry<Character, Integer> entry : map.entrySet()) { if (map.getOrDefault(entry.getKey(), 0 ) > 0 ) { return false ; } } return true ; } }
优化,临时变量记录一下,不需要每次都遍历哈希,数组存哈希更快,一起优化了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 class Solution { public String minWindow (String s, String t) { int sLen = s.length(), tLen = t.length(); if (sLen < tLen) { return "" ; } int [] map = new int [58 ]; boolean [] isHave = new boolean [58 ]; int flag = tLen; for (int i = 0 ; i < tLen; i++) { int cIndex = t.charAt(i) - 'A' ; map[cIndex]++; isHave[cIndex] = true ; } int l = 0 , r = sLen, lastL = 0 ; for (int i = 0 ; i < sLen; i++) { int cIndex = s.charAt(i) - 'A' ; if (isHave[cIndex]) { int cNum = map[cIndex] - 1 ; if (cNum >= 0 ) { flag--; } map[cIndex] = cNum; if (cNum <= 0 ) { while (lastL <= i && flag <= 0 ) { if (i - lastL < r - l) { l = lastL; r = i; } int cRIndex = s.charAt(lastL) - 'A' ; if (isHave[cRIndex]) { int cRNum = map[cRIndex] + 1 ; if (cRNum > 0 ) { flag++; } map[cRIndex] = cRNum; } lastL++; } } } } return r == sLen ? "" : s.substring(l, r + 1 ); } }
经典单调栈题目,感觉还是想不出来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public int [] maxSlidingWindow(int [] nums, int k) { int len = nums.length, ansLen = len - k + 1 , t = 0 ; int [] ans = new int [ansLen]; LinkedList<Integer> list = new LinkedList <>(); for (int i = 0 ; i < len; i++) { int temp = i - k; while (!list.isEmpty() && list.peekFirst() <= temp) { list.pollFirst(); } while (!list.isEmpty() && nums[list.peekLast()] <= nums[i]) { list.pollLast(); } list.addLast(i); if (i >= k - 1 ) { ans[t++] = nums[list.peekFirst()]; } } return ans; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution { public int characterReplacement (String s, int k) { int len = s.length(), left = 0 , right = 0 , result = 0 , maxCount = 0 ; if (len < 2 ) { return len; } char [] chars = s.toCharArray(); int [] freq = new int [26 ]; while (right < len) { freq[chars[right] - 'A' ]++; maxCount = Math.max(maxCount, freq[chars[right] - 'A' ]); right++; if (right - left > maxCount + k) { freq[chars[left] - 'A' ]--; left++; } result = Math.max(result, right - left); } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 class Solution { public List<Integer> findAnagrams (String s, String p) { List<Integer> result = new ArrayList <>(); int [] hash = new int [26 ]; char [] s1 = s.toCharArray(), p1 = p.toCharArray(); for (char c : p1) { hash[c - 'a' ]++; } int left = -1 , right = 0 ; hash[s1[right] - 'a' ]--; while (right < s1.length) { while (right + 1 < s1.length && right - left < p1.length) { right++; hash[s1[right] - 'a' ]--; } if (right - left < p1.length) { break ; } boolean flag = true ; for (int num : hash) { if (num != 0 ) { flag = false ; break ; } } if (flag) { result.add(left + 1 ); } left++; hash[s1[left] - 'a' ]++; } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 class Solution { public boolean checkInclusion (String s1, String s2) { int [] hash = new int [26 ]; int len1 = s1.length(), len2 = s2.length(); for (int i = 0 ; i < len1; i++) { hash[s1.charAt(i) - 'a' ]++; } int left = 0 , right = 0 ; while (right <= len2) { if (len2 - left < len1) { break ; } while (right < len2 && right - left < len1) { hash[s2.charAt(right) - 'a' ]--; right++; } boolean flag = true ; for (int num : hash) { if (num != 0 ) { flag = false ; break ; } } if (flag) { return true ; } hash[s2.charAt(left) - 'a' ]++; left++; } return false ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { public int longestMountain (int [] arr) { int result = 0 , len = arr.length; for (int i = 0 ; i < len; i++) { int l = i - 1 , r = i + 1 ; while (l >= 0 && arr[l] < arr[l + 1 ]) { l--; } while (r < len && arr[r] < arr[r - 1 ]) { r++; } if (l != i - 1 && r != i + 1 ) { result = Math.max(result, r - 1 - l); } } return result; } }
尝试贪心优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution { public int longestMountain (int [] arr) { int lastUp = -1 ; int i = 1 , result = 0 ; while (i < arr.length) { if (arr[i] < arr[i - 1 ]) { boolean isHaveUp = lastUp != -1 && lastUp < i - 1 ; while (i < arr.length && arr[i] < arr[i - 1 ]) { i++; } if (isHaveUp) { result = Math.max(result, i - lastUp); } } else if (arr[i] > arr[i - 1 ]) { lastUp = i - 1 ; while (i < arr.length && arr[i] > arr[i - 1 ]) { i++; } } else { while (i < arr.length && arr[i] == arr[i - 1 ]) { i++; } lastUp = i - 1 ; } } return result; } }
简化代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution { public int longestMountain (int [] arr) { int lastUp = -1 , lastDown = 0 , result = 0 ; for (int i = 1 ; i < arr.length; i++) { if (arr[i] > arr[i - 1 ]) { if (lastUp < lastDown) { lastUp = i - 1 ; } } else if (arr[i] < arr[i - 1 ]) { lastDown = i; if (lastUp != -1 ) { result = Math.max(result, lastDown - lastUp + 1 ); } } else { lastUp = -1 ; } } return result; } }
用了官方给的答案跑也是On跟自己写的时间复杂度一样,不知道怎么做到的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution { public int totalFruit (int [] fruits) { int max = 0 , len = fruits.length, kinds = 0 , l = 0 ; int [] hash = new int [len]; for (int i = 0 ; i < len; i++) { int t = fruits[i]; if (hash[t] == 0 ) { hash[t]++; kinds++; if (kinds > 2 ) { while (l < i) { hash[fruits[l]]--; if (hash[fruits[l]] == 0 ) { l++; break ; } l++; } kinds--; } } else { hash[t]++; } max = Math.max(max, i - l + 1 ); } return max; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution { public int maxSatisfied (int [] customers, int [] grumpy, int minutes) { int max = 0 , n = customers.length; for (int i = 0 ; i < n; i++) { max += (grumpy[i] == 1 ? 0 : customers[i]); } int l = 0 , r = 0 ; while (r < minutes) { if (grumpy[r] == 1 ) { max += customers[r]; } r++; } int cur = max; while (r != n) { if (grumpy[l] == 1 ) { cur -= customers[l]; } l++; if (r != n && grumpy[r] == 1 ) { cur += customers[r]; } max = Math.max(max, cur); r++; } return max; } }
链表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 class Solution { public ListNode addTwoNumbers (ListNode l1, ListNode l2) { int carry = 0 ; ListNode head = new ListNode (), cur = head; while (l1 != null && l2 != null ) { int now = l1.val + l2.val + carry; carry = now / 10 ; now %= 10 ; l1.val = now; cur.next = l1; cur = l1; l1 = l1.next; l2 = l2.next; } while (l1 != null ) { int now = l1.val + carry; carry = now / 10 ; now %= 10 ; l1.val = now; cur.next = l1; cur = l1; l1 = l1.next; } while (l2 != null ) { int now = l2.val + carry; carry = now / 10 ; now %= 10 ; l2.val = now; cur.next = l2; cur = l2; l2 = l2.next; } if (carry != 0 ) { ListNode node = new ListNode (carry); cur.next = node; } return head.next; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution { public ListNode removeNthFromEnd (ListNode head, int n) { ListNode newHead = new ListNode (0 , head); ListNode cur = newHead, delete = newHead; for (int i = 0 ; i <= n; i++) { cur = cur.next; } while (cur != null ) { cur = cur.next; delete = delete.next; } ListNode next = delete.next; delete.next = next.next; next.next = null ; return newHead.next; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public ListNode mergeTwoLists (ListNode list1, ListNode list2) { ListNode head = new ListNode (), result = head; while (list1 != null && list2 != null ) { if (list1.val <= list2.val) { head.next = list1; head = list1; list1 = list1.next; } else { head.next = list2; head = list2; list2 = list2.next; } } if (list1 != null ) { head.next = list1; } if (list2 != null ) { head.next = list2; } return result.next; } }
一开始暴力的时间复杂度很高
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution { public ListNode mergeKLists (ListNode[] lists) { ListNode cur = new ListNode (), head = cur; while (true ) { int min = -1 ; for (int i = 0 ; i < lists.length; i++) { ListNode node = lists[i]; if (node == null ) { continue ; } if (min == -1 ) { min = i; } else { if (node.val < lists[min].val) { min = i; } } } if (min == -1 ) { cur.next = null ; break ; } cur.next = lists[min]; cur = lists[min]; lists[min] = lists[min].next; } return head.next; } }
优先队列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution { public ListNode mergeKLists (ListNode[] lists) { PriorityQueue<Integer> queue = new PriorityQueue <>( (Integer node1, Integer node2) -> { return lists[node1].val - lists[node2].val; }); for (int i = 0 ; i < lists.length; i++) { if (lists[i] != null ) { queue.offer(i); } } ListNode cur = new ListNode (), head = cur; while (!queue.isEmpty()) { int min = queue.poll(); ListNode minNode = lists[min]; cur.next = minNode; cur = minNode; lists[min] = minNode.next; if (lists[min] != null ) { queue.offer(min); } } return head.next; } }
归并两两合并
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 class Solution { public ListNode mergeKLists (ListNode[] lists) { return merge(lists, 0 , lists.length - 1 ); } public ListNode merge (ListNode[] lists, int l, int r) { if (l == r) { return lists[l]; } if (l > r) { return null ; } int mid = (l + r) >> 1 ; return mergeTwoLists( merge(lists, l, mid), merge(lists, mid + 1 , r)); } public ListNode mergeTwoLists (ListNode list1, ListNode list2) { ListNode head = new ListNode (), result = head; while (list1 != null && list2 != null ) { if (list1.val <= list2.val) { head.next = list1; head = list1; list1 = list1.next; } else { head.next = list2; head = list2; list2 = list2.next; } } if (list1 != null ) { head.next = list1; } if (list2 != null ) { head.next = list2; } return result.next; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public ListNode swapPairs (ListNode head) { ListNode cur = new ListNode (), result = cur; while (head != null ) { ListNode next = head.next; if (next != null ) { ListNode nextUp = next.next; cur.next = next; next.next = head; head.next = nextUp; cur = head; head = nextUp; } else { cur.next = head; head = null ; } } return result.next; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 class Solution { public ListNode reverseKGroup (ListNode head, int k) { int cur = 1 ; ListNode node = null ; List<ListNode> list = new ArrayList <>(); while (head != null ) { if (cur == 1 ) { node = head; } if (cur == k) { list.add(node); node = null ; ListNode next = head.next; head.next = null ; head = next; cur = 1 ; continue ; } head = head.next; cur++; } ListNode newHead = null , last = null ; for (int i = 0 ; i < list.size(); i++) { ListNode t = list.get(i); ListNode r = reverseSingle(t); if (last != null ) { last.next = r; } last = t; if (newHead == null ) { newHead = r; } } last.next = node; return newHead; } public ListNode reverseSingle (ListNode head) { ListNode last = null ; while (head != null ) { ListNode next = head.next; head.next = last; last = head; head = next; } return last; } }
无需额外空间优化,翻译一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 class Solution { public ListNode reverseKGroup (ListNode head, int k) { if (k == 1 ) { return head; } int cur = 1 ; ListNode node = null , newHead = null , last = null ; List<ListNode> list = new ArrayList <>(); while (head != null ) { if (cur == 1 ) { node = head; } if (cur == k) { ListNode next = head.next; head.next = null ; head = next; cur = 1 ; ListNode temp = reverseSingle(node); if (newHead == null ) { newHead = temp; } if (last != null ) { last.next = temp; } last = node; node = null ; continue ; } head = head.next; cur++; } last.next = node; return newHead; } public ListNode reverseSingle (ListNode head) { ListNode last = null ; while (head != null ) { ListNode next = head.next; head.next = last; last = head; head = next; } return last; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 class Solution { public ListNode rotateRight (ListNode head, int k) { if (head == null ) { return head; } ListNode newHead = new ListNode (-1 , head); int count = 0 ; ListNode node = head, tail = head; while (node != null ) { node = node.next; if (tail.next != null ) { tail = tail.next; } count++; } int n = k % count, t = count - n; if (n == 0 ) { return newHead.next; } node = head; count = 1 ; while (count < t) { node = node.next; count++; } newHead.next = node.next; node.next = null ; tail.next = head; return newHead.next; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution { public ListNode deleteDuplicates (ListNode head) { if (head == null || head.next == null ) { return head; } ListNode newHead = new ListNode (), first = head, second = head.next, result = newHead; while (first != null ) { if (second == null || second.val != first.val) { newHead.next = first; newHead = newHead.next; } else { while (second != null && second.val == first.val) { second = second.next; } } if (second == null ) { break ; } else { first = second; second = second.next; } } newHead.next = null ; return result.next; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { public ListNode deleteDuplicates (ListNode head) { if (head == null || head.next == null ) { return head; } ListNode last = head, cur = head.next; while (cur != null ) { if (cur.val == last.val) { cur = cur.next; continue ; } last.next = cur; cur = cur.next; last = last.next; } last.next = cur; return head; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public ListNode partition (ListNode head, int x) { ListNode smallHead = new ListNode (), bigHead = new ListNode (), smallOriginHead = smallHead, bigOriginHead = bigHead; while (head != null ) { if (head.val < x) { smallHead.next = head; smallHead = smallHead.next; } else { bigHead.next = head; bigHead = bigHead.next; } ListNode next = head.next; head.next = null ; head = next; } if (smallOriginHead.next == null ) { return bigOriginHead.next; } else { smallHead.next = bigOriginHead.next; return smallOriginHead.next; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution { public ListNode reverseBetween (ListNode head, int left, int right) { ListNode newHead = new ListNode (-1 , head), cur = head, last = newHead; int index = 1 ; while (index < left) { last = cur; cur = cur.next; index++; } ListNode leftNode = cur, leftLast = last; while (index < right) { ListNode next = cur.next; cur.next = last; last = cur; cur = next; index++; } ListNode rightNext = cur.next; cur.next = last; leftLast.next = cur; leftNode.next = rightNext; return newHead.next; } }
不加头节点可以看下面的一题,一样的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class Solution { public boolean hasCycle (ListNode head) { ListNode newHead = new ListNode (-1 ), fast = newHead, slow = newHead; newHead.next = head; while (fast.next != null && fast.next.next != null ) { fast = fast.next.next; slow = slow.next; if (fast == slow) { return true ; } } return false ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public class Solution { public ListNode detectCycle (ListNode head) { ListNode temp = isHaveCircleInLinkedList(head); if (temp == null ) { return null ; } temp = temp.next; ListNode cur = head; while (cur != temp) { cur = cur.next; temp = temp.next; } return cur; } public ListNode isHaveCircleInLinkedList (ListNode head) { if (head == null || head.next == null ) { return null ; } ListNode fast = head.next, slow = head; while (fast.next != null && fast.next.next != null ) { fast = fast.next.next; slow = slow.next; if (fast == slow) { return fast; } } return null ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 class Solution { public void reorderList (ListNode head) { int count = 0 ; ListNode cur = head; while (cur != null ) { count++; cur = cur.next; } if (count <= 2 ) { return ; } count = count >> 1 ; cur = head; while (count != 0 ) { count--; cur = cur.next; } ListNode reverseNode = cur.next; cur.next = null ; reverseNode = reverseList(reverseNode); cur = head; head = head.next; while (reverseNode != null ) { cur.next = reverseNode; ListNode next = reverseNode.next; reverseNode.next = head; cur = head; if (head != null ) { head = head.next; } reverseNode = next; } } public ListNode reverseList (ListNode head) { ListNode last = null ; while (head != null ) { ListNode next = head.next; head.next = last; last = head; head = next; } return last; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 class Solution { public ListNode sortList (ListNode head) { int count = 0 ; ListNode temp = head; while (temp != null ) { temp = temp.next; count++; } return mergeSort(head, 1 , count); } public ListNode mergeSort (ListNode node, int left, int right) { if (left < right) { int mid = (left + right) >> 1 ; ListNode leftNode = node; for (int i = left; i < mid; i++) { leftNode = leftNode.next; } ListNode rightNode = leftNode.next; leftNode.next = null ; leftNode = mergeSort(node, left, mid); rightNode = mergeSort(rightNode, mid + 1 , right); return merge(leftNode, rightNode); } return node; } public ListNode merge (ListNode left, ListNode right) { if (left == null ) { return right; } ListNode newHead = new ListNode (), cur = newHead; while (left != null && right != null ) { if (left.val < right.val) { cur.next = left; cur = left; ListNode next = left.next; left.next = null ; left = next; } else { cur.next = right; cur = right; ListNode next = right.next; right.next = null ; right = next; } } if (left != null ) { cur.next = left; } else { cur.next = right; } return newHead.next; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class Solution { public ListNode getIntersectionNode (ListNode headA, ListNode headB) { ListNode node1 = headA, node2 = headB; while (node1 != null || node2 != null ) { if (node1 == node2) { return node1; } if (node1 == null ) { node1 = headB; } else { node1 = node1.next; } if (node2 == null ) { node2 = headA; } else { node2 = node2.next; } } return null ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Solution { public ListNode removeElements (ListNode head, int val) { ListNode newHead, cur = head; while (cur != null && cur.val == val) { ListNode next = cur.next; cur.next = null ; cur.next = next; cur = next; } if (cur != null ) { newHead = cur; } else { return null ; } while (cur.next != null ) { if (cur.next.val == val) { ListNode next = cur.next; cur.next = next.next; next.next = null ; } else { cur = cur.next; } } return newHead; } }
1 2 3 4 5 6 7 8 9 10 11 12 class Solution { public ListNode reverseList (ListNode head) { ListNode last = null ; while (head != null ) { ListNode next = head.next; head.next = last; last = head; head = next; } return last; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 class Solution { public boolean isPalindrome (ListNode head) { int count = 0 ; ListNode cur = head; while (cur != null ) { count++; cur = cur.next; } if (count <= 1 ) { return true ; } count = count >> 1 ; cur = head; int temp = 1 ; while (temp < count) { cur = cur.next; temp++; } ListNode next = cur.next; cur.next = null ; ListNode tail = reverse(next); while (head != null ) { if (head.val != tail.val) { return false ; } head = head.next; tail = tail.next; } return true ; } public ListNode reverse (ListNode head) { ListNode last = null ; while (head != null ) { ListNode next = head.next; head.next = last; last = head; head = next; } return last; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public void deleteNode (ListNode node) { ListNode last = null ; while (node.next != null ) { node.val = node.next.val; last = node; node = node.next; } if (last != null ) { last.next = null ; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public ListNode oddEvenList (ListNode head) { ListNode odd = new ListNode (), even = new ListNode (), curOdd = odd, curEven = even; int cur = 0 ; while (head != null ) { cur++; if (cur % 2 == 0 ) { curEven.next = head; curEven = head; } else { curOdd.next = head; curOdd = head; } ListNode next = head.next; head.next = null ; head = next; } if (odd.next == null ) { return odd.next; } else { curOdd.next = even.next; return odd.next; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 class Solution { public ListNode addTwoNumbers (ListNode l1, ListNode l2) { ListNode head1 = reverse(l1), head2 = reverse(l2); int last = 0 ; ListNode cur1 = head1, cur2 = head2, lastNode = head1; while (cur1 != null ) { if (cur2 == null ) { cur1.val += last; } else { cur1.val = cur1.val + last + cur2.val; cur2 = cur2.next; } last = cur1.val / 10 ; cur1.val %= 10 ; lastNode = cur1; cur1 = cur1.next; } while (cur2 != null ) { cur2.val += last; last = cur2.val / 10 ; cur2.val %= 10 ; lastNode.next = cur2; lastNode = cur2; cur2 = cur2.next; } if (last != 0 ) { lastNode.next = new ListNode (last); } return reverse(head1); } public ListNode reverse (ListNode head) { ListNode last = null ; while (head != null ) { ListNode next = head.next; head.next = last; last = head; head = next; } return last; } }
不翻转链表进阶版本,递归
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 class Solution { public ListNode addTwoNumbers (ListNode l1, ListNode l2) { int len1 = getLinkedListLength(l1), len2 = getLinkedListLength(l2); ListNode longNode, sortNode; if (len1 >= len2) { longNode = l1; sortNode = l2; } else { longNode = l2; sortNode = l1; } int balance = Math.abs(len1 - len2); if (balance == 0 ) { int last = dfs(longNode, sortNode); if (last == 0 ) { return longNode; } else { ListNode node = new ListNode (last); node.next = longNode; return node; } } else { int curLen = 1 ; ListNode longCur = longNode; while (curLen < balance) { longCur = longCur.next; curLen++; } ListNode next = longCur.next; int last = dfs(next, sortNode); if (last == 0 ) { return longNode; } else { ListNode node = new ListNode (last); longCur.next = null ; ListNode result; if (len1 >= len2) { result = addTwoNumbers(l1, node); } else { result = addTwoNumbers(l2, node); } longCur.next = next; return result; } } } public int dfs (ListNode node1, ListNode node2) { if (node1 == null && node2 == null ) { return 0 ; } int last = dfs(node1.next, node2.next); int sum = last + node1.val + node2.val; node1.val = sum % 10 ; return sum / 10 ; } public int getLinkedListLength (ListNode head) { int length = 0 ; while (head != null ) { length++; head = head.next; } return length; } }
注意边界条件
看了一些别人简洁的版本,确实保留一个虚拟头节点代码会简洁很多,很多判断都省了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 class MyLinkedList { private int len; private Node head; private Node tail; private class Node { public int val; public Node next; } public MyLinkedList () { len = 0 ; head = null ; tail = null ; } public int get (int index) { if (index < 0 || index >= len) { return -1 ; } int cur = 0 ; Node node = head; while (cur < index) { cur++; node = node.next; } return node.val; } public void addAtHead (int val) { Node node = new Node (); node.val = val; len++; if (len == 1 ) { head = node; tail = node; } else { node.next = head; head = node; } } public void addAtTail (int val) { Node node = new Node (); node.val = val; len++; if (len == 1 ) { head = node; tail = node; } else { tail.next = node; tail = node; } } public void addAtIndex (int index, int val) { if (index < 0 || index > len) { return ; } if (index == 0 ) { addAtHead(val); } else if (index == len) { addAtTail(val); } else { Node cur = head, last = head; int curIndex = 0 ; while (curIndex < index) { curIndex++; last = cur; cur = cur.next; } Node node = new Node (); node.val = val; last.next = node; node.next = cur; len++; } } public void deleteAtIndex (int index) { if (index < 0 || index >= len) { return ; } len--; if (index == 0 ) { head = head.next; if (len == 0 ) { tail = null ; } } else { Node last = head, cur = head; int curIndex = 0 ; while (curIndex < index) { curIndex++; last = cur; cur = cur.next; } if (cur == tail) { tail = last; } last.next = cur.next; cur.next = null ; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 class Solution { public ListNode[] splitListToParts(ListNode head, int k) { int len = getLinkedListLength(head); int averge = len / k; int more = len % k; ListNode[] result = new ListNode [k]; ListNode cur = head; for (int i = 0 ; i < k; i++) { int count; if (i + 1 <= more) { count = averge + 1 ; } else { count = averge; } if (count == 0 ) { result[i] = null ; } else { ListNode temp = cur; for (int t = 1 ; t < count; t++) { cur = cur.next; } ListNode next = cur.next; cur.next = null ; cur = next; result[i] = temp; } } return result; } public int getLinkedListLength (ListNode head) { int len = 0 ; while (head != null ) { len++; head = head.next; } return len; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution { public int numComponents (ListNode head, int [] nums) { HashSet<Integer> hash = new HashSet <>(); for (int i : nums) { hash.add(i); } int result = 0 ; boolean isInSet = false ; while (head != null ) { if (hash.contains(head.val)) { if (!isInSet) { isInSet = true ; result++; } } else { isInSet = false ; } head = head.next; } return result; } }
题目说了一半要最后一个,手动模拟一些可以发现快慢指针合适,快指针如果不能到next的next,next为null,就说明出结果了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public ListNode middleNode (ListNode head) { ListNode fast = head, slow = head; while (fast != null ) { if (fast.next == null ) { break ; } fast = fast.next.next; slow = slow.next; } return slow; } }
暂时只想到O(n^2)的解法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Solution { public int [] nextLargerNodes(ListNode head) { List<Integer> list = new ArrayList <>(); while (head != null ) { list.add(findNextLarger(head)); head = head.next; } int [] result = new int [list.size()]; for (int i = 0 ; i < list.size(); i++) { result[i] = list.get(i); } return result; } public int findNextLarger (ListNode head) { if (head == null ) { return 0 ; } ListNode cur = head.next; while (cur != null ) { if (cur.val > head.val) { return cur.val; } cur = cur.next; } return 0 ; } }
复制出来单调栈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class Solution { public int [] nextLargerNodes(ListNode head) { int t = 0 ; ListNode h = head; while (h != null ) { t++; h = h.next; } int [] result = new int [t]; t = 0 ; while (head != null ) { result[t++] = head.val; head = head.next; } LinkedList<Integer> linkedList = new LinkedList <>(); for (int i = 0 ; i < t; i++) { while (!linkedList.isEmpty() && result[linkedList.peekLast()] < result[i]) { result[linkedList.pollLast()] = result[i]; } linkedList.addLast(i); } while (!linkedList.isEmpty()) { result[linkedList.pollLast()] = 0 ; } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 class Solution { public ListNode removeZeroSumSublists (ListNode head) { ListNode newHead = new ListNode (-1 , head), t = newHead; while (t != null ) { boolean isDelete = isShouldDelete(t); if (!isDelete) { t = t.next; } } return newHead.next; } public boolean isShouldDelete (ListNode head) { ListNode cur = head.next; if (cur == null ) { return false ; } int t = 0 ; boolean isDelete = false ; while (cur != null ) { t += cur.val; cur = cur.next; if (t == 0 ) { isDelete = true ; head.next = cur; break ; } } return isDelete; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public int getDecimalValue (ListNode head) { int result = 0 , cur = 1 ; ListNode node = reverse(head); while (node != null ) { result += (cur * node.val); node = node.next; cur *= 2 ; } return result; } public ListNode reverse (ListNode head) { ListNode last = null ; while (head != null ) { ListNode next = head.next; head.next = last; last = head; head = next; } return last; } }
栈和队列 可以if else优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 class Solution { public boolean isValid (String s) { LinkedList<Character> stack = new LinkedList <>(); for (int i = 0 ; i < s.length(); i++) { char c = s.charAt(i); switch (c) { case '(' : stack.push(c); break ; case '[' : stack.push(c); break ; case '{' : stack.push(c); break ; case ')' : if (stack.isEmpty() || stack.pop() != '(' ) { return false ; } break ; case ']' : if (stack.isEmpty() || stack.pop() != '[' ) { return false ; } break ; case '}' : if (stack.isEmpty() || stack.pop() != '{' ) { return false ; } break ; default : return false ; } } return stack.isEmpty(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 class Solution { public String simplifyPath (String path) { ArrayDeque<String> deque = new ArrayDeque <>(); int len = path.length(); int i = 0 ; while (i < len) { if (path.charAt(i) == '/' ) { int j = i + 1 ; while (j < len && path.charAt(j) == '/' ) { j++; } i = j; while (j < len && path.charAt(j) != '/' ) { j++; } int contentLen = j - i; if (contentLen != 0 ) { String content = path.substring(i, j); if (content.equals("." )) { } else if (content.equals(".." )) { if (!deque.isEmpty()) { deque.pollLast(); } } else { deque.offerLast(content); } } i = j; } } StringBuilder builder = new StringBuilder (); builder.append("/" ); while (!deque.isEmpty()) { builder.append(deque.pollFirst()); if (!deque.isEmpty()) { builder.append("/" ); } } return builder.toString(); } }
可以优化的,去重部分复杂了,加了循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 class Solution { public String simplifyPath (String path) { ArrayDeque<String> deque = new ArrayDeque <>(); int len = path.length(); int i = 0 ; while (i < len) { if (path.charAt(i) != '/' ) { int j = i + 1 ; while (j < len && path.charAt(j) != '/' ) { j++; } String content = path.substring(i, j); if (content.equals("." )) { } else if (content.equals(".." )) { if (!deque.isEmpty()) { deque.pollLast(); } } else { deque.offerLast(content); } i = j; } else { i++; } } StringBuilder builder = new StringBuilder (); builder.append("/" ); while (!deque.isEmpty()) { builder.append(deque.pollFirst()); if (!deque.isEmpty()) { builder.append("/" ); } } return builder.toString(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { public int evalRPN (String[] tokens) { Deque<Integer> deque = new ArrayDeque <>(); for (String s : tokens) { if (s.equals("+" ) || s.equals("-" ) || s.equals("*" ) || s.equals("/" )) { int second = deque.pollLast(), first = deque.pollLast(); if (s.equals("+" )) { deque.offerLast(first + second); } else if (s.equals("-" )) { deque.offerLast(first - second); } else if (s.equals("*" )) { deque.offerLast(first * second); } else { deque.offerLast(first / second); } } else { deque.offerLast(Integer.valueOf(s)); } } return deque.pollLast(); } }
下面是官方的优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Solution { public int evalRPN (String[] tokens) { int n = tokens.length; int [] stack = new int [(n + 1 ) / 2 ]; int index = -1 ; for (int i = 0 ; i < n; i++) { String token = tokens[i]; switch (token) { case "+" : index--; stack[index] += stack[index + 1 ]; break ; case "-" : index--; stack[index] -= stack[index + 1 ]; break ; case "*" : index--; stack[index] *= stack[index + 1 ]; break ; case "/" : index--; stack[index] /= stack[index + 1 ]; break ; default : index++; stack[index] = Integer.parseInt(token); } } return stack[index]; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 class MinStack { Deque<Integer> deque; Deque<Integer> minDeque; public MinStack () { deque = new ArrayDeque <>(); minDeque = new ArrayDeque <>(); } public void push (int val) { deque.offerLast(val); if (minDeque.isEmpty() || val <= minDeque.peekLast()) { minDeque.offerLast(val); } } public void pop () { int val = deque.pollLast(); if (val == minDeque.peekLast()) { minDeque.pollLast(); } } public int top () { return deque.peekLast(); } public int getMin () { return minDeque.peekLast(); } }
官方思路
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class MinStack { Deque<Integer> stack; Deque<Integer> minStack; public MinStack () { stack = new LinkedList <>(); minStack = new LinkedList <>(); minStack.push(Integer.MAX_VALUE); } public void push (int val) { stack.push(val); minStack.push(Math.min(minStack.peek(), val)); } public void pop () { stack.pop(); minStack.pop(); } public int top () { return stack.peek(); } public int getMin () { return minStack.peek(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 class MyStack { Queue<Integer> queue1; Queue<Integer> queue2; public MyStack () { queue1 = new ArrayDeque <>(); queue2 = new ArrayDeque <>(); } public void push (int x) { queue2.offer(x); while (!queue1.isEmpty()) { queue2.offer(queue1.poll()); } Queue temp = queue1; queue1 = queue2; queue2 = temp; } public int pop () { return queue1.poll(); } public int top () { return queue1.peek(); } public boolean empty () { return queue1.isEmpty(); } }
一个实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class MyStack { Queue<Integer> queue; public MyStack () { queue = new ArrayDeque <>(); } public void push (int x) { int n = queue.size(); queue.offer(x); while ((n--) != 0 ) { queue.offer(queue.poll()); } } public int pop () { return queue.poll(); } public int top () { return queue.peek(); } public boolean empty () { return queue.isEmpty(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class MyQueue { LinkedList<Integer> stack1; LinkedList<Integer> stack2; public MyQueue () { stack1 = new LinkedList <>(); stack2 = new LinkedList <>(); } public void push (int x) { stack1.push(x); } public int pop () { if (stack2.isEmpty()) { while (!stack1.isEmpty()) { stack2.push(stack1.pop()); } } return stack2.pop(); } public int peek () { if (stack2.isEmpty()) { while (!stack1.isEmpty()) { stack2.push(stack1.pop()); } } return stack2.peek(); } public boolean empty () { return stack1.isEmpty() && stack2.isEmpty(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public int [] nextGreaterElement(int [] nums1, int [] nums2) { HashMap<Integer, Integer> map = new HashMap <>(); for (int i = 0 ; i < nums1.length; i++) { map.put(nums1[i], i); } int [] result = new int [nums1.length]; Arrays.fill(result, -1 ); LinkedList<Integer> stack = new LinkedList <>(); for (int i = 0 ; i < nums2.length; i++) { while (!stack.isEmpty() && nums2[i] > stack.peek()) { int temp = stack.pop(); if (map.containsKey(temp)) { result[map.get(temp)] = nums2[i]; } } stack.push(nums2[i]); } return result; } }
取巧根据范围数组hash
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution { public int [] nextGreaterElement(int [] nums1, int [] nums2) { int [] hash = new int [10001 ]; Arrays.fill(hash, -1 ); for (int i = 0 ; i < nums1.length; i++) { hash[nums1[i]] = i; } int [] result = new int [nums1.length]; Arrays.fill(result, -1 ); LinkedList<Integer> stack = new LinkedList <>(); for (int i = 0 ; i < nums2.length; i++) { while (!stack.isEmpty() && nums2[i] > stack.peek()) { int temp = stack.pop(); if (hash[temp] != -1 ) { result[hash[temp]] = nums2[i]; } } stack.push(nums2[i]); } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import java.util.Arrays;import java.util.LinkedList;class Solution { public int [] nextGreaterElements(int [] nums) { LinkedList<Integer> linkedList = new LinkedList <>(); int len = nums.length; int [] result = new int [len]; Arrays.fill(result, -1 ); for (int i = 0 ; i < len * 2 ; i++) { int cur = i % len; while (!linkedList.isEmpty() && nums[cur] > nums[linkedList.peekLast()]) { result[linkedList.pollLast()] = nums[cur]; } linkedList.addLast(cur); } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public int calPoints (String[] operations) { int [] temp = new int [operations.length]; int index = -1 ; for (String s : operations) { if (s.equals("+" )) { int t = temp[index] + temp[index - 1 ]; temp[++index] = t; } else if (s.equals("D" )) { int t = temp[index] * 2 ; temp[++index] = t; } else if (s.equals("C" )) { index--; } else { temp[++index] = Integer.valueOf(s); } } int result = 0 ; for (int i = 0 ; i <= index; i++) { result += temp[i]; } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 import java.util.LinkedList;class Solution { public int [] asteroidCollision(int [] asteroids) { LinkedList<Integer> linkedList = new LinkedList <>(); for (int i = 0 ; i < asteroids.length; i++) { if (asteroids[i] > 0 ) { linkedList.addLast(asteroids[i]); } else { boolean isAdd = true ; while (!linkedList.isEmpty()) { int t = linkedList.peekLast(); if (t > 0 ) { if (t + asteroids[i] < 0 ) { linkedList.pollLast(); } else if (t + asteroids[i] == 0 ) { linkedList.pollLast(); isAdd = false ; break ; } else { isAdd = false ; break ; } } else { break ; } } if (isAdd) { linkedList.addLast(asteroids[i]); } } } int [] result = new int [linkedList.size()]; for (int i = linkedList.size() - 1 ; i >= 0 ; i--) { result[i] = linkedList.pollLast(); } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public int [] dailyTemperatures(int [] temperatures) { LinkedList<Integer> linkedList = new LinkedList <>(); int [] result = new int [temperatures.length]; for (int i = 0 ; i < temperatures.length; i++) { while (!linkedList.isEmpty() && temperatures[i] > temperatures[linkedList.peekLast()]) { int t = linkedList.pollLast(); result[t] = i - t; } linkedList.addLast(i); } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 class Solution { public boolean backspaceCompare (String s, String t) { char [] s1 = new char [s.length()], t1 = new char [t.length()]; int sIndex = -1 , tIndex = -1 ; for (char c : s.toCharArray()) { if (sIndex == -1 ) { if (c != '#' ) { s1[++sIndex] = c; } } else { if (c == '#' ) { sIndex--; } else { s1[++sIndex] = c; } } } for (char c : t.toCharArray()) { if (tIndex == -1 ) { if (c != '#' ) { t1[++tIndex] = c; } } else { if (c == '#' ) { tIndex--; } else { t1[++tIndex] = c; } } } if (sIndex != tIndex) { return false ; } for (int i = 0 ; i <= sIndex; i++) { if (s1[i] != t1[i]) { return false ; } } return true ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class Solution { public int scoreOfParentheses (String s) { LinkedList<String> linkedList = new LinkedList <>(); int result = 0 ; for (char c : s.toCharArray()) { if (c == '(' ) { linkedList.addLast("(" ); } else { int t = 0 ; if (linkedList.peekLast().equals("(" )) { t += 1 ; } else { while (!linkedList.peekLast().equals("(" )) { t += Integer.valueOf(linkedList.pollLast()); } t *= 2 ; } linkedList.pollLast(); linkedList.addLast(String.valueOf(t)); } } while (!linkedList.isEmpty()) { result += Integer.valueOf(linkedList.pollLast()); } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class StockSpanner { LinkedList<Integer> linkedList; List<Integer> list; public StockSpanner () { linkedList = new LinkedList <>(); list = new ArrayList <>(); } public int next (int price) { int last = list.size(); list.add(price); while (!linkedList.isEmpty() && list.get(linkedList.peekLast()) <= price) { linkedList.pollLast(); } int result = last - (linkedList.isEmpty() ? -1 : linkedList.peekLast()); linkedList.addLast(last); return result; } }
优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 class StockSpanner { LinkedList<Node> linkedList; int size = 0 ; public StockSpanner () { linkedList = new LinkedList <>(); } public int next (int price) { Node node = new Node (size,price); size++; while (!linkedList.isEmpty() && linkedList.peekLast().value <= price) { linkedList.pollLast(); } int result = size - 1 - (linkedList.isEmpty() ? -1 : linkedList.peekLast().index); linkedList.addLast(node); return result; } public static class Node { public final int index; public final int value; public Node (int index,int value) { this .index = index; this .value = value; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution { public int minAddToMakeValid (String s) { LinkedList<Character> linkedList = new LinkedList <>(); int result = 0 ; for (char c : s.toCharArray()) { if (c == ')' ) { if (!linkedList.isEmpty() && linkedList.peekLast() == '(' ) { linkedList.pollLast(); } else { result++; } } else { linkedList.add(c); } } result += linkedList.size(); return result; } }
优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution { public int minAddToMakeValid (String s) { int leftArrow = 0 , result = 0 ; for (char c : s.toCharArray()) { if (c == ')' ) { if (leftArrow != 0 ) { leftArrow--; } else { result++; } } else { leftArrow++; } } result += leftArrow; return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public boolean validateStackSequences (int [] pushed, int [] popped) { int r = 0 , l = 0 ; LinkedList<Integer> linkedList = new LinkedList <>(); while (r < popped.length) { if (linkedList.isEmpty()) { linkedList.addLast(pushed[l]); l++; } else { if (linkedList.peekLast() == popped[r]) { r++; linkedList.pollLast(); } else { if (l == pushed.length) { return false ; } linkedList.addLast(pushed[l]); l++; } } } return true ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public String removeOuterParentheses (String s) { StringBuilder builder = new StringBuilder (); char [] temp = s.toCharArray(); Deque<Integer> deque = new ArrayDeque <>(); for (int i = 0 ; i < s.length(); i++) { if (deque.isEmpty()) { deque.addLast(i); } else { if (temp[deque.peekLast()] == '(' && temp[i] == ')' ) { int start = deque.pollLast(); if (deque.isEmpty() && i > start + 1 ) { builder.append(s.substring(start + 1 , i)); } } else { deque.addLast(i); } } } return builder.toString(); } }
优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution { public String removeOuterParentheses (String s) { StringBuilder builder = new StringBuilder (); char [] temp = s.toCharArray(); int [] deque = new int [s.length()]; int t = -1 ; for (int i = 0 ; i < s.length(); i++) { if (t == -1 ) { deque[++t] = i; } else { if (temp[deque[t]] == '(' && temp[i] == ')' ) { int start = deque[t--]; if (t == -1 && i > start + 1 ) { builder.append(s.substring(start + 1 , i)); } } else { deque[++t] = i; } } } return builder.toString(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution { public String removeDuplicates (String s) { Deque<Character> deque = new ArrayDeque <>(); for (int i = 0 ; i < s.length(); i++) { char c = s.charAt(i); if (deque.isEmpty()) { deque.addLast(c); } else { if (deque.peekLast() == c) { deque.pollLast(); } else { deque.addLast(c); } } } StringBuilder builder = new StringBuilder (); for (char c : deque){ builder.append(c); } return builder.toString(); } }
优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution { public String removeDuplicates (String s) { int index = -1 ; char [] temp = new char [s.length()]; for (char c : s.toCharArray()) { if (index == -1 ) { temp[++index] = c; } else { if (temp[index] == c) { index--; } else { temp[++index] = c; } } } StringBuilder builder = new StringBuilder (); for (int i = 0 ; i <= index; i++) { builder.append(temp[i]); } return builder.toString(); } }
树 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public List<Integer> inorderTraversal (TreeNode root) { List<Integer> result = new ArrayList <>(); LinkedList<TreeNode> stack = new LinkedList <>(); while (root != null || !stack.isEmpty()) { if (root != null ) { stack.push(root); root = root.left; } else { root = stack.poll(); result.add(root.val); root = root.right; } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { TreeNode last = null ; public boolean isValidBST (TreeNode root) { if (root == null ) { return true ; } boolean isLeftLegal = isValidBST(root.left); if (!isLeftLegal) { return false ; } if (last != null && root.val <= last.val) { return false ; } last = root; return isValidBST(root.right); } }
1 2 3 4 5 6 7 8 9 10 11 12 class Solution { public boolean isSameTree (TreeNode p, TreeNode q) { if (p == null && q == null ) { return true ; } else if ((p == null && q != null ) || (p != null && q == null )) { return false ; } else { return p.val == q.val && isSameTree(p.left, q.left) && isSameTree(p.right, q.right); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution { public boolean isSymmetric (TreeNode root) { return root == null || isLegal(root.left, root.right); } public boolean isLegal (TreeNode node1, TreeNode node2) { if (node1 == null && node2 == null ) { return true ; } else if ((node1 == null && node2 != null ) || (node1 != null && node2 == null )) { return false ; } else { return node1.val == node2.val && isLegal(node1.left, node2.right) && isLegal(node1.right, node2.left); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution { public List<List<Integer>> levelOrder (TreeNode root) { List<List<Integer>> result = new ArrayList <>(); Queue<TreeNode> queue = new LinkedList <>(); if (root != null ) { queue.offer(root); } while (!queue.isEmpty()) { int size = queue.size(); List<Integer>list = new ArrayList <>(); while (size != 0 ) { size--; root = queue.poll(); list.add(root.val); if (root.left != null ) { queue.offer(root.left); } if (root.right != null ) { queue.offer(root.right); } } result.add(list); } return result; } }
1 2 3 4 5 6 7 8 class Solution { public int maxDepth (TreeNode root) { if (root == null ) { return 0 ; } return Math.max((maxDepth(root.left)), maxDepth(root.right)) + 1 ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution { public List<List<Integer>> levelOrderBottom (TreeNode root) { List<List<Integer>> result = new ArrayList <>(); Queue<TreeNode> queue = new LinkedList <>(); if (root != null ) { queue.offer(root); while (!queue.isEmpty()) { int size = queue.size(); List<Integer> list = new ArrayList <>(); while (size != 0 ) { size--; root = queue.poll(); list.add(root.val); if (root.left != null ) { queue.offer(root.left); } if (root.right != null ) { queue.offer(root.right); } } result.add(0 , list); } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution { public TreeNode sortedArrayToBST (int [] nums) { return build(nums, 0 , nums.length - 1 ); } public TreeNode build (int [] nums, int left, int right) { if (left > right) { return null ; } int mid = (left + right) >> 1 ; TreeNode node = new TreeNode (nums[mid]); node.left = build(nums, left, mid - 1 ); node.right = build(nums, mid + 1 , right); return node; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution { ListNode cur; public TreeNode sortedListToBST (ListNode head) { cur = head; int len = getLen(head); return build(0 , len - 1 ); } private TreeNode build (int left, int right) { if (left > right) { return null ; } int mid = (left + right) >> 1 ; TreeNode leftNode = build(left, mid - 1 ); TreeNode node = new TreeNode (cur.val); cur = cur.next; node.left = leftNode; node.right = build(mid + 1 , right); return node; } public int getLen (ListNode head) { int len = 0 ; while (head != null ) { head = head.next; len++; } return len; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public boolean isBalanced (TreeNode root) { return getDeep(root) != -1 ; } public int getDeep (TreeNode root) { if (root == null ) { return 0 ; } int left = getDeep(root.left); if (left == -1 ) { return -1 ; } int right = getDeep(root.right); if (right == -1 ) { return -1 ; } if (Math.abs(left - right) > 1 ) { return -1 ; } return Math.max(left, right) + 1 ; } }
当然也可以getDeep就是获取高度,在isBalanced分别获取left和right的高度,发现高度差直接返回了,不然就再递归isBalanced左右
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution { public boolean isBalanced (TreeNode root) { if (root == null ) { return true ; } if (Math.abs(getDeep(root.left) - getDeep(root.right)) > 1 ) { return false ; } else { return isBalanced(root.left) && isBalanced(root.right); } } public int getDeep (TreeNode root) { if (root == null ) { return 0 ; } return Math.max(getDeep(root.left), getDeep(root.right)) + 1 ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution { public int minDepth (TreeNode root) { if (root == null ) { return 0 ; } Queue<TreeNode> queue = new LinkedList <>(); queue.offer(root); int minDeep = 0 ; while (!queue.isEmpty()) { minDeep++; int size = queue.size(); while ((size--) != 0 ) { TreeNode node = queue.poll(); if (node.left == null && node.right == null ) { return minDeep; } else { if (node.left != null ) { queue.offer(node.left); } if (node.right != null ) { queue.offer(node.right); } } } } return minDeep; } }
也可以递归,效率低了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public int minDepth (TreeNode root) { if (root == null ) { return 0 ; } if (root.left == null ) { return minDepth(root.right) + 1 ; } if (root.right == null ) { return minDepth(root.left) + 1 ; } return Math.min(minDepth(root.left), minDepth(root.right)) + 1 ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution { public boolean hasPathSum (TreeNode root, int targetSum) { return hasPath(targetSum, root, 0 ); } public boolean hasPath (int targetSum, TreeNode root, int temp) { if (root == null ) { return false ; } temp += root.val; if (root.left == null && root.right == null ) { return temp == targetSum; } return hasPath(targetSum, root.left, temp) || hasPath(targetSum, root.right, temp); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution { public List<List<Integer>> pathSum (TreeNode root, int targetSum) { List<List<Integer>> result = new ArrayList <>(); dfs(result, new ArrayList <>(), root, targetSum, 0 ); return result; } public void dfs (List<List<Integer>> result, List<Integer> temp, TreeNode root, int targetSum, int tempSum) { if (root == null ) { return ; } tempSum += root.val; temp.add(root.val); if (root.left == null && root.right == null ) { if (tempSum == targetSum) { result.add(new ArrayList <>(temp)); temp.remove(temp.size() - 1 ); return ; } } dfs(result, temp, root.left, targetSum, tempSum); dfs(result, temp, root.right, targetSum, tempSum); temp.remove(temp.size() - 1 ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { TreeNode newTreeNode = new TreeNode (), last = newTreeNode; public void flatten (TreeNode root) { preOrder(root); } public void preOrder (TreeNode root) { if (root == null ) { return ; } TreeNode left = root.left, right = root.right; last.left = null ; last.right = root; last = root; preOrder(left); preOrder(right); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Solution { public int sumNumbers (TreeNode root) { return dfs(root, 0 ); } public int dfs (TreeNode node, int last) { if (node == null ) { return 0 ; } last *= 10 ; last += node.val; if (node.left == null && node.right == null ) { return last; } return dfs(node.left, last) + dfs(node.right, last); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { public List<Integer> preorderTraversal (TreeNode root) { LinkedList<TreeNode> stack = new LinkedList <>(); List<Integer> result = new ArrayList <>(); if (root == null ) { return result; } stack.add(root); while (!stack.isEmpty()) { root = stack.poll(); result.add(root.val); if (root.right != null ) { stack.push(root.right); } if (root.left != null ) { stack.push(root.left); } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { public List<Integer> postorderTraversal (TreeNode root) { LinkedList<TreeNode> stack = new LinkedList <>(); List<Integer> result = new ArrayList <>(); TreeNode last = null ; while (root != null || !stack.isEmpty()) { while (root != null ) { stack.push(root); root = root.left; } root = stack.peek(); if (root.right == null || root.right == last) { result.add(root.val); last = stack.poll(); root = null ; } else { root = root.right; } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class BSTIterator { LinkedList<TreeNode> stack; public BSTIterator (TreeNode root) { stack = new LinkedList <>(); pushLeft(root); } public int next () { TreeNode node = stack.poll(); pushLeft(node.right); return node.val; } public boolean hasNext () { return !stack.isEmpty(); } private void pushLeft (TreeNode node) { while (node != null ) { stack.push(node); node = node.left; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public List<Integer> rightSideView (TreeNode root) { List<Integer> result = new ArrayList <>(); Queue<TreeNode> queue = new LinkedList <>(); if (root == null ) { return result; } queue.offer(root); while (!queue.isEmpty()) { int size = queue.size(); TreeNode cur = null ; while ((size--) != 0 ) { cur = queue.poll(); if (cur.left != null ) { queue.offer(cur.left); } if (cur.right != null ) { queue.offer(cur.right); } } result.add(cur.val); } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 class Solution { public TreeNode invertTree (TreeNode root) { if (root == null ) { return null ; } TreeNode left = root.left, right = root.right; root.right = invertTree(left); root.left = invertTree(right); return root; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 class Solution { public List<String> binaryTreePaths (TreeNode root) { List<String> result = new ArrayList <>(); dfs(root, result, new StringBuilder ()); return result; } public void dfs (TreeNode root, List<String> result, StringBuilder builder) { if (root == null ) { return ; } String s = String.valueOf(root.val); builder.append(s); builder.append("->" ); if (root.left == null && root.right == null ) { builder.delete(builder.length() - 2 , builder.length()); result.add(builder.toString()); builder.delete(builder.length() - s.length(), builder.length()); return ; } dfs(root.left, result, builder); dfs(root.right, result, builder); builder.delete(builder.length() - s.length() - 2 , builder.length()); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution { public int sumOfLeftLeaves (TreeNode root) { int [] value = new int [] { 0 }; dfs(root, value); return value[0 ]; } public void dfs (TreeNode root, int [] value) { if (root == null ) { return ; } if (root.left != null && root.left.left == null && root.left.right == null ) { value[0 ] += root.left.val; } dfs(root.left, value); dfs(root.right, value); } }
long类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { public int pathSum (TreeNode root, long targetSum) { if (root == null ) { return 0 ; } int [] value = new int [] { 0 }; dfs(root, targetSum, 0 , value); return value[0 ] + pathSum(root.left, targetSum) + pathSum(root.right, targetSum); } public void dfs (TreeNode root, long targetSum, long temp, int [] value) { if (root == null ) { return ; } temp += root.val; if (temp == targetSum) { value[0 ]++; } dfs(root.left, targetSum, temp, value); dfs(root.right, targetSum, temp, value); } }
同样也是要注意Long类型,这里是前缀和,然后要看前面有多少个符合要求的,就需要HashMap,还要注意开始的0的处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public int pathSum (TreeNode root, int targetSum) { HashMap<Long, Integer> preSum = new HashMap <>(); preSum.put(0L , 1 ); return getPreSum(root, targetSum, preSum, 0L ); } public int getPreSum (TreeNode root, int targetSum, HashMap<Long, Integer> preSum, long cur) { if (root == null ) { return 0 ; } int result = 0 ; cur += root.val; result += preSum.getOrDefault(cur - targetSum, 0 ); preSum.put(cur, preSum.getOrDefault(cur, 0 ) + 1 ); result += getPreSum(root.left, targetSum, preSum, cur); result += getPreSum(root.right, targetSum, preSum, cur); preSum.put(cur, preSum.get(cur) - 1 ); return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public int findBottomLeftValue (TreeNode root) { int result = 0 ; LinkedList<TreeNode> queue = new LinkedList <>(); queue.offer(root); while (!queue.isEmpty()) { int size = queue.size(), cur = size; while (cur != 0 ) { TreeNode node = queue.poll(); if (cur == size) { result = node.val; } if (node.left != null ) { queue.offer(node.left); } if (node.right != null ) { queue.offer(node.right); } cur--; } } return result; } }
递归优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution { int deep = 0 , result = 0 ; public int findBottomLeftValue (TreeNode root) { getResult(root, 1 ); return result; } public void getResult (TreeNode root, int curDeep) { if (curDeep > deep) { deep = curDeep; result = root.val; } if (root.left != null ) { getResult(root.left, curDeep + 1 ); } if (root.right != null ) { getResult(root.right, curDeep + 1 ); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 class Solution { public List<Integer> largestValues (TreeNode root) { List<Integer> result = new ArrayList <>(); if (root == null ) { return result; } LinkedList<TreeNode> queue = new LinkedList <>(); queue.offer(root); while (!queue.isEmpty()) { int size = queue.size() - 1 ; TreeNode largest = queue.poll(); if (largest.left != null ) { queue.offer(largest.left); } if (largest.right != null ) { queue.offer(largest.right); } while ((size--) != 0 ) { TreeNode node = queue.poll(); if (largest.val < node.val) { largest = node; } if (node.left != null ) { queue.offer(node.left); } if (node.right != null ) { queue.offer(node.right); } } result.add(largest.val); } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { int result = 0 ; public int findTilt (TreeNode root) { dfs(root); return result; } public int dfs (TreeNode root) { if (root == null ) { return 0 ; } int left = dfs(root.left), right = dfs(root.right); result += Math.abs(left - right); return left + right + root.val; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { public boolean isSubtree (TreeNode root, TreeNode subRoot) { boolean result = isSame(root, subRoot); if (root == null || subRoot == null ) { return result; } return result || isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot); } public boolean isSame (TreeNode root, TreeNode subRoot) { if (root == null && subRoot == null ) { return true ; } if (root != null && subRoot != null ) { return root.val == subRoot.val && isSame(root.left, subRoot.left) && isSame(root.right, subRoot.right); } return false ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution { public List<Double> averageOfLevels (TreeNode root) { List<Double> result = new ArrayList <>(); LinkedList<TreeNode> queue = new LinkedList <>(); queue.offer(root); while (!queue.isEmpty()) { int size = queue.size(), curSize = size; double temp = 0 ; while ((curSize--) != 0 ) { TreeNode node = queue.poll(); if (node.left != null ) { queue.offer(node.left); } if (node.right != null ) { queue.offer(node.right); } temp += node.val; } result.add(temp / size); } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution { public boolean findTarget (TreeNode root, int k) { List<Integer> temp = new ArrayList <>(); midOrder(root, temp); int left = 0 , right = temp.size() - 1 ; while (left < right) { if (temp.get(left) + temp.get(right) > k) { right--; } else if (temp.get(left) + temp.get(right) < k) { left++; } else { break ; } } return left < right; } public void midOrder (TreeNode root, List<Integer> temp) { if (root == null ) { return ; } midOrder(root.left, temp); temp.add(root.val); midOrder(root.right, temp); } }
网上另一种思路
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution { public boolean findTarget (TreeNode root, int k) { return find(root, k, new HashSet <Integer>()); } public boolean find (TreeNode root, int k, HashSet<Integer> set) { if (root == null ) { return false ; } if (set.contains(k - root.val)) { return true ; } set.add(root.val); return find(root.left, k, set) || find(root.right, k, set); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { public boolean leafSimilar (TreeNode root1, TreeNode root2) { List<Integer> list1 = new ArrayList <>(), list2 = new ArrayList <>(); dfs(root1, list1); dfs(root2, list2); return list1.equals(list2); } public void dfs (TreeNode root, List<Integer> list) { if (root == null ) { return ; } if (root.left == null && root.right == null ) { list.add(root.val); } dfs(root.left, list); dfs(root.right, list); } }
注意最后将left和right都置为null
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { TreeNode newRoot = new TreeNode (), last = newRoot; public TreeNode increasingBST (TreeNode root) { midOrder(root); last.left = null ; last.right = null ; return newRoot.right; } public void midOrder (TreeNode root) { if (root == null ) { return ; } midOrder(root.left); last.left = null ; last.right = root; last = root; midOrder(root.right); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { public int deepestLeavesSum (TreeNode root) { int result = 0 ; LinkedList<TreeNode> queue = new LinkedList <>(); queue.offer(root); while (!queue.isEmpty()) { int size = queue.size(), temp = 0 ; while ((size--) != 0 ) { TreeNode node = queue.poll(); temp += node.val; if (node.left != null ) { queue.offer(node.left); } if (node.right != null ) { queue.offer(node.right); } } result = temp; } return result; } }
递归避免了频繁抛出和加入队列,更快了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { int maxDeep = 0 , sum = 0 ; public int deepestLeavesSum (TreeNode root) { if (root != null ) { dfs(root, 1 ); } return sum; } public void dfs (TreeNode root, int deep) { if (root == null ) { return ; } if (deep > maxDeep) { sum = root.val; maxDeep = deep; } else if (deep == maxDeep) { sum += root.val; } dfs(root.left, deep + 1 ); dfs(root.right, deep + 1 ); } }
动态规划 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public int climbStairs (int n) { if (n <= 2 ) { return n; } int first = 1 , second = 2 ; for (int i = 3 ; i <= n; i++) { int temp = first + second; first = second; second = temp; } return second; } }
1 2 3 4 5 6 7 8 9 10 11 class Solution { public int climbStairs (int n) { int [] dp = new int [n + 1 ]; dp[0 ] = 1 ; dp[1 ] = 1 ; for (int i = 2 ; i <= n; i++) { dp[i] = dp[i - 1 ] + dp[i - 2 ]; } return dp[n]; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution { public int rob (int [] nums) { int [] dp = new int [nums.length + 1 ]; dp[0 ] = 0 ; dp[1 ] = nums[0 ]; for (int i = 2 ; i <= nums.length; i++) { dp[i] = Math.max(dp[i - 1 ], dp[i - 2 ] + nums[i - 1 ]); } return dp[nums.length]; } }
1 2 3 4 5 6 7 8 9 10 11 class Solution { public int rob (int [] nums) { int first = 0 , second = nums[0 ]; for (int i = 1 ; i < nums.length; i++) { int temp = Math.max(second, first + nums[i]); first = second; second = temp; } return second; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public int maxProfit (int [] prices) { int [][] dp = new int [prices.length][3 ]; dp[0 ][0 ] = -prices[0 ]; for (int i = 1 ; i < prices.length; i++) { dp[i][0 ] = Math.max(dp[i - 1 ][0 ], dp[i - 1 ][2 ] - prices[i]); dp[i][1 ] = dp[i - 1 ][0 ] + prices[i]; dp[i][2 ] = Math.max(dp[i - 1 ][2 ], dp[i - 1 ][1 ]); } return Math.max(dp[prices.length - 1 ][1 ], dp[prices.length - 1 ][2 ]); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution { public int maxProfit (int [] prices) { int [] dp = new int [3 ]; dp[0 ] = -prices[0 ]; for (int i = 1 ; i < prices.length; i++) { int old = dp[0 ]; dp[0 ] = Math.max(dp[0 ], dp[2 ] - prices[i]); dp[2 ] = Math.max(dp[1 ], dp[2 ]); dp[1 ] = old + prices[i]; } return Math.max(dp[1 ], dp[2 ]); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public int coinChange (int [] coins, int amount) { int [] dp = new int [amount + 1 ]; Arrays.fill(dp, amount + 1 ); dp[0 ] = 0 ; for (int coin : coins) { for (int j = coin; j <= amount; j++) { dp[j] = Math.min(dp[j], dp[j - coin] + 1 ); } } return dp[amount] == amount + 1 ? -1 : dp[amount]; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public int integerBreak (int n) { int [] dp = new int [n + 1 ]; dp[2 ] = 1 ; for (int i = 3 ; i <= n; i++) { for (int j = 1 ; j <= i / 2 ; j++) { dp[i] = Math.max(dp[i], Math.max(j * (i - j), j * dp[i - j])); } } return dp[n]; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public boolean canPartition (int [] nums) { int sum = 0 ; for (int num : nums) { sum += num; } if (sum % 2 != 0 ) { return false ; } sum /= 2 ; int [] dp = new int [sum + 1 ]; for (int i : nums) { for (int j = sum; j >= i; j--) { dp[j] = Math.max(dp[j], dp[j - i] + i); if (dp[j] == sum) { return true ; } } } return dp[sum] == sum; } }
DFS和BFS 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution { public List<String> letterCombinations (String digits) { HashMap<Character, String> map = new HashMap <>(); map.put('2' , "abc" ); map.put('3' , "def" ); map.put('4' , "ghi" ); map.put('5' , "jkl" ); map.put('6' , "mno" ); map.put('7' , "pqrs" ); map.put('8' , "tuv" ); map.put('9' , "wxyz" ); List<String> result = new ArrayList <>(); if (digits.length() != 0 ) { backTracking(map, result, new char [digits.length()], 0 , digits); } return result; } public void backTracking (HashMap<Character, String> map, List<String> result, char [] temp, int len, String digits) { if (len == digits.length()) { result.add(new String (temp)); return ; } char c = digits.charAt(len); String s = map.get(c); for (int i = 0 ; i < s.length(); i++) { temp[len] = s.charAt(i); backTracking(map, result, temp, len + 1 , digits); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Solution { public List<String> generateParenthesis (int n) { List<String> result = new ArrayList <>(); backTracking(0 , 0 , n, new char [n * 2 ], result); return result; } public void backTracking (int left, int right, int n, char [] temp, List<String> result) { if (left == n && right == n) { result.add(new String (temp)); return ; } int cur = left + right; if (left < n) { if (left == right) { temp[cur] = '(' ; backTracking(left + 1 , right, n, temp, result); } else { temp[cur] = '(' ; backTracking(left + 1 , right, n, temp, result); temp[cur] = ')' ; backTracking(left, right + 1 , n, temp, result); } } else { temp[cur] = ')' ; backTracking(left, right + 1 , n, temp, result); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 class Solution { public void solveSudoku (char [][] board) { for (int i = 0 ; i < 9 ; i++) { for (int j = 0 ; j < 9 ; j++) { if (board[i][j] == '.' ) { for (char k = '1' ; k <= '9' ; k++) { if (isLegal(board, i, j, k)) { board[i][j] = k; solveSudoku(board); if (isFill(board)) { return ; } board[i][j] = '.' ; } } return ; } } } } public boolean isFill (char [][] board) { for (int i = 0 ; i < 9 ; i++) { for (int j = 0 ; j < 9 ; j++) { if (board[i][j] == '.' ) { return false ; } } } return true ; } public boolean isLegal (char [][] board, int row, int column, char num) { for (int i = 0 ; i < 9 ; i++) { if (board[i][column] == num) { return false ; } } for (int j = 0 ; j < 9 ; j++) { if (board[row][j] == num) { return false ; } } int left = row / 3 * 3 , right = column / 3 * 3 ; for (int i = left; i < left + 3 ; i++) { for (int j = right; j < right + 3 ; j++) { if (board[i][j] == num) { return false ; } } } return true ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution { public List<List<Integer>> permute (int [] nums) { boolean [] isSelected = new boolean [nums.length]; List<List<Integer>> result = new ArrayList <>(); List<Integer> temp = new ArrayList <>(); backTracking(result, nums, isSelected, temp); return result; } public void backTracking (List<List<Integer>> result, int [] nums, boolean [] isSelected, List<Integer> temp) { if (temp.size() == nums.length) { result.add(new ArrayList <>(temp)); return ; } for (int i = 0 ; i < nums.length; i++) { if (!isSelected[i]) { temp.add(nums[i]); isSelected[i] = true ; backTracking(result, nums, isSelected, temp); isSelected[i] = false ; temp.remove(temp.size() - 1 ); } } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 class Solution { List<List<String>> result = new ArrayList <>(); char [][] board; public List<List<String>> solveNQueens (int n) { board = new char [n][n]; for (int i = 0 ; i < n; i++) { for (int j = 0 ; j < n; j++) { board[i][j] = '.' ; } } backTracking(n, 0 ); return result; } public void backTracking (int n, int deep) { if (deep == n) { List<String> temp = new ArrayList <>(); for (char [] chars : board) { temp.add(new String (chars)); } result.add(temp); return ; } for (int j = 0 ; j < n; j++) { if (isLegal(n, deep, j)) { board[deep][j] = 'Q' ; backTracking(n, deep + 1 ); board[deep][j] = '.' ; } } } public boolean isLegal (int n, int x, int y) { for (int i = 0 ; i < n; i++) { if (board[i][y] != '.' ) { return false ; } } for (int i = x - 1 , j = y - 1 ; i >= 0 && j >= 0 ; i--, j--) { if (board[i][j] != '.' ) { return false ; } } for (int i = x + 1 , j = y - 1 ; i < n && j >= 0 ; i++, j--) { if (board[i][j] != '.' ) { return false ; } } for (int i = x - 1 , j = y + 1 ; i >= 0 && j < n; i--, j++) { if (board[i][j] != '.' ) { return false ; } } for (int i = x + 1 , j = y + 1 ; i < n && j < n; i++, j++) { if (board[i][j] != '.' ) { return false ; } } return true ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 class Solution { int result = 0 ; char [][] board; public int totalNQueens (int n) { board = new char [n][n]; for (int i = 0 ; i < n; i++) { for (int j = 0 ; j < n; j++) { board[i][j] = '.' ; } } backTracking(n, 0 ); return result; } public void backTracking (int n, int deep) { if (deep == n) { result++; return ; } for (int j = 0 ; j < n; j++) { if (isLegal(n, deep, j)) { board[deep][j] = 'Q' ; backTracking(n, deep + 1 ); board[deep][j] = '.' ; } } } public boolean isLegal (int n, int x, int y) { for (int i = 0 ; i < n; i++) { if (board[i][y] != '.' ) { return false ; } } for (int i = x - 1 , j = y - 1 ; i >= 0 && j >= 0 ; i--, j--) { if (board[i][j] != '.' ) { return false ; } } for (int i = x + 1 , j = y - 1 ; i < n && j >= 0 ; i++, j--) { if (board[i][j] != '.' ) { return false ; } } for (int i = x - 1 , j = y + 1 ; i >= 0 && j < n; i--, j++) { if (board[i][j] != '.' ) { return false ; } } for (int i = x + 1 , j = y + 1 ; i < n && j < n; i++, j++) { if (board[i][j] != '.' ) { return false ; } } return true ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class Solution { String result = "" ; int cur = 0 ; public String getPermutation (int n, int k) { backTracking(n, k, new boolean [n], new char [n], 0 ); return result; } public void backTracking (int n, int k, boolean [] isSelect, char [] temp, int deep) { if (deep == n) { cur++; if (cur == k) { result = new String (temp); } return ; } if (cur >= k) { return ; } for (int i = 0 ; i < isSelect.length; i++) { if (cur >= k) { return ; } if (!isSelect[i]) { isSelect[i] = true ; temp[deep] = (char ) ('0' + i + 1 ); backTracking(n, k, isSelect, temp, deep + 1 ); isSelect[i] = false ; } } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution { List<List<Integer>> result = new ArrayList <>(); public List<List<Integer>> combine (int n, int k) { backTracking(n, k, new ArrayList <>(), 1 ); return result; } public void backTracking (int n, int k, List<Integer> temp, int cur) { if (temp.size() == k) { result.add(new ArrayList <>(temp)); return ; } if (temp.size() + n - cur + 1 < k) { return ; } for (int i = cur; i <= n; i++) { temp.add(i); backTracking(n, k, temp, i + 1 ); temp.remove(temp.size() - 1 ); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class Solution { List<String> result = new ArrayList <>(); public List<String> restoreIpAddresses (String s) { backTracking(s, new StringBuilder (), 0 , 0 ); return result; } public void backTracking (String s, StringBuilder builder, int cur, int pointCount) { if (pointCount == 4 && cur == s.length()) { builder.deleteCharAt(builder.length() - 1 ); result.add(builder.toString()); builder.append("." ); return ; } if (pointCount == 4 ) { return ; } int curMaxLen = cur + 3 > s.length() ? s.length() : cur + 3 ; for (int i = cur + 1 ; i <= curMaxLen; i++) { String temp = s.substring(cur, i); if (temp.charAt(0 ) == '0' && temp.length() > 1 ) { return ; } if (Integer.valueOf(temp) > 255 ) { return ; } builder.append(temp); builder.append("." ); backTracking(s, builder, i, pointCount + 1 ); builder.delete(builder.length() - temp.length() - 1 , builder.length()); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 class Solution { List<List<String>> result = new ArrayList <>(); public List<List<String>> partition (String s) { backTracking(s, new ArrayList <>(), 0 ); return result; } public void backTracking (String s, List<String> temp, int cur) { if (cur == s.length()) { result.add(new ArrayList <>(temp)); return ; } for (int i = cur + 1 ; i <= s.length(); i++) { if (isLegal(s, cur, i - 1 )) { temp.add(s.substring(cur, i)); backTracking(s, temp, i); temp.remove(temp.size() - 1 ); } } } public boolean isLegal (String s, int left, int right) { while (left < right) { if (s.charAt(left++) != s.charAt(right--)) { return false ; } } return true ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 class WordDictionary { HashSet<String> dic; public WordDictionary () { dic = new HashSet <>(); } public void addWord (String word) { dic.add(word); } public boolean search (String word) { return isInDic(word.toCharArray(), 0 ); } public boolean isInDic (char [] word, int cur) { if (cur == word.length) { return dic.contains(new String (word)); } for (int i = cur; i < word.length; i++) { if (word[i] == '.' ) { for (char c = 'a' ; c <= 'z' ; c++) { word[i] = c; boolean result = isInDic(word, i + 1 ); word[i] = '.' ; if (result) { return true ; } } return false ; } } return isInDic(word, word.length); } }
TODO 前缀树优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 class Solution { public List<String> findWords (char [][] board, String[] words) { boolean [] isHeadHas = new boolean [26 ]; int maxLen = 0 ; HashSet<String> dic = new HashSet <>(); for (String word : words) { dic.add(word); isHeadHas[word.charAt(0 ) - 'a' ] = true ; maxLen = Math.max(maxLen, word.length()); } StringBuilder temp = new StringBuilder (); boolean [][] isVisited = new boolean [board.length][board[0 ].length]; int [][] dirs = new int [][] { { 1 , 0 }, { -1 , 0 }, { 0 , 1 }, { 0 , -1 } }; HashSet<String> result = new HashSet <>(); for (int i = 0 ; i < board.length; i++) { for (int j = 0 ; j < board[0 ].length; j++) { if (isHeadHas[board[i][j] - 'a' ]) { temp.append(board[i][j]); isVisited[i][j] = true ; dfs(temp, 1 , isVisited, board, dic, i, j, dirs, result, maxLen); temp.deleteCharAt(temp.length() - 1 ); isVisited[i][j] = false ; } } } return new ArrayList <>(result); } public void dfs (StringBuilder temp, int deep, boolean [][] isVisited, char [][] board, HashSet<String> dic, int i, int j, int [][] dirs, HashSet<String> result, int maxLen) { String s = temp.toString(); if (dic.contains(s) && !result.contains(s)) { result.add(s); } if (deep == maxLen) { return ; } for (int [] dir : dirs) { int nextI = i + dir[0 ], nextJ = j + dir[1 ]; if (nextI >= 0 && nextI < isVisited.length && nextJ >= 0 && nextJ < isVisited[0 ].length && !isVisited[nextI][nextJ]) { isVisited[nextI][nextJ] = true ; temp.append(board[nextI][nextJ]); dfs(temp, deep + 1 , isVisited, board, dic, nextI, nextJ, dirs, result, maxLen); isVisited[nextI][nextJ] = false ; temp.deleteCharAt(temp.length() - 1 ); } } } }
TODO 优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class Solution { public int longestIncreasingPath (int [][] matrix) { int max = 0 ; int [][] dirs = new int [][] { { 0 , -1 }, { 0 , 1 }, { -1 , 0 }, { 1 , 0 } }; int [][] memory = new int [matrix.length][matrix[0 ].length]; for (int i = 0 ; i < matrix.length; i++) { for (int j = 0 ; j < matrix[0 ].length; j++) { max = Math.max(max, dfs(matrix, dirs, memory, i, j)); } } return max; } public int dfs (int [][] matrix, int [][] dirs, int [][] memory, int i, int j) { if (memory[i][j] != 0 ) { return memory[i][j]; } memory[i][j]++; for (int [] dir : dirs) { int newI = dir[0 ] + i, newJ = dir[1 ] + j; if (newI >= 0 && newI < matrix.length && newJ >= 0 && newJ < matrix[0 ].length && matrix[newI][newJ] > matrix[i][j]) { memory[i][j] = Math.max(memory[i][j], dfs(matrix, dirs, memory, newI, newJ) + 1 ); } } return memory[i][j]; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 import java.util.ArrayList;import java.util.Arrays;import java.util.HashSet;import java.util.List;class Solution { public List<List<Integer>> findSubsequences (int [] nums) { List<List<Integer>> result = new ArrayList <>(); dfs(nums, result, new ArrayList <>(), new HashSet <>(), -1 ); return result; } public void dfs (int [] nums, List<List<Integer>> result, List<Integer> temp, HashSet<Integer> already, int index) { if (temp.size() >= 2 ) { result.add(new ArrayList <>(temp)); } HashSet<Integer> set = new HashSet <>(); for (int i = index + 1 ; i < nums.length; i++) { if ((temp.isEmpty() && already.add(nums[i])) || (!temp.isEmpty() && (set.add(nums[i]) && nums[i] >= temp.get(temp.size() - 1 )))) { temp.add(nums[i]); dfs(nums, result, temp, already, i); temp.remove(temp.size() - 1 ); } } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Solution { public int findTargetSumWays (int [] nums, int target) { return dfs(nums, target, 0 , 0 ); } public int dfs (int [] nums, int target, int index, int tmp) { if (index == nums.length) { return tmp == target ? 1 : 0 ; } if (tmp < target) { int t = tmp; for (int i = index; i < nums.length; i++) { t += nums[i]; } if (t < target) { return 0 ; } } else { int t = tmp; for (int i = index; i < nums.length; i++) { t -= nums[i]; } if (t > target) { return 0 ; } } return dfs(nums, target, index + 1 , tmp + nums[index]) + dfs(nums, target, index + 1 , tmp - nums[index]); } }
TODO 背包优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 import java.util.LinkedList;class Solution { public int [][] updateMatrix(int [][] mat) { int [][] dp = new int [mat.length][mat[0 ].length]; for (int i = 0 ; i < mat.length; i++) { for (int j = 0 ; j < mat[0 ].length; j++) { if (mat[i][j] != 0 ) { dp[i][j] = 10001 ; } } } for (int i = 0 ; i < mat.length; i++) { for (int j = 0 ; j < mat[0 ].length; j++) { if (i - 1 >= 0 ) { dp[i][j] = Math.min(dp[i][j], dp[i - 1 ][j] + 1 ); } if (j - 1 >= 0 ) { dp[i][j] = Math.min(dp[i][j], dp[i][j - 1 ] + 1 ); } } } for (int i = mat.length - 1 ; i >= 0 ; i--) { for (int j = mat[0 ].length - 1 ; j >= 0 ; j--) { if (i + 1 < mat.length) { dp[i][j] = Math.min(dp[i][j], dp[i + 1 ][j] + 1 ); } if (j + 1 < mat[0 ].length) { dp[i][j] = Math.min(dp[i][j], dp[i][j + 1 ] + 1 ); } } } return dp; } }
一开始写的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 import java.util.LinkedList;class Solution { public int [][] updateMatrix(int [][] mat) { int m = mat.length, n = mat[0 ].length; int [][] result = new int [m][n]; boolean [][] isVisited = new boolean [m][n]; LinkedList<int []> linkedList = new LinkedList <>(); int [][] dirs = new int [][] { { 1 , 0 }, { -1 , 0 }, { 0 , -1 }, { 0 , 1 } }; for (int i = 0 ; i < m; i++) { for (int j = 0 ; j < n; j++) { if (mat[i][j] == 0 ) { linkedList.addLast(new int [] { i, j }); isVisited[i][j] = true ; } } } while (!linkedList.isEmpty()) { int [] tmp = linkedList.pollFirst(); for (int [] dir : dirs) { int newI = tmp[0 ] + dir[0 ], newJ = tmp[1 ] + dir[1 ]; if (newI >= 0 && newI < m && newJ >= 0 && newJ < n && !isVisited[newI][newJ]) { result[newI][newJ] = result[tmp[0 ]][tmp[1 ]] + 1 ; linkedList.addLast(new int [] { newI, newJ }); isVisited[newI][newJ] = true ; } } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution { int [][] dirs = new int [][] { { -1 , 0 }, { 1 , 0 }, { 0 , -1 }, { 0 , 1 } }; public int [][] floodFill(int [][] image, int sr, int sc, int color) { dfs(image, sr, sc, color, image[sr][sc]); return image; } public void dfs (int [][] image, int i, int j, int color, int target) { if (image[i][j] == color) { return ; } image[i][j] = color; for (int [] dir : dirs) { int newI = i + dir[0 ], newJ = j + dir[1 ]; if (newI >= 0 && newI < image.length && newJ >= 0 && newJ < image[0 ].length && image[newI][newJ] == target) { dfs(image, newI, newJ, color, target); } } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 import java.util.ArrayList;import java.util.List;class Solution { public List<String> letterCasePermutation (String s) { List<String> result = new ArrayList <>(); backtrack(result, s.toCharArray(), 0 ); return result; } public void backtrack (List<String> result, char [] temp, int index) { if (index == temp.length) { result.add(new String (temp)); return ; } char c = temp[index]; if (c >= '0' && c <= '9' ) { backtrack(result, temp, index + 1 ); } else if (c >= 'a' && c <= 'z' ) { backtrack(result, temp, index + 1 ); temp[index] = (char ) ('A' + c - 'a' ); backtrack(result, temp, index + 1 ); temp[index] = c; } else { backtrack(result, temp, index + 1 ); temp[index] = (char ) ('a' + c - 'A' ); backtrack(result, temp, index + 1 ); temp[index] = c; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 class Solution { public int numEnclaves (int [][] grid) { int [][] dirs = new int [][] { { 0 , -1 }, { 0 , 1 }, { -1 , 0 }, { 1 , 0 } }; for (int j = 0 ; j < grid[0 ].length; j++) { if (grid[0 ][j] == 1 ) { dfs(grid, dirs, 0 , j); } if (grid[grid.length - 1 ][j] == 1 ) { dfs(grid, dirs, grid.length - 1 , j); } } for (int i = 0 ; i < grid.length; i++) { if (grid[i][0 ] == 1 ) { dfs(grid, dirs, i, 0 ); } if (grid[i][grid[0 ].length - 1 ] == 1 ) { dfs(grid, dirs, i, grid[0 ].length - 1 ); } } int result = 0 ; for (int i = 0 ; i < grid.length; i++) { for (int j = 0 ; j < grid[0 ].length; j++) { if (grid[i][j] == 1 ) { result++; } } } return result; } public void dfs (int [][] grid, int [][] dirs, int i, int j) { grid[i][j] = 0 ; for (int [] dir : dirs) { int newI = i + dir[0 ], newJ = j + dir[1 ]; if (newI >= 0 && newI < grid.length && newJ >= 0 && newJ < grid[0 ].length && grid[newI][newJ] == 1 ) { dfs(grid, dirs, newI, newJ); } } } }
这题不用剪枝的方法,直接暴力dfs然后用HashMap去重就行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution { public int numTilePossibilities (String tiles) { int [] result = new int [1 ]; char [] temp = tiles.toCharArray(); Arrays.sort(temp); dfs(temp, new boolean [tiles.length()], 0 , result); return result[0 ]; } public void dfs (char [] tiles, boolean [] isVisited, int len, int [] result) { if (len == tiles.length) { return ; } int last = -1 ; for (int i = 0 ; i < tiles.length; i++) { if (!isVisited[i] && (last == -1 || tiles[last] != tiles[i])) { isVisited[i] = true ; last = i; result[0 ]++; dfs(tiles, isVisited, len + 1 , result); isVisited[i] = false ; } } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 class Solution { public int closedIsland (int [][] grid) { int [][] dirs = new int [][] { { 0 , 1 }, { 0 , -1 }, { 1 , 0 }, { -1 , 0 } }; int result = 0 ; for (int i = 0 ; i < grid.length; i++) { for (int j = 0 ; j < grid[0 ].length; j++) { if (grid[i][j] == 0 && dfs(grid, dirs, i, j)) { result++; } } } return result; } public boolean dfs (int [][] grid, int [][] dirs, int i, int j) { boolean result = true ; grid[i][j] = 1 ; for (int [] dir : dirs) { int newI = i + dir[0 ], newJ = j + dir[1 ]; if (newI < 0 || newJ < 0 || newI >= grid.length || newJ >= grid[0 ].length) { result = false ; continue ; } if (grid[newI][newJ] == 0 ) { result = result & dfs(grid, dirs, newI, newJ); } } return result; } }
二分搜索 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public double myPow (double x, int n) { return n >= 0 ? quickPow(x, (long ) n) : 1.0 / quickPow(x, -(long ) n); } public double quickPow (double x, long n) { if (n == 0 ) { return 1.0 ; } double y = quickPow(x, n / 2 ); return n % 2 == 0 ? y * y : y * y * x; } }
迭代
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { public double myPow (double x, int n) { return n >= 0 ? quickPow(x, (long ) n) : 1.0 / quickPow(x, -(long ) n); } public double quickPow (double x, long n) { double result = 1.0 ; double temp = x; while (n > 0 ) { if (n % 2 == 1 ) { result *= temp; } temp *= temp; n /= 2 ; } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution { public int mySqrt (int x) { int left = 0 , right = x; while (left <= right) { int mid = left + ((right - left) >> 1 ); long square = (long )mid * mid; if (square > x) { right = mid - 1 ; } else if (square < x) { left = mid + 1 ; } else { return mid; } } return right; } }
个人感觉没什么二分思想
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public int countNodes (TreeNode root) { if (root == null ) { return 0 ; } TreeNode left = root.left; TreeNode right = root.right; int l = 0 , r = 0 ; while (left != null ) { left = left.left; l++; } while (right != null ) { right = right.right; r++; } if (l == r) { return (2 << l) - 1 ; } return 1 + countNodes(root.left) + countNodes(root.right); } }
个人写的,感觉没什么二分思想
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public int kthSmallest (TreeNode root, int k) { int [] temp = new int [] { k, -1 }; dfs(root, temp); return temp[1 ]; } public void dfs (TreeNode root, int [] temp) { if (root == null ) { return ; } dfs(root.left, temp); if (temp[0 ] == 1 ) { temp[0 ]--; temp[1 ] = root.val; return ; } temp[0 ]--; dfs(root.right, temp); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public boolean searchMatrix (int [][] matrix, int target) { for (int [] m : matrix) { if (binarySearch(m, target)) { return true ; } } return false ; } public boolean binarySearch (int [] matrix, int target) { int l = 0 , r = matrix.length - 1 ; while (l <= r) { int mid = (l + r) >> 1 ; if (matrix[mid] < target) { l = mid + 1 ; } else if (matrix[mid] > target) { r = mid - 1 ; } else { return true ; } } return false ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public boolean searchMatrix (int [][] matrix, int target) { int i = matrix.length - 1 , j = 0 ; while (i >= 0 && j <= matrix[0 ].length - 1 ) { if (matrix[i][j] < target) { j++; } else if (matrix[i][j] > target) { i--; } else { return true ; } } return false ; } }
275. H 指数 II - 力扣(LeetCode)
后续看看,这里看的网上的讲解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution { public int hIndex (int [] citations) { int l = 1 , r = citations.length, len = citations.length; while (l <= r) { int mid = (l + r) >> 1 ; if (citations[len - mid] >= mid) { l = mid + 1 ; } else { r = mid - 1 ; } } return r; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public int hIndex (int [] citations) { int l = 0 , r = citations.length - 1 , len = citations.length; while (l <= r) { int mid = (l + r) >> 1 ; if (len - mid > citations[mid]) { l = mid + 1 ; } else { r = mid - 1 ; } } return len - l; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { public int search (int [] nums, int target) { int left = 0 , right = nums.length - 1 ; while (left <= right) { int mid = left + ((right - left) >> 1 ); if (nums[mid] < target) { left = mid + 1 ; } else if (nums[mid] > target) { right = mid - 1 ; } else { return mid; } } return -1 ; } }
数学 1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public boolean isPalindrome (int x) { String s = String.valueOf(x); int left = 0 , right = s.length() - 1 ; while (left < right) { if (s.charAt(left) != s.charAt(right)) { return false ; } left++; right--; } return true ; } }
不用字符串,效率很低
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public boolean isPalindrome (int x) { if (x < 0 ) { return false ; } int temp = 0 , num = x; while (num != 0 ) { temp = temp * 10 + (num % 10 ); num /= 10 ; } return temp == x; } }
暴力
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public boolean checkPerfectNumber (int num) { int sum = 0 ; for (int i = 1 ; i < num; i++) { if (num % i == 0 ) { sum += i; if (sum > num) { return false ; } } } return sum == num; } }
待优化
哈希表 正常模拟
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution { public boolean isValidSudoku (char [][] board) { for (int i = 0 ; i < 9 ; i++) { for (int j = 0 ; j < 9 ; j++) { if (board[i][j] != '.' ) { for (int k = 0 ; k < 9 ; k++) { if (k != j && board[i][j] == board[i][k]) { return false ; } } for (int k = 0 ; k < 9 ; k++) { if (k != i && board[i][j] == board[k][j]) { return false ; } } int top = i / 3 * 3 , start = j / 3 * 3 ; for (int k = top; k < top + 3 ; k++) { for (int l = start; l < start + 3 ; l++) { if (k != i && l != j && board[k][l] == board[i][j]) { return false ; } } } } } } return true ; } }
哈希
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 class Solution { public boolean isValidSudoku (char [][] board) { for (int i = 0 ; i < 9 ; i++) { int [] hash = new int [9 ]; for (int j = 0 ; j < 9 ; j++) { if (board[i][j] != '.' && (hash[board[i][j] - '1' ]++) != 0 ) { return false ; } } } for (int j = 0 ; j < 9 ; j++) { int [] hash = new int [9 ]; for (int i = 0 ; i < 9 ; i++) { if (board[i][j] != '.' && (hash[board[i][j] - '1' ]++) != 0 ) { return false ; } } } for (int i = 0 ; i < 9 ; i += 3 ) { for (int j = 0 ; j < 9 ; j += 3 ) { int [] hash = new int [9 ]; for (int k = i; k < i + 3 ; k++) { for (int l = j; l < j + 3 ; l++) { if (board[k][l] != '.' && (hash[board[k][l] - '1' ]++) != 0 ) { return false ; } } } } } return true ; } }
再优化,都是哈希,代码更优雅
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public boolean isValidSudoku (char [][] board) { int [][] rows = new int [9 ][9 ]; int [][] columns = new int [9 ][9 ]; int [][][] grids = new int [3 ][3 ][9 ]; for (int i = 0 ; i < 9 ; i++) { for (int j = 0 ; j < 9 ; j++) { char c = board[i][j]; if (c != '.' ) { int index = c - '1' ; rows[i][index]++; columns[j][index]++; grids[i / 3 ][j / 3 ][index]++; if (rows[i][index] > 1 || columns[j][index] > 1 || grids[i / 3 ][j / 3 ][index] > 1 ) { return false ; } } } } return true ; } }
哈希+排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution { public List<List<String>> groupAnagrams (String[] strs) { HashMap<String, List<String>> map = new HashMap <>(); for (String str : strs) { char [] charArray = str.toCharArray(); Arrays.sort(charArray); String sortedStr = new String (charArray); if (!map.containsKey(sortedStr)) { map.put(sortedStr, new ArrayList <String>()); } map.get(sortedStr).add(str); } return new ArrayList <>(map.values()); } }
哈希+哈希计数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution { public List<List<String>> groupAnagrams (String[] strs) { HashMap<String, List<String>> map = new HashMap <>(); for (String str : strs) { int [] hash = new int [26 ]; for (int i = 0 ; i < str.length(); i++) { hash[str.charAt(i) - 'a' ]++; } StringBuilder builder = new StringBuilder (); for (int i = 0 ; i < 26 ; i++) { builder.append((char ) ('a' + i)); builder.append(hash[i]); } String key = builder.toString(); List<String> list = map.getOrDefault(key, new ArrayList <String>()); list.add(str); map.put(key, list); } return new ArrayList <List<String>>(map.values()); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class Solution { public boolean wordPattern (String pattern, String s) { HashMap<Character, String> map = new HashMap <>(); HashSet<String> set = new HashSet <>(); String[] strs = s.split(" " ); if (strs.length != pattern.length()) { return false ; } for (int i = 0 ; i < pattern.length(); i++) { Character c = pattern.charAt(i); String str = strs[i]; if (map.containsKey(c)) { if (!map.get(c).equals(str)) { return false ; } } else { if (set.contains(str)) { return false ; } } map.put(c, str); set.add(str); } return true ; } }
排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public int [][] merge(int [][] intervals) { Arrays.sort(intervals, (int [] ints1, int [] ints2) -> { return ints1[0 ] - ints2[0 ]; }); List<int []> list = new ArrayList <>(); list.add(intervals[0 ]); int [] last = intervals[0 ]; for (int i = 1 ; i < intervals.length; i++) { int [] cur = intervals[i]; if (cur[0 ] >= last[0 ] && cur[0 ] <= last[1 ]) { last[1 ] = Math.max(last[1 ], cur[1 ]); } else { list.add(cur); last = cur; } } int [][] result = new int [list.size()][2 ]; for (int i = 0 ; i < list.size(); i++) { result[i] = list.get(i); } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution { public ListNode insertionSortList (ListNode head) { ListNode newHead = new ListNode (-5001 , head), cur = head, curLast = newHead; while (cur != null ) { ListNode curNext = cur.next; if (cur.val >= curLast.val) { curLast = cur; } else { curLast.next = cur.next; ListNode node = newHead; while (node.next != null && node.next.val < cur.val) { node = node.next; } ListNode next = node.next; node.next = cur; cur.next = next; } cur = curNext; } return newHead.next; } }
归并排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 class Solution { public int maximumGap (int [] nums) { if (nums.length < 2 ) { return 0 ; } mergeSort(nums, new int [nums.length], 0 , nums.length - 1 ); int result = Math.abs(nums[0 ] - nums[1 ]); for (int i = 2 ; i < nums.length; i++) { int temp = Math.abs(nums[i] - nums[i - 1 ]); result = Math.max(temp, result); } return result; } public void mergeSort (int [] nums, int [] temp, int start, int end) { if (start < end) { int mid = (start + end) >> 1 ; mergeSort(nums, temp, start, mid); mergeSort(nums, temp, mid + 1 , end); merge(nums, temp, start, mid, end); } } public void merge (int [] nums, int [] temp, int start, int mid, int end) { int left = start, right = mid + 1 , cur = start; while (left <= mid && right <= end) { if (nums[left] < nums[right]) { temp[cur++] = nums[left++]; } else { temp[cur++] = nums[right++]; } } while (left <= mid) { temp[cur++] = nums[left++]; } while (right <= end) { temp[cur++] = nums[right++]; } for (int i = start; i <= end; i++) { nums[i] = temp[i]; } } }
快排,自己写的会超时,系统Api不会
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 class Solution { public int maximumGap (int [] nums) { if (nums.length < 2 ) { return 0 ; } quickSort(nums, 0 , nums.length - 1 ); int result = Math.abs(nums[0 ] - nums[1 ]); for (int i = 2 ; i < nums.length; i++) { result = Math.max(Math.abs(nums[i] - nums[i - 1 ]), result); } return result; } public void quickSort (int [] nums, int start, int end) { if (start < end) { int position = partition(nums, start, end); quickSort(nums, start, position - 1 ); quickSort(nums, position + 1 , end); } } public int partition (int [] nums, int start, int end) { int base = nums[start], left = start + 1 , right = end; while (left <= right) { while (left <= right && nums[left] <= base) { left++; } while (left <= right && nums[right] > base) { right--; } if (left < right) { swap(nums, left, right); } } swap(nums, start, right); return right; } public void swap (int [] nums, int left, int right) { int temp = nums[left]; nums[left] = nums[right]; nums[right] = temp; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution { public int maximumGap (int [] nums) { if (nums.length < 2 ) { return 0 ; } Arrays.sort(nums); int result = Math.abs(nums[0 ] - nums[1 ]); for (int i = 2 ; i < nums.length; i++) { result = Math.max(Math.abs(nums[i] - nums[i - 1 ]), result); } return result; } }
基数排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 class Solution { public int maximumGap (int [] nums) { if (nums.length < 2 ) { return 0 ; } lSDRadixSort(nums); int max = Math.abs(nums[0 ] - nums[1 ]); for (int i = 2 ; i < nums.length; i++) { max = Math.max(max, Math.abs(nums[i] - nums[i - 1 ])); } return max; } public void lSDRadixSort (int [] nums) { int max = -1 ; for (int i : nums) { max = Math.max(max, i); } int len = String.valueOf(max).length(); int last = 1 , cur = 10 ; int [][] bucket = new int [nums.length][10 ]; int [] bucketNum = new int [10 ]; for (int i = 0 ; i < len; i++) { for (int num : nums) { int curIndex = num % cur / last; bucket[bucketNum[curIndex]++][curIndex] = num; } int index = 0 ; for (int j = 0 ; j < 10 ; j++) { for (int k = 0 ; k < bucketNum[j]; k++) { nums[index++] = bucket[k][j]; } bucketNum[j] = 0 ; } last *= 10 ; cur *= 10 ; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Solution { int quickselect (int [] nums, int start, int end, int k) { int base = nums[start], left = start, right = end; while (left <= right) { while (left <= right && nums[right] > base) { right--; } while (left <= right && nums[left] <= base) { left++; } if (left < right) { int tmp = nums[left]; nums[left] = nums[right]; nums[right] = tmp; } } nums[start] = nums[right]; nums[right] = base; if (right == k) { return nums[right]; } else if (right < k) { return quickselect(nums, right + 1 , end, k); } else { return quickselect(nums, start, right - 1 , k); } } public int findKthLargest (int [] _nums, int k) { int n = _nums.length; return quickselect(_nums, 0 , n - 1 , n - k); } }
冒泡->快排
插入->希尔
计数->桶排
选择
归并
基数
堆排
1. 冒泡排序 时间复杂度:均为O(n^2),可以优化最好到O(n),本来有序就优化到一次遍历结束,空间O(1),稳定排序
两两比较,将最大的复位
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public int [] sortArray(int [] nums) { bubbleSort(nums); return nums; } public void bubbleSort (int [] nums) { for (int i = 1 ; i < nums.length; i++) { boolean flag = false ; for (int j = 0 ; j < nums.length - i; j++) { if (nums[j + 1 ] < nums[j]) { int temp = nums[j + 1 ]; nums[j + 1 ] = nums[j]; nums[j] = temp; flag = true ; } } if (!flag) { return ; } } } }
2. 选择排序 超时
时间复杂度均为On^2,空间复杂度O1,5 8 5 2 9例子,第一个5会换到2的位置,两个相同的顺序变了,不是稳定排序
记住是保存下标就行,每轮选择剩下最小的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public int [] sortArray(int [] nums) { selectSort(nums); return nums; } public void selectSort (int [] nums) { for (int i = 0 ; i < nums.length - 1 ; i++) { int min = i; for (int j = i + 1 ; j < nums.length; j++) { if (nums[j] < nums[min]) { min = j; } } if (min != i) { int temp = nums[min]; nums[min] = nums[i]; nums[i] = temp; } } } }
3. 插入排序 超时
时间复杂度:最坏全逆序,O(n^2);最好有序,O(n);平均O(n^2)
空间复杂度:O(1)
稳定排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { public int [] sortArray(int [] nums) { insertSort(nums); return nums; } public void insertSort (int [] nums) { for (int i = 1 ; i < nums.length; i++) { int cur = nums[i], j = i; while (j > 0 && nums[j - 1 ] > cur) { nums[j] = nums[j - 1 ]; j--; } nums[j] = cur; } } }
4. 希尔排序 插入排序的进阶版
这个居然ac了,而且效率在这题表现跟归并排序差不多,但空间复杂度是O1
时间复杂度在nlogn到n^2之间,不稳定排序
初始状态:
列表:[8, 3, 1, 2, 7, 5, 6, 4]。
初始增量:4(列表长度 8 的一半)。
第一轮(增量为 4):
将列表分成 4 个子列表:
子列表 1:[8, 7]。
子列表 2:[3, 5]。
子列表 3:[1, 6]。
子列表 4:[2, 4]。
对每个子列表进行插入排序:
子列表 1:[7, 8]。
子列表 2:[3, 5]。
子列表 3:[1, 6]。
子列表 4:[2, 4]。
排序后的列表:[7, 3, 1, 2, 8, 5, 6, 4]。
第二轮(增量为 2):
将列表分成 2 个子列表:
子列表 1:[7, 1, 8, 6]。
子列表 2:[3, 2, 5, 4]。
对每个子列表进行插入排序:
子列表 1:[1, 6, 7, 8]。
子列表 2:[2, 3, 4, 5]。
排序后的列表:[1, 2, 6, 3, 7, 4, 8, 5]。
第三轮(增量为 1):
将整个列表视为一个子列表,进行插入排序。
排序后
的列表:[1, 2, 3, 4, 5, 6, 7, 8]。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public int [] sortArray(int [] nums) { shellSort(nums); return nums; } public void shellSort (int [] nums) { int len = nums.length; for (int step = len / 2 ; step >= 1 ; step /= 2 ) { for (int i = step; i < len; i++) { int j = i, cur = nums[i]; while (j - step >= 0 && nums[j - step] > cur) { nums[j] = nums[j - step]; j -= step; } nums[j] = cur; } } } }
5. 归并排序 时间复杂度:最好最坏平均都是O(nlogn)
空间复杂度:O(n)
稳定排序,每次对比的两个序列不会破坏相等的先后顺序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 class Solution { public int [] sortArray(int [] nums) { mergeSort(nums, new int [nums.length], 0 , nums.length - 1 ); return nums; } public void mergeSort (int [] nums, int [] temp, int start, int end) { if (start < end) { int mid = (start + end) >> 1 ; mergeSort(nums, temp, start, mid); mergeSort(nums, temp, mid + 1 , end); merge(nums, temp, start, mid, end); } } public void merge (int [] nums, int [] temp, int start, int mid, int end) { int left = start, right = mid + 1 , cur = start; while (left <= mid && right <= end) { if (nums[left] <= nums[right]) { temp[cur++] = nums[left++]; } else { temp[cur++] = nums[right++]; } } while (left <= mid) temp[cur++] = nums[left++]; while (right <= end) temp[cur++] = nums[right++]; while (start <= end) { nums[start] = temp[start]; start++; } } }
6. 快速排序 时间复杂度,最好O(nlogn),平均O(nlogn),最坏O(n^2),空间复杂度,O(1),不稳定排序
结合代码看7 7 6 3 8 12,发现两个7的先后顺序变了,不稳定
最坏的触发的话就刚好每次选的第一个元素就是极值,有序就是最好的例子,就为最坏情况了
快排在比较乱序的时候由于nlogn的常数比较小就比归并快并且不用额外空间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class Solution { public int [] sortArray(int [] nums) { quickSort(nums, 0 , nums.length - 1 ); return nums; } public void quickSort (int [] nums, int start, int end) { if (start < end) { int left = start, right = end, base = nums[start]; while (left < right) { while (left < right && nums[right] >= base) right--; while (left < right && nums[left] <= base) left++; if (left < right) { nums[left] ^= nums[right]; nums[right] ^= nums[left]; nums[left] ^= nums[right]; } } nums[start] = nums[left]; nums[left] = base; quickSort(nums, start, left - 1 ); quickSort(nums, left + 1 , end); } } }
不随机选取过不了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 import java.util.Random;class Solution { public int [] sortArray(int [] nums) { quickSort(nums, 0 , nums.length - 1 ); return nums; } public void quickSort (int [] nums, int start, int end) { if (start < end) { int left = start, right = end; int baseIndex = new Random ().nextInt(right - left + 1 ) + left; int base = nums[baseIndex]; nums[baseIndex] = nums[start]; nums[start] = base; while (left < right) { while (left < right && nums[right] >= base) { right--; } while (left < right && nums[left] <= base) { left++; } if (left < right) { int temp = nums[left]; nums[left] = nums[right]; nums[right] = temp; } } nums[start] = nums[left]; nums[left] = base; quickSort(nums, start, left - 1 ); quickSort(nums, left + 1 , end); } } }
7. 堆排序 时间复杂度O(nlogn),空间复杂度O(1),不稳定排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 class Solution { public int [] sortArray(int [] nums) { heapSort(nums); return nums; } public void heapSort (int [] nums) { for (int i = nums.length / 2 - 1 ; i >= 0 ; i--) { heapify(nums, nums.length, i); } for (int i = nums.length - 1 ; i >= 0 ; i--) { swap(nums, i, 0 ); heapify(nums, i, 0 ); } } public void heapify (int [] nums, int len, int index) { int largest = index, lson = index * 2 + 1 , rson = index * 2 + 2 ; if (lson < len && nums[lson] > nums[largest]) { largest = lson; } if (rson < len && nums[rson] > nums[largest]) { largest = rson; } if (largest != index) { swap(nums, largest, index); heapify(nums, len, largest); } } public void swap (int [] nums, int first, int second) { int temp = nums[first]; nums[first] = nums[second]; nums[second] = temp; } }
8. 计数排序 时间复杂度是O(n+k),计数排序不是比较排序,排序的速度快于任何比较排序算法。由于用来计数的数组C的长度取决于待排序数组中数据的范围(等于待排序数组的最大值与最小值的差加上1),这使得计数排序对于数据范围很大的数组,需要大量时间和内存。
空间复杂度O(n+k),页可以说O(k)其实,稳定排序
经典版本,没有负数哈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public int [] sortArray(int [] nums) { countingSort(nums); return nums; } public void countingSort (int [] nums) { int max = Integer.MIN_VALUE; for (int i : nums) { max = Math.max(max, i); } int [] count = new int [max + 1 ]; for (int i : nums) { count[i]++; } int t = 0 ; for (int i = 0 ; i <= max; i++) { while (count[i] > 0 ) { nums[t++] = i; count[i]--; } } } }
常数级别,在数字相差不大就是快,就是需要额外空间,下面这个ac了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution { public int [] sortArray(int [] nums) { countingSort(nums); return nums; } public void countingSort (int [] nums) { int [] count = new int [100001 ]; for (int i : nums) { count[i + 50000 ]++; } int t = 0 ; for (int i = 0 ; i <= 100000 ; i++) { int j = i - 50000 ; while (count[i] > 0 ) { nums[t++] = j; count[i]--; } } } }
9. 桶排序 1.9 桶排序 | 菜鸟教程
这里不写了,有个思路就行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 public class BucketSort { public static void main (String[] args) { int [] ints = new int []{2343 , 234 , 765 , 1 , 23 , 5 , 3 , 2 , 0 , 3 }; bucketSort(ints); for (int i : ints) { System.out.print(i + "\t" ); } } public static void bucketSort (int [] ints) { if (ints == null || ints.length == 1 ) { return ; } int min = ints[0 ]; int max = ints[0 ]; for (int i = 1 ; i < ints.length; i++) { if (ints[i] > max) { max = ints[i]; } if (ints[i] < min) { min = ints[i]; } } int buketNum = (max - min) / ints.length + 1 ; ArrayList<ArrayList<Integer>> bucketList = new ArrayList <>(buketNum); for (int i = 0 ; i < buketNum; i++) { bucketList.add(new ArrayList <>()); } for (int i : ints) { bucketList.get((i - min) / ints.length).add(i); } for (int i = 0 ; i < buketNum; i++) { Collections.sort(bucketList.get(i)); } int t = 0 ; for (int i = 0 ; i < buketNum; i++) { ArrayList<Integer> list = bucketList.get(i); for (Integer integer : list) { ints[t++] = integer; } } } }
10. 基数排序 对于每位,每个数字的这个位放入对应位的桶内,按顺序放,然后每位的大小先后放回原数组,继续对下一位进行处理,从低位到高位,注意负数情况
空间复杂度O(n+k),时间复杂度度O(n*k),稳定排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 class Solution { public int [] sortArray(int [] nums) { radixSort(nums); return nums; } public void radixSort (int [] nums) { int maxDigit = getMaxDigit(nums); int [] digitCount = new int [19 ]; int [][] bucket = new int [19 ][nums.length]; int mod = 10 , dev = 1 ; for (int i = 0 ; i < maxDigit; i++, mod *= 10 , dev *= 10 ) { for (int num : nums) { int bucketPosition = num % mod / dev + 9 ; bucket[bucketPosition][digitCount[bucketPosition]++] = num; } int t = 0 ; for (int j = 0 ; j < 19 ; j++) { for (int k = 0 ; k < digitCount[j]; k++) { nums[t++] = bucket[j][k]; } } Arrays.fill(digitCount, 0 ); } } public int getMaxDigit (int [] nums) { int max = 0 ; for (int i : nums) { max = Math.max(max, Math.abs(i)); } int digit = 0 ; do { digit++; max /= 10 ; } while (max != 0 ); return digit; } }
位运算 1 2 3 4 5 6 7 8 9 10 class Solution { public int singleNumber (int [] nums) { int result = nums[0 ]; for (int i = 1 ; i < nums.length; i++) { result ^= nums[i]; } return result; } }
哈希表暴力解法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public int singleNumber (int [] nums) { HashMap<Integer, Integer> map = new HashMap <>(); for (int num : nums) { map.put(num, map.getOrDefault(num, 0 ) + 1 ); } for (Integer key : map.keySet()) { if (map.get(key) == 1 ) { return key; } } return -1 ; } }
二进制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public int singleNumber (int [] nums) { int result = 0 ; for (int i = 0 ; i < 32 ; i++) { int total = 0 ; for (int num : nums) { total += ((num >> i) & 1 ); } if (total % 3 != 0 ) { result |= (1 << i); } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 class Solution { public int reverseBits (int n) { int result = 0 ; for (int i = 0 ; i < 32 && n != 0 ; i++) { result |= (n & 1 ) << (31 - i); n >>>= 1 ; } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution { public int hammingWeight (int n) { int i = 0 ; while (n != 0 ) { if ((n & 1 ) != 0 ) { i++; } n >>= 1 ; } return i; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution { public int [] singleNumber(int [] nums) { int a = 0 , b = 0 ; int xor = 0 ; for (int i : nums) { xor ^= i; } int div = 1 ; while ((xor & div) == 0 ) { div <<= 1 ; } for (int i : nums) { if ((i & div) == 0 ) { a ^= i; } else { b ^= i; } } return new int [] { a, b }; } }
不用位运算解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public int missingNumber (int [] nums) { int [] hash = new int [nums.length + 1 ]; for (int i : nums) { hash[i]++; } for (int i = 0 ; i < hash.length; i++) { if (hash[i] == 0 ) { return i; } } return 0 ; } }
原地哈希
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { public int missingNumber (int [] nums) { for (int i = 0 ; i < nums.length; i++) { if (nums[i] != i && nums[i] < nums.length) { int t = nums[i]; nums[i] = nums[nums[i]]; nums[t] = t; i--; } } for (int i = 0 ; i < nums.length; i++) { if (nums[i] != i) { return i; } } return nums.length; } }
数学公式
1 2 3 4 5 6 7 8 9 10 11 12 class Solution { public int missingNumber (int [] nums) { int sum = (nums.length + 1 ) * nums.length / 2 ; int temp = 0 ; for (int i : nums) { temp += i; } return sum - temp; } }
位运算,找缺失数、找出现一次数都是异或的经典应用
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution { public int missingNumber (int [] nums) { int sum = 0 ; for (int i = 1 ; i <= nums.length; i++) { sum ^= i; } for (int i : nums) { sum ^= i; } return sum; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class Solution { public int [] countBits(int n) { int [] result = new int [n + 1 ]; if (n == 0 ) { return result; } result[1 ] = 1 ; if (n == 1 ) { return result; } int start = 1 , end = 1 , cur = 2 ; while (cur <= n) { while (start <= end) { if (cur <= n) { result[cur++] = result[start]; } else { break ; } if (cur <= n) { result[cur++] = result[start] + 1 ; } else { break ; } start++; } end = cur - 1 ; } return result; } }
优化代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution { public int [] countBits(int n) { int [] result = new int [n + 1 ]; for (int i = 1 ; i <= n; i++) { if (i % 2 == 0 ) { result[i] = result[i / 2 ]; } else { result[i] = result[i / 2 ] + 1 ; } } return result; } }
1 2 3 4 5 6 class Solution { public int getSum (int a, int b) { return b == 0 ? a : getSum(a ^ b, (a & b) << 1 ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution { public char findTheDifference (String s, String t) { char temp = (char ) 0 ; for (int i = 0 ; i < s.length(); i++) { temp ^= s.charAt(i); } for (int j = 0 ; j < t.length(); j++) { temp ^= t.charAt(j); } return temp; } }
优化一下
1 2 3 4 5 6 7 8 9 10 11 class Solution { public char findTheDifference (String s, String t) { char temp = t.charAt(t.length() - 1 ); for (int i = 0 ; i < s.length(); i++) { temp ^= s.charAt(i); temp ^= t.charAt(i); } return temp; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public int hammingDistance (int x, int y) { int result = 0 ; int max = Math.max(x, y), min = Math.min(x, y); while (max != 0 ) { if (((max ^ min) & 1 ) != 0 ) { result++; } max >>= 1 ; min >>= 1 ; } return result; } }
同461
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public int minBitFlips (int start, int goal) { int result = 0 ; int max = Math.max(start, goal), min = Math.min(start, goal); while (max != 0 ) { if (((max ^ min) & 1 ) != 0 ) { result++; } max >>= 1 ; min >>= 1 ; } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 class Solution { public int findComplement (int num) { int temp = num, cur = 0 ; while (temp != 0 ) { temp >>= 1 ; cur <<= 1 ; cur += 1 ; } return (num ^ cur); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution { public int totalHammingDistance (int [] nums) { int len = nums.length, result = 0 ; for (int i = 0 ; i < 32 ; i++) { int count = 0 ; for (int j = 0 ; j < len; j++) { if ((nums[j] & 1 ) != 0 ) { count++; } nums[j] >>= 1 ; } result += (len - count) * count; } return result; } }
优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public int totalHammingDistance (int [] nums) { int len = nums.length, result = 0 ; for (int i = 0 ; i < 32 ; i++) { int count = 0 ; for (int num : nums) { count += (num >> i) & 1 ; } result += (len - count) * count; } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public boolean hasAlternatingBits (int n) { int last = (n & 1 ); n >>= 1 ; while (n != 0 ) { int t = n & 1 ; n >>= 1 ; if (last == t) { return false ; } last = t; } return true ; } }
优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public boolean hasAlternatingBits (int n) { n = n ^ (n >> 1 ); return (n & (n + 1 )) == 0 ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Solution { public int countPrimeSetBits (int left, int right) { boolean [] isLegal = getIsPrimeList(); int result = 0 ; for (int i = left; i <= right; i++) { int count = 0 , t = i; while (t != 0 ) { count += (t & 1 ); t >>= 1 ; } result += isLegal[count] ? 1 : 0 ; } return result; } public boolean [] getIsPrimeList() { boolean [] isPrime = new boolean [33 ]; for (int i = 2 ; i < 33 ; i++) { isPrime[i] = true ; for (int j = 2 ; j <= i / 2 ; j++) { if (i % j == 0 ) { isPrime[i] = false ; break ; } } } return isPrime; } }
优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public int countPrimeSetBits (int left, int right) { int result = 0 ; for (int i = left; i <= right; i++) { result += isPrime(Integer.bitCount(i)) ? 1 : 0 ; } return result; } public boolean isPrime (int x) { return x == 2 || x == 3 || x == 5 || x == 7 || x == 11 || x == 13 || x == 17 || x == 19 ; } }