1. 程式人生 > 遊戲 >《新美妙世界》TV動畫聯動CM釋出 於澀谷展開死神遊戲

《新美妙世界》TV動畫聯動CM釋出 於澀谷展開死神遊戲

前言

清明假期馬上就要結束了,小熊給大家帶來一道筆試和麵試中與「動態規劃」相關的常考的簡單題,這道題被位元組、微軟、亞馬遜和蘋果等各大網際網路大廠作為筆試題。

這道題就是 Leetcode 的第 53 題-最大子序和,瞭解「動態規劃」的童鞋,在看到最大兩個字的時候,很容易就會想到用「動態規劃」去解答,因為涉及到「最優解」的問題,一般都可以通過動歸去做。本題小熊提供「動態規劃」的思路供大家參考,希望對大家有所幫助。

題目

解題思路

本題是一道典型的「動態規劃」的題,因此採用動態規劃的策略去解答。

「定義狀態」 dp[i]:以 nums[i]結尾(包含 nums[i])的連續子陣列的最大和。

「狀態轉移方程」 dp[i] = max(dp[i - 1] + nums[i], nums[i]),其中 i >= 1,當 dp[i - 1] < 0 時,拋棄當前的和最大的連續子陣列,從 nums[i] 開始,重新尋找和最大的連續子陣列,否則,將 nums[i] 加入到當前的和最大的連續子陣列。

「邊界條件」 dp[0] = nums[0]。

「舉慄」

以陣列 nums[i] = [-2,1,-3,4,-1,2,1,-5,4] 為例子,如下圖示。

從上圖可以看出:dp[0] = nums[0] = -1 < 0,由於當前的連續子陣列的最大和小於零,因此應該丟棄 num[0],從 nums[1] = 1 開始重新尋找和最大的連續子陣列。

尋找和最大的連續子陣列的完整動圖,如下所示:

由狀態轉移方程可知,dp[i] 只與 dp[i - 1] 和 nums[i] 相關,因此沒必要再去定義 dp,直接複用 nums 即可。

Show me the Code

「C++」

1 int maxSubArray(vector<int>& nums) {
2     int maxSum = nums[0];
3     for (int i = 1; i < nums.size(); ++i) {
4         nums[i] = max(nums[i - 1], 0) + nums[i];
5         maxSum = max(maxSum, nums[i]);
6 } 7 8 return maxSum; 9 }
View Code

「Java」

1 int maxSubArray(int[] nums) {
2     int maxSum = nums[0];
3     for (int i = 1; i < nums.length; ++i) {
4         nums[i] = Math.max(nums[i - 1], 0) + nums[i];
5         maxSum = Math.max(maxSum, nums[i]);
6     }
7 
8     return maxSum;
9 }
View Code

「Python3」

1 def maxSubArray(self, nums: List[int]) -> int:
2     for i in range(1, len(nums)):
3         nums[i] = max(nums[i - 1], 0) + nums[i]
4     
5     return max(nums)
View Code

「Golang」

 1 func maxSubArray(nums []int) int {
 2     maxSum := nums[0];
 3     for i := 1; i < len(nums); i++ {
 4         if nums[i - 1] > 0 {
 5             nums[i] += nums[i - 1]
 6         }
 7 
 8         if nums[i] > maxSum {
 9             maxSum = nums[i]
10         }
11     }
12 
13     return maxSum;
14 }
View Code

「C」

1 int maxSubArray(int* nums, int numsSize){
2     int maxSum = nums[0];
3     for (int i = 1; i < numsSize; ++i) {
4         nums[i] = fmax(nums[i - 1] + nums[i], nums[i]);
5         maxSum = fmax(maxSum, nums[i]);
6     }
7 
8     return maxSum;
9 }
View Code

「複雜度分析」

時間複雜度:「O(n)」,其中 n 是陣列的長度,需要遍歷一遍陣列。

空間複雜度:「O(1)」,未開闢額外的儲存空間。