Leetcode53/376/55/1005之經典貪心例題
阿新 • • 發佈:2022-04-13
Leetcode53-最大子陣列和
- 給你一個整數陣列 nums ,請你找出一個具有最大和的連續子陣列(子陣列最少包含一個元素),返回其最大和。
- 子陣列 是陣列中的一個連續部分。
- 輸入:nums = [-2,1,-3,4,-1,2,1,-5,4]
- 輸出:6
- 解釋:連續子陣列 [4,-1,2,1] 的和最大,為 6 。
//經典貪心和動態對比 public class L53 { //貪心 public int maxSubArray(int[] nums) { int res=Integer.MIN_VALUE; int sum=0; for(int i=0;i<nums.length;i++){ sum+=nums[i]; if(sum>res){ res=sum; } if(sum<0){ sum=0; } } return res; } //動態 public int maxSubArray2(int[] nums) { int ans = Integer.MIN_VALUE; int[] dp = new int[nums.length]; dp[0] = nums[0]; ans = dp[0]; for (int i = 1; i < nums.length; i++){ dp[i] = Math.max(dp[i-1] + nums[i], nums[i]); ans = Math.max(dp[i], ans); } return ans; } }
Leetcode376-擺動序列
- 如果連續數字之間的差嚴格地在正數和負數之間交替,則數字序列稱為 擺動序列 。第一個差(如果存在的話)可能是正數或負數。僅有一個元素或者含兩個不等元素的序列也視作擺動序列。
- 例如, [1, 7, 4, 9, 2, 5] 是一個 擺動序列 ,因為差值 (6, -3, 5, -7, 3) 是正負交替出現的。
- 相反,[1, 4, 7, 2, 5] 和 [1, 7, 4, 5, 5] 不是擺動序列,第一個序列是因為它的前兩個差值都是正數,第二個序列是因為它的最後一個差值為零。
- 子序列 可以通過從原始序列中刪除一些(也可以不刪除)元素來獲得,剩下的元素保持其原始順序。
- 給你一個整數陣列 nums ,返回 nums 中作為 擺動序列 的 最長子序列的長度
- 輸入:nums = [1,17,5,10,13,15,10,5,16,8]
- 輸出:7
public class L376 { //貪心 public int wiggleMaxLength(int[] nums) { if (nums.length <= 1) { return nums.length; } //當前差值 int curDiff = 0; //上一個差值 int preDiff = 0; int count = 1; for (int i = 1; i < nums.length; i++) { //得到當前差值 curDiff = nums[i] - nums[i - 1]; //如果當前差值和上一個差值為一正一負 //等於0的情況表示初始時的preDiff if ((curDiff > 0 && preDiff <= 0) || (curDiff < 0 && preDiff >= 0)) { count++; preDiff = curDiff; } } return count; } //動態規劃 public int wiggleMaxLength2(int[] nums) { // 0 i 作為波峰的最大長度 // 1 i 作為波谷的最大長度 int dp[][] = new int[nums.length][2]; dp[0][0] = dp[0][1] = 1; for (int i = 1; i < nums.length; i++){ //i 自己可以成為波峰或者波谷 dp[i][0] = dp[i][1] = 1; for (int j = 0; j < i; j++){ if (nums[j] > nums[i]){ // i 是波谷 dp[i][1] = Math.max(dp[i][1], dp[j][0] + 1); } if (nums[j] < nums[i]){ // i 是波峰 dp[i][0] = Math.max(dp[i][0], dp[j][1] + 1); } } } return Math.max(dp[nums.length - 1][0], dp[nums.length - 1][1]); } }
Leetcode55-跳躍遊戲
- 給定一個非負整數陣列 nums ,你最初位於陣列的 第一個下標,陣列中的每個元素代表你在該位置可以跳躍的最大長度。判斷你是否能夠到達最後一個下標。
- 輸入:nums = [2,3,1,1,4]
- 輸出:true
public boolean canJump(int[] nums) {
int finalIndex=0;
for(int i=0;i<=finalIndex;i++){
if(nums[i]+i>finalIndex){
finalIndex=nums[i]+i;
}
if(finalIndex>=nums.length-1){
return true;
}
}
return false;
}
Leetcode1005-K次取反後最大化的陣列和
- 給你一個整數陣列 nums 和一個整數 k ,按以下方法修改該陣列:
- 選擇某個下標 i 並將 nums[i] 替換為 -nums[i]
- 重複這個過程恰好 k 次。可以多次選擇同一個下標 i 。
- 以這種方式修改陣列後,返回陣列 可能的最大和
- 輸入:nums = [3,-1,0,2], k = 3
- 輸出:6
public class L1005 {
public int largestSumAfterKNegations(int[] nums, int k) {
Arrays.sort(nums);
int i = 0;
boolean flag = false;
while (k > 0) {
if (nums[i] < 0 && flag == false) {
nums[i] = -nums[i];
i++;
k--;
if (i >= nums.length) {//表示此時數組裡已經全為非負數
flag = true;
i--;
}
} else if (nums[i] >= 0 || flag == true) {
flag = true;//表示此時數組裡已經全為非負數
if (i != 0) {
if (nums[i] > nums[i - 1]) {
i = i - 1;
}
}
nums[i] = -nums[i];
k--;
}
}
int sum = 0;
for (int j = 0; j < nums.length; j++) {
sum += nums[j];
}
return sum;
}
public static void main(String[] args) {
int[] nums = new int[]{-3, -2, 1, 5, 6};
L1005 l1005 = new L1005();
l1005.largestSumAfterKNegations(nums, 1);
}
}