会在近期陆续地完成数组篇的整理,希望对找工作的小伙伴有所帮助。
1、Two Sum:两数相加为一固定值,求其下标。一次遍历数组,用一个hash表存储已经访问过的数及其下标,对于新访问的数value,查hash表中是否有target-value的值,如果有,程序输出,如果没有,继续访问下一个数直到访问完。
1 public int[] twoSum(int[] nums, int target) { 2 Maphash = new HashMap<>(); 3 for (int i=0; i ){ 4 if(hash.containsKey(target-nums[i])){ 5 return new int[]{hash.get(target-nums[i]),i}; 6 }else{ 7 hash.put(nums[i],i); 8 } 9 } 10 return new int[]{0,0}; 11 }
2、Median of Two Sorted Arrays:求两个有序数组的中位数。其实就是求第k大的数。首先比较两数组k/2处的数的大小,若a[k/2]
3、Container With Most Water:给一个数组,每一个元素表示一个高度,找两个元素和x轴围城的容器装下水的最大量。直接的做法是暴力求解,O(n2)复杂度。优化做法是,从两头向中间靠,比较两头元素的大小,大的不动,小的往中间移动。
1 public int maxArea(int[] height) { 2 int max = 0; 3 int left = 0; 4 int right = height.length - 1; 5 int curArea = 0; 6 while (left < right) { 7 curArea = (right - left) * (height[right] < height[left] ? height[right--] : height[left++]); 8 if (curArea > max) 9 max = curArea; 10 } 11 return max; 12 }
4、3Sum:在数组中求三个数相加等于0。先排序,然后遍历数组,两重循环。3个指针,外层循环遍历数组,内层循环遍历外层循环后面的数,如果和大于0,则指针往左移动,如果小于0,则往右移动。
1 public List> threeSum(int[] nums) { 2 List
> list = new ArrayList
>(); 3 Set
> set = new HashSet<>(); 4 sort(nums); 5 int j = 0; 6 int k = 0; 7 for (int i = 0; i < nums.length - 2; i++) { 8 j = i + 1; 9 k = nums.length - 1; 10 while (j < k) { 11 int x = nums[i] + nums[j] + nums[k]; 12 if (x == 0) { 13 List
innerList = new ArrayList<>(); 14 innerList.add(nums[i]); 15 innerList.add(nums[j]); 16 innerList.add(nums[k]); 17 if (!set.contains(innerList)) { 18 set.add(innerList); 19 list.add(innerList); 20 } 21 j = j + 1; 22 k = k - 1; 23 } else if (x > 0) { 24 k = k - 1; 25 } else { 26 j = j + 1; 27 } 28 } 29 } 30 return list; 31 }
5、3Sum Closest:类似3Sum
6、4Sum:类似3Sum
7、Remove Duplicates from Sorted Array:有序数组去重,返回剩余数的个数
1 public int removeDuplicates(int[] nums) { 2 if (nums.length == 0) return 0; 3 int index = 0; 4 for (int i = 1; i < nums.length; i++) { 5 if (nums[index] != nums[i]) { 6 nums[++index] = nums[i]; 7 } 8 } 9 return index + 1; 10 }
8、Remove Element:数组中移除给定的数,返回剩余数的个数
1 public int removeElement(int[] nums, int val) { 2 int index=0; 3 for(int i =0; i){ 4 if(nums[i] != val) nums[index++]=nums[i]; 5 } 6 return index; 7 }
9、Next Permutation:数组表示一个整数,返回下一个排列数,如果没有比原数组大的排列数,则返回最小的排列数
1 public void nextPermutation(int[] nums) { 2 if(nums==null || nums.length<2) return; 3 int len = nums.length; 4 // 从右向左遍历,找到第一个前一个数小于后一个的数(升序对),记value=nums[i-1] 5 int i = len - 1; 6 while (i>0 && nums[i-1]>=nums[i]){ 7 i--; 8 } 9 if(i==0){ 10 reverse(nums, 0, len-1); // 反转数组 11 }else{ 12 // 从右向左遍历,找到第一个大于value的数 13 int j = i-1; 14 int k = len -1; 15 while(nums[j]>=nums[k]){ 16 k--; 17 } 18 int temp = nums[j]; 19 nums[j] = nums[k]; 20 nums[k] = temp; 21 reverse(nums, i, len-1); 22 } 23 }
10、Search in Rotated Sorted Array:在循环有序的数组(数没有重复)中查询一个数,返回这个数的下标,没有则返回-1
1 public int search(int[] nums, int target) { 2 if(nums==null || nums.length==0) return -1; 3 // 找到最小值,即旋转中心 4 int n=nums.length; 5 int lo=0, hi=n-1; 6 while(lo<hi){ 7 int mid=(hi-lo)/2+lo; 8 if(nums[mid]>nums[hi]) lo=mid+1; 9 else hi=mid; 10 } 11 int pivot=lo; 12 lo=0; 13 hi=n-1; 14 while(lo<=hi){ 15 int mid=(hi-lo)/2+lo; 16 int realmid=(mid+pivot)%n; 17 if(nums[realmid]==target) return realmid; 18 else if(nums[realmid]>target) hi=mid-1; 19 else lo=mid+1; 20 } 21 return -1; 22 }
11、Search for a Range:找到给定的数在有序数组中的下标区间,两次二分搜索,一次找左边界,一次找右边界
1 public int[] searchRange(int[] nums, int target) { 2 int[] ret = {-1,-1}; 3 if(nums==null || nums.length==0) return nums; 4 int n=nums.length; 5 int lo=0, hi=n-1; 6 while(lo<hi){ 7 int mid=(hi-lo)/2+lo; 8 if(nums[mid]; 9 else hi=mid; 10 } 11 if(nums[lo]!=target) return ret; 12 ret[0]=lo; 13 14 lo=0; 15 hi=n-1; 16 while(lo<hi){ 17 int mid=(hi-lo)/2+lo+1; // 保证偏向右边 18 if(nums[mid]>target) hi=mid-1; 19 else lo=mid; 20 } 21 ret[1]=lo; 22 return ret; 23 }
12、Search Insert Position:二分查找
13、Combination Sum:求数组中元素等于给定的数的集合,允许重复,回溯法
1 public List> combinationSum(int[] candidates, int target) { 2 List
> res = new ArrayList
>(); 3 if(candidates == null || candidates.length == 0) 4 return res; 5 List
list = new ArrayList<>(); 6 helper(candidates, target, 0, list, res); 7 return res; 8 } 9 public void helper(int[] candidates, int target, int start, List temp, List > res) { 10 if(target == 0){ 11 res.add(new ArrayList<>(temp)); 12 return; 13 } 14 if(target < 0) return; 15 for (int i = start; i < candidates.length; i++){ 16 temp.add(candidates[i]); 17 helper(candidates, target-candidates[i], i, temp, res); 18 temp.remove(temp.size() - 1); 19 } 20 }
14、Combination Sum II:求数组中元素等于给定的数的集合,数组中的元素只能用一次,回溯法
1 public List> combinationSum2(int[] candidates, int target) { 2 List
> res = new ArrayList
>(); 3 if(candidates.length == 0 || candidates == null) 4 return res; 5 List
list = new ArrayList<>(); 6 Arrays.sort(candidates); 7 helper(candidates, target, 0, list, res); 8 return res; 9 } 10 public void helper(int[] candidates, int target, int start, List temp, List > res) { 11 if(target == 0){ 12 res.add(new ArrayList<>(temp)); 13 return; 14 } 15 else if(target < 0) 16 return; 17 else { 18 for (int i = start; i < candidates.length; i++){ 19 // 跳过重复元素 20 if(i>start && candidates[i]==candidates[i-1]) 21 continue; 22 temp.add(candidates[i]); 23 helper(candidates, target-candidates[i], i+1, temp, res); 24 temp.remove(temp.size() - 1); 25 } 26 } 27 }
15、First Missing Positive:无序数组,找到第一个缺失的正数,主要思想是将正确的数放到正确的位置上
1 public int firstMissingPositive(int[] nums) { 2 if(nums == null || nums.length == 0) return 1; 3 int n = nums.length; 4 for (int i=0; i){ 5 while(nums[i]>0 && nums[i]<=n && nums[i]!=nums[nums[i]-1]) swap(nums, i, nums[i]-1); 6 } 7 for(int i=0; i ){ 8 if(nums[i]!=i+1) return i+1; 9 } 10 return n+1; 11 }
16、Trapping Rain Water:求最大的积水量。解法:先找到最大高度的下标,然后分别从两边往最大高度靠,同时维护一个当前最大值变量,积水量就是当前最大值减去当前高度。
1 public int trap(int[] height) { 2 if (height==null || height.length <= 2) return 0; 3 // 找最大高度 4 int maxIndex=0; 5 int max=0; 6 for(int i=0; i){ 7 if(height[i]>max){ 8 max=height[i]; 9 maxIndex=i; 10 } 11 } 12 int result=0; 13 int curMax=0; 14 for(int i=0; i ){ 15 if(height[i]<curMax){ 16 result += curMax-height[i]; 17 }else{curMax=height[i];} 18 } 19 curMax=0; 20 for(int i=height.length-1; i>maxIndex; i--){ 21 if(height[i] height[i]; 22 else curMax=height[i]; 23 } 24 return result; 25 }
17、Jump Game II:给定一个数组,求数组头到数组尾的最少的步数。贪心法。
1 public int jump(int[] nums) { 2 if(nums==null || nums.length==0) return 0; 3 int dis=0; 4 int edge=0; 5 int steps=0; 6 for(int i=0; i){ 7 dis=Math.max(dis, i+nums[i]); 8 if(dis>=nums.length-1) return steps+1; 9 // 判断是否在一次跳转之内,只有等于最大边界时才会步数加1 10 if(edge == i){ 11 edge = dis; 12 steps++; 13 } 14 } 15 return 0; 16 }
18、Rotate Image:顺时针旋转n*n矩阵。先转置,再左右翻转。
1 public void rotate(int[][] matrix) { 2 if(matrix==null || matrix.length==0) return; 3 int n = matrix.length; 4 int tmp; 5 for (int i = 0; i < n; ++i) { 6 for (int j = i; j < n; ++j) { 7 tmp = matrix[i][j]; 8 matrix[i][j] = matrix[j][i]; 9 matrix[j][i] = tmp; 10 } 11 } 12 for(int i=0; i){ 13 reverse(matrix[i]); 14 } 15 }
19、Maximum Subarray:求数组的最大子串和。
1 public int maxSubArray(int[] nums) { 2 if(nums==null || nums.length==0) return 0; 3 int max=nums[0]; 4 int curSum=0; 5 for(int i=0; i){ 6 curSum=Math.max(nums[i], curSum+nums[i]); 7 max=Math.max(max, curSum); 8 } 9 return max; 10 }
20、Spiral Matrix:螺旋输出矩阵的元素
1 public ListspiralOrder(int[][] matrix) { 2 List res = new ArrayList<>(); 3 int m = matrix.length; 4 if (m < 1) return res; 5 int n = matrix[0].length; 6 int left = 0; 7 int right = n-1; 8 int up = 0; 9 int down = m-1; 10 while (left <= right && up <= down) { 11 // traverse right 12 for (int i = left; i <= right; i++) { 13 res.add(matrix[up][i]); 14 } 15 up++; 16 // traverse down 17 for (int i = up; i <= down; i++) { 18 res.add(matrix[i][right]); 19 } 20 right--; 21 // traverse left 22 if (up <= down) { 23 for (int i = right; i >= left; i--) { 24 res.add(matrix[down][i]); 25 } 26 } 27 down--; 28 // traverse up 29 if (left <= right) { 30 for (int i = down; i >= up; i--) { 31 res.add(matrix[i][left]); 32 } 33 } 34 left++; 35 } 36 37 return res; 38 }
21、Jump Game:给定一个数组,判断能否从数组头到达数组尾。贪心法。维护一个变量,记录当前位置能到达的最远的距离,当最远距离超出数组长度,即可判断能到达数组尾。
1 public boolean canJump(int[] nums) { 2 if(nums==null || nums.length==0) return false; 3 int dis=0; 4 for(int i=0; i){ 5 dis = Math.max(dis, i+nums[i]); 6 if(dis >= nums.length-1) return true; 7 } 8 return false; 9 }
22、Merge Intervals:合并区间。先按照区间的前端进行排序操作,再查看是否出现覆盖的情况。
1 public Listmerge(List intervals) { 2 List res = new ArrayList<>(); 3 int n = intervals.size(); 4 if (n < 1) return res; 5 // Sort by ascending starting point using an anonymous Comparator 6 Collections.sort(intervals, new Comparator () { 7 @Override 8 public int compare(Interval i1, Interval i2) { 9 return Integer.compare(i1.start, i2.start); 10 } 11 }); 12 int start = intervals.get(0).start; 13 int end = intervals.get(0).end; 14 for(int i=1; i ){ 15 Interval curInteval = intervals.get(i); 16 if(curInteval.start <= end){ 17 end = Math.max(end, curInteval.end); 18 } 19 else{ 20 res.add(new Interval(start, end)); 21 start = curInteval.start; 22 end = curInteval.end; 23 } 24 } 25 }
23、Insert Interval:给定一个按前端排好序的区间数组,现有另外一个区间,求插入并合并后的区间。
1 public Listinsert(List intervals, Interval newInterval) { 2 int i=0; 3 while(i < intervals.size() && intervals.get(i).end < newInterval.start) i++; // 是否可以用二分找到这个i? 4 while(i newInterval.end){ 5 newInterval = new Interval(Math.min(intervals.get(i).start, newInterval.start), Math.max(intervals.get(i).end, newInterval.end)); 6 intervals.remove(i); 7 } 8 intervals.add(i,newInterval); 9 return intervals; 10 }
24、Spiral Matrix II:生成螺旋的矩阵
1 public int[][] generateMatrix(int n) { 2 int[][] matrix = new int[n][n]; 3 if (n < 1) 4 return matrix; 5 int count = 1; 6 int left = 0; 7 int right = n-1; 8 int up = 0; 9 int down = n-1; 10 while (left <= right && up <= down) { 11 for (int i = left; i <= right; i++) { 12 matrix[up][i] = count; 13 count++; 14 } 15 up++; 16 for (int i = up; i <= down; i++) { 17 matrix[i][right] = count; 18 count++; 19 } 20 right--; 21 if (up <= down) { 22 for (int i = right; i >= left; i--) { 23 matrix[down][i] = count; 24 count++; 25 } 26 down--; 27 } 28 if (left <= right) { 29 for (int i = down; i >= up; i--) { 30 matrix[i][left] = count; 31 count++; 32 } 33 left++; 34 } 35 } 36 return matrix; 37 }
25、Unique Paths:求从左上到右下的路径数。
public int uniquePaths(int m, int n) { int[] paths = new int[n+1]; Arrays.fill(paths, 1); paths[0] = 0; for(int i=0; i){ for(int j=0; j ){ paths[j+1] = paths[j+1] + paths[j]; } } return paths[n]; }
26、Unique Paths II:存在障碍的情况下,求从左上到右下的路径数。
1 public int uniquePathsWithObstacles(int[][] obstacleGrid) { 2 int n = obstacleGrid.length; 3 int m = obstacleGrid[0].length; 4 int[][] p = new int[n][m]; 5 // 初始化第一行 6 for (int i = 0; i < m; i++){ 7 p[0][i] = 1 - obstacleGrid[0][i]; 8 if (p[0][i] == 0) break; 9 } 10 // 初始化第一列 11 for (int j = 0; j < n; j++){ 12 p[j][0] = 1 - obstacleGrid[j][0]; 13 if (p[j][0] == 0) break; 14 } 15 for ( int i = 1; i < n; i++){ 16 for (int j = 1; j < m; j++) { 17 if(obstacleGrid[i][j] == 1) 18 p[i][j] = 0; 19 else p[i][j] = p[i-1][j] + p[i][j-1]; 20 } 21 } 22 return p[n-1][m-1]; 23 }
27、Minimum Path Sum:求从左上到右下的最小的路径的长度,只能向右或向下走。
1 public int minPathSum(int[][] grid) { 2 if(grid==null || grid.length==0) return 0; 3 int m = grid.length; 4 int n = grid[0].length; 5 int[][] p = new int[m][n]; 6 for (int i = 0; i < m; i++) { 7 for (int j = 0; j < n; j++) { 8 if (i == 0 && j == 0) 9 p[i][j] = grid[i][j]; 10 else if (i == 0 && j > 0) 11 p[i][j] = p[i][j-1] + grid[i][j]; 12 else if (i > 0 && j == 0) 13 p[i][j] = p[i-1][j] + grid[i][j]; 14 else 15 p[i][j] = Math.min(p[i-1][j], p[i][j-1]) + grid[i][j]; 16 } 17 } 18 return p[m-1][n-1]; 19 }
28、Plus One:数组加1
public int[] plusOne(int[] digits) { int carry = 1; for(int i=digits.length-1; i>=0; i--){ carry += digits[i]; digits[i] = carry % 10; carry /= 10; } if(carry==0) return digits; else{ int[] newdigits = new int[digits.length+1]; newdigits[0]=1; for(int i=1; i){ newdigits[i]=digits[i-1]; } return newdigits; } }
29、Set Matrix Zeroes:当(i,j)=0是,把第i行和第j列置为0
1 public void setZeroes(int[][] matrix) { 2 boolean col0 = false; 3 for (int i = 0; i < matrix.length; i++) { 4 if(matrix[i][0]==0) col0=true; 5 for (int j = 1; j < matrix[0].length; j++) { 6 if (matrix[i][j] == 0) { 7 matrix[0][j] = 0; 8 matrix[i][0] = 0; 9 } 10 } 11 } 12 for (int i = matrix.length-1; i>=0; i--) { 13 for (int j = matrix[0].length-1; j>=1; j--) { 14 if (matrix[0][j] == 0 || matrix[i][0] == 0) { 15 matrix[i][j] = 0; 16 } 17 } 18 if(col0) matrix[i][0]=0; 19 } 20 }
30、Search a 2D Matrix:在矩阵里查找数。二分查找
1 public boolean searchMatrix(int[][] matrix, int target) { 2 if(matrix==null || matrix[0].length==0) return false; 3 int m=matrix.length; 4 int n=matrix[0].length; 5 int lo=0; 6 int hi=m*n-1; 7 int mid; 8 while(lo<=hi){ 9 mid=(hi-lo)/2+lo; 10 int row=mid/n; 11 int col=mid%n; 12 if(matrix[row][col]==target) return true; 13 else if(matrix[row][col] > target) hi = mid-1; 14 else lo = mid + 1; 15 } 16 return false; 17 }
31、Sort Colors:给定一个数组,元素只有0,1,2,给它排序。可以用计数排序,也可以用交换。
1 public void sortColors(int[] nums) { 2 if(nums==null || nums.length==0) return; 3 int lo=0; 4 int hi=nums.length-1; 5 int i=0; 6 while(i<=hi){ 7 if(nums[i]==0) swap(nums, i++, lo++); 8 else if(nums[i]==2) swap(nums, i, hi--); 9 else{i++;} 10 } 11 }
32、Subsets:求一个集合的所有子集
1 public List> subsets(int[] nums) { 2 List
> res = new ArrayList<>(); 3 List
list = new ArrayList<>(); 4 res.add(list); 5 for(int i=0; i ){ 6 int size = res.size(); 7 for(int k=0; k ){ 8 List newList = new ArrayList<>(res.get(k)); 9 newList.add(nums[i]); 10 res.add(newList); 11 } 12 } 13 return res; 14 }
1 public List> subsets(int[] nums) { 2 Arrays.sort(nums); 3 List
> res = new ArrayList<>(); 4 int totalNumber = 1 << nums.length; 5 for(int i=0; i
){ 6 List set = new ArrayList<>(); 7 for(int j=0; j ){ 8 if(((i>>>j) & 0x1) == 1) set.add(nums[j]); 9 } 10 res.add(set); 11 } 12 return res; 13 }
33、Word Search: 在二维字符数组中,查找单词,回溯法
1 public boolean exist(char[][] board, String word) { 2 for(int i = 0; i < board.length; i++) 3 for(int j = 0; j < board[0].length; j++){ 4 if(exist(board, i, j, word, 0)) return true; 5 } 6 return false; 7 } 8 private boolean exist(char[][] board, int i, int j, String word, int ind){ 9 if(ind == word.length()) return true; 10 if(i > board.length-1 || i <0 || j<0 || j >board[0].length-1 || board[i][j]!=word.charAt(ind)) return false; 11 char ch=board[i][j]; 12 board[i][j]='*'; 13 boolean result = exist(board, i-1, j, word, ind+1) || 14 exist(board, i, j-1, word, ind+1) || 15 exist(board, i, j+1, word, ind+1) || 16 exist(board, i+1, j, word, ind+1); 17 board[i][j] = ch; 18 return result; 19 }
34、Remove Duplicates from Sorted Array II: 数组已排序,去除数组中重复的元素,允许出现两次
1 public int removeDuplicates(int[] nums) { 2 if(nums.length <= 2) return nums.length; 3 int index=0; 4 int p=1; 5 int counter=1; 6 while(p<nums.length){ 7 if(nums[p] == nums[index]){ 8 if(counter == 2){ 9 p++; 10 } 11 else{ 12 nums[++index] = nums[p]; 13 p++; 14 counter = 2; 15 } 16 } 17 else { 18 nums[++index] = nums[p]; 19 p++; 20 counter = 1; 21 } 22 } 23 return index+1; 24 }
35、Search in Rotated Sorted Array II: 在循环有序数组中查找,数组中有重复的数
1 public class Solution { 2 public boolean search(int[] nums, int target) { 3 if (nums.length < 1) 4 return false; 5 int start = 0; 6 int end = nums.length - 1; 7 while (start < end) { 8 int mid = start + (end-start)/2; 9 if (nums[mid] == target) return true; 10 11 if (nums[start] < nums[mid]) { 12 if (target < nums[mid] && target >= nums[start]) 13 end = mid - 1; 14 else start = mid + 1; 15 } 16 else if (nums[start] > nums[mid]){ 17 if (target > nums[mid] && target <= nums[end]) 18 start = mid + 1; 19 else end = mid - 1; 20 } 21 else { 22 start++; 23 } 24 } 25 return target == nums[start]; 26 } 27 }
36、Largest Rectangle in Histogram: 求最大的长方形面积
1 public int largestRectangleArea(int[] heights) { 2 int maxArea = 0; 3 Stackstack = new Stack<>(); 4 int i=0; 5 int height = 0; 6 int area = 0; 7 while(i <= heights.length){ 8 if(i < heights.length) height = heights[i]; 9 else height = 0; 10 if(stack.isEmpty() || height >= heights[stack.peek()]){ 11 stack.push(i++); 12 } 13 else{ 14 int index = stack.pop(); 15 if(stack.isEmpty()) area = i * heights[index]; 16 else { 17 area = (i-stack.peek()-1) * heights[index]; 18 } 19 maxArea = Math.max(area, maxArea); 20 } 21 } 22 return maxArea; 23 }
37、Maximal Rectangle: 利用36题结论
1 public int maximalRectangle(char[][] matrix) { 2 int m = matrix.length; 3 if (m < 1){ 4 return 0; 5 } 6 int n = matrix[0].length; 7 int[][] heights = new int[m][n+1]; 8 for(int i = 0; i < m; i++){ 9 for(int j = 0; j < n; j++) { 10 if(matrix[i][j] == '0'){ 11 heights[i][j] = 0; 12 }else { 13 heights[i][j] = i == 0 ? 1 : heights[i - 1][j] + 1; 14 } 15 } 16 } 17 int maxArea=0; 18 for(int i = 0; i < m; i++){ 19 int area = maxAreaInHist(heights[i]); 20 if(area > maxArea){ 21 maxArea=area; 22 } 23 } 24 return maxArea; 25 }
38、Merge Sorted Array: 类似于插入排序
39、Subsets II: 数组子集,数组中有重复的元素
1 public List> subsetsWithDup(int[] nums) { 2 int length = nums.length; 3 Arrays.sort(nums); 4 5 List
> res = new ArrayList<>(); 6 List
emptyList = new ArrayList<>(); 7 res.add(emptyList); 8 9 for (int i = 0; i < length; i++) { 10 int count = 1; 11 while (i+1< length && nums[i] == nums[i+1]) { 12 count++; 13 i++; 14 } 15 int size = res.size(); 16 for (int j = 0; j < size; j++) { 17 for (int k = 0; k < count; k++) { 18 List newList = new ArrayList<>(res.get(j)); 19 for (int p = 0; p <= k; p++) 20 newList.add(nums[i]); 21 res.add(newList); 22 } 23 } 24 } 25 return res; 26 }
40、Construct Binary Tree from Preorder and Inorder Traversal: 根据先序和中序遍历构建树
构建过程,在中序遍历中找根节点的下标可以用hashmap加速
41、Construct Binary Tree from Inorder and Postorder Traversal: 根据中序和后序遍历构建树
构建过程,在中序遍历中找根节点的下标可以用hashmap加速
42、Pascal's Triangle: 生成杨辉三角
1 public List> generate(int numRows) { 2 List
> res = new ArrayList<>(); 3 4 if (numRows < 1) return res; 5 List
first = new ArrayList<>(); 6 first.add(1); 7 res.add(first); 8 for (int i = 2; i <= numRows; i++) 9 { 10 List list = new ArrayList<>(); 11 List preList = res.get(i-2); 12 for (int j = 0; j < i; j++) 13 { 14 if (j == 0) 15 list.add(1); 16 else if (j == i-1) 17 list.add(1); 18 else 19 { 20 list.add(preList.get(j-1)+preList.get(j)); 21 } 22 } 23 res.add(list); 24 } 25 return res; 26 }
43、Pascal's Triangle II: 生成第k个杨辉三角
1 public ListgetRow(int rowIndex) { 2 List res = new ArrayList<>(); 3 if (rowIndex < 0) 4 return res; 5 6 for (int i = 0; i <= rowIndex; i++) 7 { 8 res.add(0, 1); 9 for (int j = 1; j < res.size()-1; j++) 10 { 11 res.set(j, res.get(j)+res.get(j+1)); 12 } 13 } 14 return res; 15 }
44、Triangle: 求最短路径
1 public int minimumTotal(List> triangle) { 2 if (triangle == null || triangle.size() == 0) 3 return 0; 4 5 int [] sum = new int[triangle.size()]; 6 for (int i = 0; i < triangle.size(); i++) 7 sum[i] = triangle.get(triangle.size()-1).get(i); 8 9 for (int i = triangle.size()-2; i >= 0; i--) 10 { 11 for (int j = 0; j <= i; j++) 12 sum[j] = Math.min(sum[j], sum[j+1]) + triangle.get(i).get(j); 13 } 14 return sum[0]; 15 16 }
45、Best Time to Buy and Sell Stock:
46、Best Time to Buy and Sell Stock II:
47、Best Time to Buy and Sell Stock III:
48、Word Ladder II:
49、Longest Consecutive Sequence:
50、Maximum Product Subarray:
51、Find Minimum in Rotated Sorted Array:
52、Find Minimum in Rotated Sorted Array II:
53、Find Peak Element:
54、Missing Ranges:
55、Two Sum II - Input array is sorted:
56、Majority Element:
57、Rotate Array:
58、Minimum Size Subarray Sum:
59、Combination Sum III:给定数k和n,求所有的k个数之和等于n的集合,其中k个数中不允许重复的数,并且数字大小为1到9。回溯法
1 public List> combinationSum3(int k, int n) 2 { 3 List
> result = new ArrayList<>(); 4 List
temp = new ArrayList<>(); 5 boolean[] visited = new boolean[10]; 6 helper(k, n, 1, 0, visited, temp, result); 7 return result; 8 } 9 public void helper(int k, int n, int start, int sum, boolean[] visited, List temp, List > res) 10 { 11 if (sum == n && temp.size() == k){ 12 res.add(new ArrayList<>(temp)); 13 return; 14 } 15 if (sum > n || temp.size() > k) return; 16 for (int i = start; i < 10; i++){ 17 if (visited[i]) 18 continue; 19 if (temp.size() > 0 && temp.get(temp.size()-1) > i) 20 continue; 21 temp.add(i); 22 visited[i] = true; 23 helper(k, n, start+1, sum+i, visited, temp, res); 24 temp.remove(temp.size()-1); 25 visited[i] = false; 26 } 27 }
60、Contains Duplicate:
61、Contains Duplicate II:
62、Summary Ranges:
63、Majority Element II:
64、Product of Array Except Self:
65、Shortest Word Distance:
66、Shortest Word Distance III:
67、3Sum Smaller:
68、Missing Number:
69、Find the Celebrity:
70、Wiggle Sort:
71、Move Zeroes:
72、Find the Duplicate Number:
73、Game of Life:
74、Range Addition:
75、Patching Array:给出一个从小到大排好序的整数数组nums和一个整数n,在数组中添加若干个补丁(元素)使得[1,n]的区间内的所有数都可以表示成nums中若干个数的和。返回最少需要添加的补丁个数。
1 public class Solution { 2 /** 3 定义一个当前数字i之前的数组合能到达的最小上界minUpper,如表示的数范围是1-m,则定义上界为minUpper=m+1 4 循环如下: 5 上界minUpper <= N: 6 如果当前数字i <= minUpper: 7 更新上界:minUpper = minUpper + i 8 如果当前数字i > minUpper:说明需要添加补丁数字minUpper,并且更新此时的上界minUpper=minUpper+minUpper; 9 */ 10 public int minPatches(int[] nums, int n) { 11 int minUpper = 1; 12 int index = 0; 13 int missingCounter = 0; 14 while (minUpper <= n) { 15 if(index < nums.length && nums[index] <= minUpper) { 16 minUpper += nums[index]; 17 index++; 18 } 19 else { 20 //System.out.println(minUpper); 21 minUpper += minUpper; 22 missingCounter ++; 23 } 24 } 25 return missingCounter; 26 } 27 }
转载于:https://www.cnblogs.com/shizhh/p/5717425.html