Jump Game
Given an array of non-negative integers, you are initially positioned at the first index of the array. Each element in the array represents your maximum jump length at that position. Determine if you are able to reach the last index.
贪心:
1 public boolean canJump(int[] nums) { 2 if (nums == null || nums.length == 0) { 3 return false; 4 } 5 int finalIndex = 0; 6 for (int i = 0; i < nums.length; i++) { 7 if (finalIndex < i) { 8 return false; 9 } 10 finalIndex = Math.max(finalIndex, i + nums[i]); 11 } 12 return true; 13 }
Jump Game II ---not bug free
Given an array of non-negative integers, you are initially positioned at the first index of the array. Each element in the array represents your maximum jump length at that position. Your goal is to reach the last index in the minimum number of jumps.
方法一:直接使用O(n ^ 2)的DP超时了
方法二:类似于LIS的思想 O(nlogn)的解法
h[i]记录i步能够到达末尾的最小下标。遍历数组,如果刚好都能到达末尾,那么就是1,right = 1。如果nums[i] + i不能到达末尾,那么需要在h中找到它能到达谁,也就是第一个小于等于nums[i] + i的位置,这个位置下标就是当前位置最少需要跳的步数。把right赋值为这个步数。比如4116541 在遍历第一个之前的h数组为 6, 3, 2, 1现在0位置能够跳的最远为0 + 4 = 4。h第一个小于4的是3,下标是1,所以表明原数组第一个位置最少两步可以到达末尾。right也要更新。
1 /// 4 1 1 6 5 4 1 2 public int jump(int[] nums) { 3 if (nums == null || nums.length < 2) { 4 return 0; 5 } 6 int n = nums.length; 7 int[] h = new int[n]; // h[i]表示i步到达结尾的最小下标(希望下标越小越好,这样有利于前边的跳跃嘛) 8 h[0] = n - 1; 9 int right = 0; 10 for (int i = n - 2; i >= 0; i--) { 11 int maxReach = nums[i] + i; 12 if (maxReach >= n - 1) { 13 h[1] = i; 14 right = 1; 15 } else { 16 right = findFirstSmallOrEqual(h, 0, right, maxReach) + 1; 17 h[right] = i; 18 } 19 } 20 return right; 21 } 22 public int findFirstSmallOrEqual(int[] nums, int start, int end, int target) { 23 while (start + 1 < end) { 24 int mid = (start + end) / 2; 25 if (nums[mid] == target) { 26 end = mid; 27 } else if (nums[mid] < target) { 28 end = mid; 29 } else { 30 start = mid; 31 } 32 } 33 if (nums[start] <= target) { 34 return start; 35 } else { 36 return end; 37 } 38 }
方法三:贪心:记录当前步数最多跳到哪儿(edge),和当前步数加 1 最多跳到哪儿(maxReach)。遍历的时候就更新maxReach,只有遇到i > edge的时候才更新edge和minStep. O(n)
1 public int jump(int[] nums) { 2 if (nums == null || nums.length < 2) { 3 return 0; 4 } 5 int step = 0; // 最小步数 6 int edge = 0; // 当前步数最远可以跳到那儿 7 int nextEdge = nums[0]; // 当前步数 + 1 最远可以跳到那儿 8 for (int i = 1; i < nums.length; i++) { 9 if (i > edge) { 10 step++; 11 edge = nextEdge; 12 } 13 nextEdge = Math.max(nextEdge, nums[i] + i); 14 } 15 return step; 16 }
Best Time to Buy and Sell Stock II
def maxProfit(self, prices): """ :type prices: List[int] :rtype: int """ if not prices: return 0 res = 0 for i in range(1,len(prices)): if (prices[i] > prices[i - 1]): res += prices[i] - prices[i - 1] return res