买卖股票2
核心思路
-
贪心算法
-
如果想到其实最终利润是可以分解的,那么本题就很容易了!
如何分解呢?
假如第 0 天买入,第 3 天卖出,那么利润为:prices[3] - prices[0]。
相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])。
此时就是把利润分解为每天为单位的维度,而不是从 0 天到第 3 天整体去考虑!
-
要求最大利润, 那就拆分成每天都能获得正利润. 这样汇总之后就是最大利润了
题解
-
自己写的
javapublic int maxProfit(int[] prices) { int maxProfit = 0; int preProfit = 0; int prePrice = prices[0]; for (int i = 1; i < prices.length; i++) { if (prices[i] < prePrice) { maxProfit += preProfit; preProfit = 0; } else { preProfit = preProfit + prices[i] - prePrice; } prePrice = prices[i]; } return maxProfit + preProfit; } -
优化
javapublic int maxProfit(int[] prices) { int result = 0; for (int i = 1; i < prices.length; i++) { //只收集 每天卖出是正利润的. 全局下就是最大利润 result += Math.max(prices[i] - prices[i - 1], 0); } return result; }
-
跳跃游戏
核心思路
-
要求最终能不能跳跃到最后位置, 只需要找到每个元素可跳跃的最大范围, 这样到最后, 每个元素的最大范围都求出来了, 那么全局的可跳跃的最大范围也就求出来了
javapublic boolean canJump(int[] nums) { if (nums.length <= 1) return true; int max = nums[0]; for (int i = 1; i <= max; i++) { max = Math.max(max, i + nums[i]); if (max >= nums.length - 1) { return true; } } return false; }
跳跃游戏2
核心思路
-
核心依然是求每个元素的最大跳跃范围.
-
只是 在该元素的跳跃范围内, 要找到 其中的可跳跃范围最大的某个元素. 直到执行到范围末尾, count++. 并更新最大跳跃范围
javapublic int jump(int[] nums) { if (nums.length <= 1) return 0; int count = 0; //当前的最大范围 int curDistance = 0; //当前范围内的, 元素的可跳跃的最大范围 int maxDistance = 0; for (int i = 0; i < nums.length; i++) { maxDistance = Math.max(maxDistance, i + nums[i]); if (maxDistance >= nums.length - 1) { return ++count; } if (i == curDistance) { count++; curDistance = maxDistance; } } return count; }
K次取反后最大化的数组和
核心思路
- 这道题要怎么贪心呢, 正数越多值就越大, 那就是尽可能的将负数转正
- 如果负数全部转正之后, k还没用完呢?
- 那就是第二个贪心, 只对值最小的一个数进行取反, 这样得到的和就是最大的
题解
java
public static int largestSumAfterKNegations(int[] nums, int k) {
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
if(nums[i] < 0 && k>0){
k--;
nums[i] = -nums[i];
}
}
Arrays.sort(nums);
if(k % 2 == 1) nums[0] = -nums[0];
return IntStream.of(nums).sum();
}
- 将数组根据绝对值大小进行排序, 这样就不用第二次排序了
java
public static int largestSumAfterKNegations(int[] nums, int k) {
nums = IntStream.of(nums).boxed().sorted((a, b) -> Math.abs(b) - Math.abs(a)).mapToInt(Integer::valueOf).toArray();
for (int i = 0; i < nums.length; i++) {
if (nums[i] < 0 && k > 0) {
k--;
nums[i] = -nums[i];
}
}
if (k % 2 == 1) nums[nums.length - 1] = -nums[nums.length - 1];
return IntStream.of(nums).sum();
}