122. 买卖股票的最佳时机 II
题目描述
给定一个数组 prices,它的第 i 个元素是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:
- 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
解题思路
-
方法一:模拟买卖过程
- 使用变量
front记录买入价格,used标记是否已经买入股票。 - 遍历数组,计算每天的价格差
pre = prices[i+1] - prices[i]:- 如果
pre > 0且未买入(used == false),记录买入价格front并标记已买入。 - 如果
pre < 0且已买入(used == true),卖出当前股票,将利润加入总利润count,并重置标记。
- 如果
- 遍历结束后,若股票仍未卖出(
used == true),则在最后一天卖出并计算利润。 - 时间复杂度:O(n),空间复杂度:O(1)。
- 使用变量
-
方法二:贪心算法
- 只要价格上涨,即
pre = prices[i] - prices[i-1] > 0,直接将差值加入总利润count。 - 不需要记录具体的买卖操作,只需累加所有的上涨区间。
- 时间复杂度:O(n),空间复杂度:O(1)。
- 只要价格上涨,即
Java代码
class Solution {
public int maxProfit(int[] prices) {
int count = 0;
int front = 0;
int pre = 0;
boolean used = false;
for(int i=0;i<prices.length-1;i++){
pre = prices[i+1]-prices[i];
if(pre > 0 && used == false){
front = prices[i];
used =true;
}
if(pre<0 && used == true){
count = count + prices[i] - front;
used =false;
}
}
if(prices[prices.length-1]>front && used == true ){
count = count + prices[prices.length-1] - front;
}
return count;
}
}
class Solution {
public int maxProfit(int[] prices) {
int count =0;
int pre =0;
for(int i=1;i<prices.length;i++){
pre = prices[i]-prices[i-1];
if(pre > 0){
count = count + pre;
}
}
return count;
}
}
55. 跳跃游戏
题目描述
给定一个非负整数数组 nums,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
解题思路
-
方法一:贪心算法(手动模拟最大跳跃)
- 维护一个变量
maxcount,记录当前可以跳跃的最大距离。 - 遍历数组:
- 如果当前位置的最大跳跃值
nums[i]大于maxcount,则更新maxcount。 - 如果
nums.length - 1 - i <= maxcount,说明可以跳到最后一个位置,直接返回true。 - 如果
maxcount减少到 0,说明无法继续前进,返回false。
- 如果当前位置的最大跳跃值
- 时间复杂度:O(n),空间复杂度:O(1)。
- 维护一个变量
-
方法二:覆盖范围法
- 维护一个变量
coverRange,表示当前能覆盖的最远位置。 - 遍历数组:
- 对每个位置
i,更新coverRange = Math.max(coverRange, nums[i] + i)。 - 如果
coverRange已经大于或等于数组的最后一个位置,则返回true。 - 如果遍历到
coverRange之外的位置,说明无法到达最后一个位置,返回false。
- 对每个位置
- 时间复杂度:O(n),空间复杂度:O(1)。
- 维护一个变量
Java代码
class Solution {
public boolean canJump(int[] nums) {
int count = 0;
int maxcount = 0;
for(int i=0;i<nums.length-1;i++){
if(maxcount<nums[i]){
maxcount = nums[i];
}
if(nums.length-1-i<maxcount){
return true;
}
if(maxcount<=0){
return false;
}
maxcount--;
}
return true;
}
}
class Solution {
public boolean canJump(int[] nums) {
if (nums.length == 1) {
return true;
}
int coverRange = 0;
for(int i=0;i <= coverRange;i++){
coverRange = Math.max(coverRange,nums[i]+i);
if (coverRange >= nums.length-1){
return true;
}
}
return false;
}
}
45. 跳跃游戏 II
题目描述
给定一个非负整数数组 nums,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
目标是使用最少的跳跃次数到达数组的最后一个位置。
解题思路
- 贪心算法
- 维护两个变量:
coverRange:当前跳跃范围。maxcoverRange:在当前范围内能跳跃到的最远距离。
- 遍历数组:
- 如果
maxcoverRange超过当前coverRange,更新coverRange = maxcoverRange,并增加跳跃次数count++。 - 如果
coverRange已经覆盖到数组的最后一个位置,则退出循环。
- 如果
- 时间复杂度:O(n),空间复杂度:O(1)。
- 维护两个变量:
Java代码
class Solution {
public int jump(int[] nums) {
if(nums.length<2){
return nums.length-1;
}
int coverRange = 0;
int maxcoverRange = 0;
int count = 0;
for(int i = 0;i<=coverRange;i++){
if(maxcoverRange<i+nums[i]){
maxcoverRange = i+nums[i];
}
if(coverRange <=i && maxcoverRange > coverRange ){
coverRange = maxcoverRange;
count++;
}
if(coverRange >= nums.length-1){
break;
}
}
return count;
}
}
1005. K 次取反后最大化的数组和
题目描述
给定一个整数数组 nums,我们只能用以下方法修改该数组:
选择某个索引 i 并将 nums[i] 替换为 -nums[i],然后总共重复这个过程 K 次。(可以多次选择同一个索引 i。)
以这种方式修改数组后,返回数组可能的最大和。
解题思路
-
方法一:排序+贪心
- 对数组进行从小到大排序。
- 遍历数组,将负数变为正数,尽量减少负值,减少
K的次数。 - 如果
K还有剩余,且剩余为奇数,需要对最小值取反一次。 - 重新计算数组的总和并返回。
-
方法二:按绝对值排序+贪心
- 按数组元素绝对值从大到小排序,优先处理绝对值最大的元素。
- 遍历数组,将负数变为正数,减少
K的次数。 - 如果
K还有剩余,且为奇数,对绝对值最小的元素取反。 - 最后计算数组的总和。
Java代码
class Solution {
public int largestSumAfterKNegations(int[] nums, int k) {
Arrays.sort(nums);
int i = 0;
for(i = 0;i<k && i<nums.length && nums[i] < 0;i++){
nums[i] = -nums[i];
}
if(k>i && (k-i)%2!=0){
Arrays.sort(nums);
nums[0] = -nums[0];
}
int sum = 0;
for(i = 0;i<nums.length;i++){
sum = sum + nums[i];
}
return sum;
}
}
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 < nums.length;i++){
if(nums[i]<0 && k>0){
nums[i] = -nums[i];
k--;
}
}
if(k%2!=0) nums[len-1] = -nums[len-1];
return Arrays.stream(nums).sum();
}
}
305

被折叠的 条评论
为什么被折叠?



