沒證:SpaceX 星鏈在印度收到政府命令,將向預購使用者退款
阿新 • • 發佈:2022-01-05
給你一個整數陣列 nums ,請你找出一個具有最大和的連續子陣列(子陣列最少包含一個元素),返回其最大和。
子陣列 是陣列中的一個連續部分。
示例 1:
輸入:nums = [-2,1,-3,4,-1,2,1,-5,4]
輸出:6
解釋:連續子陣列[4,-1,2,1] 的和最大,為6 。
示例 2:
輸入:nums = [1]
輸出:1
示例 3:
輸入:nums = [5,4,-1,7,8]
輸出:23
提示:
1 <= nums.length <= 105
-104 <= nums[i] <= 104
進階:如果你已經實現複雜度為 O(n) 的解法,嘗試使用更為精妙的 分治法 求解。
解法一:動態規劃+貪心思想
首先要明白以下幾點:
- 設定dp[i]為第i位的暫存值(注意:不是最大值,只是下標滑到第i位時,dp的數值)
- 最大子序和的第一位一定為 正數,
- 如果一個序列全為負數,那麼就要求負數的最大值(不要想當然的覺得最大數大於0!然後就隨隨便便的把dp[i]=0),
- 如果
dp[i-1]<=0
,那麼就要勇敢捨棄前面算的,從當前位重新開始(違反第2條)。 - 如果
dp[i-1]>0
,當然要加上當前位(貪心),至於加上當前位後是會減少dp[i]或者增加,留給下一個迴圈去判斷。
程式碼如下:
class Solution { public int maxSubArray(int[] nums) { int [] dp = new int [nums.length]; dp[0] = nums[0]; for(int i=1;i<nums.length;i++){ if(dp[i-1]<=0){ dp[i] = nums[i]; } else{ dp[i] = dp[i-1]+nums[i]; } } java.util.Arrays.sort(dp); return dp[nums.length-1]; } }
上述程式碼並沒有清楚的寫出動態規劃的統一方程,但由for迴圈中的兩個if,
if(dp[i-1]<=0){
dp[i] = nums[i];
}
else{
dp[i] = dp[i-1]+nums[i];
}
可以推測dp公式:dp[i] = nums[i]+Math.max(dp[i-1], 0)
故上述程式碼可簡化為:
class Solution { public int maxSubArray(int[] nums) { int [] dp = new int [nums.length]; dp[0] = nums[0]; int max = dp[0]; for(int i=1;i<nums.length;i++){ dp[i] = nums[i] + Math.max(dp[i-1], 0); max = Math.max(dp[i], max); } return max; } }
繼續優化
class Solution {
public int maxSubArray(int[] nums) {
int temp_i = nums[0];
int max = nums[0];
for(int i=1;i<nums.length;i++){
temp_i = nums[i] + Math.max(temp_i, 0);
max = Math.max(temp_i, max);
}
return max;
}
}