我覺得我和這個題型特別有緣阿,之前實習面試還被問到,然後這兩週的week competition都有出到,下面就從最原始的問題開始,然後慢慢講解其他有的沒的變形題目。
第二篇看這裡:[LeetCode]各種Max subarray問題-2
LeetCode 53. Maximum Subarray
題意: 從array裡面找一個subarray,使得該subarray有最大的和。
Input: [-2,1,-3,4,-1,2,1,-5,4], Output: 6 Explanation: [4,-1,2,1] has the largest sum = 6.
1. 暴力掃過: 枚舉所有可能的區段,找出最大值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution {public : int maxSubArray (vector & nums) { if (nums.empty()) return 0 ; int ans = nums[0 ]; for (int i = 0 ; i < nums.size () ; i++){ int temp = 0 ; for (int j = i ; j < nums.size () ; j++){ temp = temp + nums[j]; ans = max (ans, temp); } } return ans; } }; };
2. kadane’s algo
DP方法,DP[i]記錄了在i-th當下的max subarray,DP[i]只有兩種可能:
DP[i] = arr[i]
DP[i] = DP[i-1] + arr[i]
最後掃過一次DP取得最大的值即可。實際上,可以一邊掃一邊存最大值,如此就不用另外開一個DP array。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution {public : int maxSubArray (vector & nums) { if (nums.empty()) return 0 ; int temp_max = nums[0 ]; int max_so_far = nums[0 ]; for (int i = 1 ; i < nums.size () ; i++){ temp_max = max (nums[i], temp_max+nums[i]); max_so_far = max (temp_max, max_so_far); } return max_so_far; } };
LeetCode 918. Maximum Sum Circular Subarray
題意: 從array裡面找一個subarray,使得該subarray有最大的和,但這個array是一個circular array。
Input: [5,-3,5] Output: 10 Explanation: Subarray [5,5] has maximum sum 5 + 5 = 10
1. kadane’s algo
有兩種case:
max_sum_subarray在array中間,這時候直接用kadane’s algo
max_sum_subarray在array的頭跟尾,這時要換個想法,把問題轉成total_sum - min_sum_subarray(也是用kadane’s algo去計算)
答案在這兩個case取最大值即可 ,但要注意如果array全部都是負數,此時total_sum - min_sum_array = 0,會得到錯誤的結果,這個case要特別處理(直接回傳max_sum_subarray)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution {public : int maxSubarraySumCircular (vector & A) { int temp_max = A[0 ]; int max_so_far = A[0 ]; int temp_min = A[0 ]; int min_so_far = A[0 ]; int total_sum = A[0 ]; for (int i = 1 ; i < A.size () ; i++){ temp_max = max (A[i], temp_max + A[i]); max_so_far = max (max_so_far, temp_max); temp_min = min (A[i], temp_min + A[i]); min_so_far = min (min_so_far, temp_min); total_sum += A[i]; } if (min_so_far == total_sum) return max_so_far; return max (max_so_far, total_sum-min_so_far); } };