文章目录
代码随想录开源LeetCode题单:代码随想录
1.LeetCode122
1.1 思路
由于没有限制交易次数,可以尽可能利用价格上涨的区间获利。
如果某天价格比前一天高,则可以视为当天卖出前一天买入的利润。多次交易的总利润等价于每天的上涨差值之和。
- 算法核心:
- 遍历价格数组:如果 prices[i] > prices[i-1],则将差值 prices[i] - prices[i-1] 累加到总利润中。
- 通过这样的贪心策略,不需要关心具体的买卖时机,保证所有上涨的利润都被捕获。
- 贪心策略有效性:
假设价格从 prices[i-1] 到 prices[i] 是递增的:即 prices[i] > prices[i-1]。贪心策略通过每天的差值累加,等效于在最低点买入,最高点卖出。 - 终止条件:
遍历完整个数组后,返回累计利润。
1.2 代码
class Solution {
public 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;
}
}
2.LeetCode55
2.1思路
-
核心思路:
- 维护一个变量 maxPos,表示当前可以跳跃到的最远位置。
- 遍历数组时,如果当前位置 i 超过了 maxPos,说明无法到达当前位置,因此返回 false。
- 遍历过程中,更新 maxPos 为 max(maxPos, i + nums[i])。
-
贪心策略:
- 每一步都尽可能跳得更远,从而保证最远可达的位置始终在当前范围内的最大值。
- 如果遍历完成后,始终没有返回 false,说明可以到达最后一个位置,返回 true。
-
终止条件:
- 如果当前索引 i > maxPos,说明当前位置不可达
- 如果遍历完成,返回 true,表示可以到达最后位置
2.2 代码
class Solution {
public boolean canJump(int[] nums) {
if (nums.length == 1) {
return true;
}
//覆盖范围, 初始覆盖范围应该是0,因为下面的迭代是从下标0开始的
int coverRange = 0;
//在覆盖范围内更新最大的覆盖范围
for (int i = 0; i <= coverRange; i++) {
coverRange = Math.max(coverRange, i + nums[i]);
if (coverRange >= nums.length - 1) {
return true;
}
}
return false;
}
}
3.LeetCode45
3.1 思路
从覆盖范围出发,不管怎么跳,覆盖范围内一定是可以跳到的,以最小的步数增加覆盖范围,覆盖范围一旦覆盖了终点,得到的就是最少步数!需要统计两个覆盖范围,当前这一步的最大覆盖和下一步最大覆盖。
如果移动下标达到了当前这一步的最大覆盖最远距离了,还没有到终点的话,那么就必须再走一步来增加覆盖范围,直到覆盖范围覆盖了终点。
3.2 代码
class Solution {
public int jump(int[] nums) {
int result = 0;
// 当前覆盖的最远距离下标
int end = 0;
// 下一步覆盖的最远距离下标
int temp = 0;
for (int i = 0; i <= end && end < nums.length - 1; ++i) {
temp = Math.max(temp, i + nums[i]);
// 可达位置的改变次数就是跳跃次数
if (i == end) {
end = temp;
result++;
}
}
return result;
}
}
4.LeetCode1005
4.1 思路
- 贪心算法:
- 局部最优:只找数值最小的正整数进行反转,当前数值和可以达到最大(例如正整数数组{5, 3, 1},反转1 得到-1 比 反转5得到的-5 大多了。
- 全局最优:整个数组和达到最大。
- 本题的解题步骤:
- 将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小
- 从前向后遍历,遇到负数将其变为正数,同时k自减
- 如果k还大于0,那么反复转变数值最小的元素,将k用完
- 求和
4.2 代码
class Solution {
public int largestSumAfterKNegations(int[] nums, int k) {
// 将数组按照绝对值大小从大到小排序(注意要按照绝对值的大小)
nums = IntStream.of(nums)
.boxed()
.sorted((o1, o2) -> Math.abs(o2) - Math.abs(o1))
.mapToInt(Integer::intValue).toArray();
int len = nums.length;
for (int i = 0; i < len; i++) {
//从前向后遍历,遇到负数将其变为正数,同时k--
if (nums[i] < 0 && k > 0) {
nums[i] = -nums[i];
k--;
}
}
// 如果k还大于0,那么反复转变数值最小的元素,将k用完
if (k % 2 == 1) nums[len - 1] = -nums[len - 1];
return Arrays.stream(nums).sum();
}
}