LeetCode——第53題:最大欄位和
題目:
給定一個整數陣列 nums ,找到一個具有最大和的連續子陣列(子陣列最少包含一個元素),返回其最大和。
示例:
輸入: [-2,1,-3,4,-1,2,1,-5,4],
輸出: 6
解釋: 連續子陣列 [4,-1,2,1] 的和最大,為 6。
進階:
如果你已經實現複雜度為 O(n) 的解法,嘗試使用更為精妙的分治法求解。
程式碼;
/**
* @作者:dhc
* @建立時間:14:18 2018/8/8
* @描述:53.最大子串和
*
*/
public class FiftyThree {
//方法1.1:三重for迴圈求出所有子串和 (leetCode超出時間限制)
public int maxSubArray1(int[] nums){
int sum = nums[0];
for (int i = 0; i < nums.length; i++) {
for (int j = i; j < nums.length; j++) {
int thissum = 0;
for (int k = i; k <= j; k++) {
thissum+=nums[k];
}
if(thissum > sum){
sum = thissum;
}
}
}
return sum;
}
//方法1.2,對方法1.1的優化
public static int maxSubArray2(int[] nums){
int sum = nums[0];
for (int i = 0; i < nums.length; i++) {
int thissum = 0;
for (int j = i; j < nums.length; j++) {
thissum += nums[j];
if(thissum > sum){
sum = thissum;
}
}
}
return sum;
}
//方法二:滿足最優子結構的性質,因為如果假如結果子串的子串和不是最大,那麼 // 和結果子串的和是矛盾的,同時也滿足重疊子問題,在方法一種用一個二維陣列儲存之前已經計算過的子串和值, //並且在計算更長子串時用到了之前的值,這個方法通過了200/202個測試例子,後面超出記憶體限制了,所以還需要 // 更好的演算法O(n2) public int maxSubArray3(int[] nums) { if(nums.length == 1){ return nums[0]; } //儲存最大值 int re = Integer.MIN_VALUE; //儲存子問題的值,行表示子串長度,列表示子串的結束下標,值存子串和 int[][] sumArray = new int[nums.length][nums.length]; for (int i = 0; i < nums.length; i++) { if(nums[i] > re){ re = nums[i]; } sumArray[0][i] = nums[i]; } int tem = 0; //此時迴圈的長度為i+1 for (int i = 1; i < nums.length; i++) { //求所有某一長度的子串的和 for(int j = i;j<nums.length;j++){ tem = nums[j]+sumArray[i-1][j-1]; if(tem > re){ re = tem; } sumArray[i][j] = tem; } } return re; } //方法三,分治法。我們將整個序列分成nums[1:n/2]和nums[n/2:n],結果有三種情況 //1.結果和nums[1:n/2]的最大子串和相等 //2.結果和nums[n/2:n]的最大子串和相等 //3.結果是nums[1:n/2]中某個元素到nums[n/2:n]中某個元素的子串的和,這種情況,可以知道這個 //序列中包含了nums[n/2]和nums[n/2+1],因此可以從這兩個數分別想左向右求出最大子串和在相加,即 //是最大子串和,這步操作的複雜度為O(n)。對於1,2可以用遞迴來求出子最大串和 //程式碼優點問題,思路沒錯,實在沒調處來 public static int maxSubArray4(int[] nums){ return subMsa(nums,0,nums.length - 1); } public static int subMsa(int[] nums,int left,int right){ int sum; if(left == right){ sum = nums[left]; }else{ int middle = (left+right)/2; int leftSum = subMsa(nums,left,middle); int rightSum = subMsa(nums, middle + 1, right); int lm = nums[middle]; int rm = nums[middle+1]; int lefts = 0; int rights = 0; for (int i = middle; i >= left ; i--) { lefts += nums[i]; if(lefts > lm){ lm = lefts; } } for (int i = middle + 1; i <= right ; i++) { rights += nums[i]; if(rights > lm){ rm = rights; } } sum = lm + rm; if(sum < leftSum){ sum = leftSum; } if(sum < rightSum){ sum = rightSum; } } return sum; } //方法四。動態規劃。 public static int maxSubArray5(int[] nums){ int sum = nums[0]; int b = 0; for (int i = 0; i < nums.length; i++) { if(b>0){ b+=nums[i]; }else{ b = nums[i]; } if(b > sum){ sum = b; } } return sum; } public static void main(String[] args) { int[] nums = new int[]{-2,1,-3,4,-1,2,1,-5,4}; System.out.println(maxSubArray5(nums)); }
}
相關推薦
LeetCode——第53題:最大欄位和
題目: 給定一個整數陣列 nums ,找到一個具有最大和的連續子陣列(子陣列最少包含一個元素),返回其最大和。 示例: 輸入: [-2,1,-3,4,-1,2,1,-5,4], 輸出: 6 解釋: 連續子陣列 [4,-1,2,1] 的和最大,為 6
演算法優化:最大欄位和,雙指標遍歷(n^2),分治法(nlogn),動態規劃(n)
最大欄位和,有點類似與最長公共子序列,這裡是求連續一段求和最大的一段,比如[-2,11,-4,-4,13,-5,-2]最大求和的連續一段為11,-4,-4,13,和為16. 最基本的雙針模型遍歷,兩個指標,分別代表最大和序列的起始和終止,演算法時間複雜度O(n^2) # 以下演算法時
動態規劃:最大欄位和問題
import java.util.Scanner; /* * 最大子段和問題,-2 11 -4 13 -5 -2中最大的子段和 */ public class MaxSum { publi
leetcode第32題:最長有效括號(遇到一個奇葩的錯誤)
問題描述: 給一個只包含 '(' 和 ')' 的字串,找出最長的有效(正確關閉)括號子串的長度。 對於 "(()",最長有效括號子串為 "()" ,它的長度是 2。 另一個例子 ")()())",最長有效括號子
LeetCode第五題:最長迴文子串(C語言)
給定一個字串 s,找到 s 中最長的迴文子串。你可以假設 s 的最大長度為1000。 示例 1: 輸入: “babad” 輸出: “bab” 注意: "aba"也是一個有效答案。 示例 2: 輸入: “cbbd” 輸出: “bb” 解法一:暴力求解法 思想:
LeetCode第85題(最大矩形)
原題如下: 給定一個僅包含 0 和 1 的二維二進位制矩陣,找出只包含 1 的最大矩形,並返回其面積。 示例: 輸入: [ [“1”,“0”,“1”,“0”,“0”], [“1”,“0”,“1”,“1”,“1”], [“1”,“1”,“1”,“1”,“1”],
2017第八屆藍橋杯B組省賽第六題:最大公共子串
第六題 標題:最大公共子串 最大公共子串長度問題就是: 求兩個串的所有子串中能夠匹配上的最大長度是多少。 比如:"abcdkkk" 和 "baabcdadabc", 可以找到的最長的公共子串是"a
分治法 解決最大欄位和問題
分治法求解最大欄位和問題 1 問題描述 給定由n個整數(可能由負數)組成的序列(a1, a2,...,an),最大欄位和問題求 該序列中連續子段和的最大值,並找出這個連續子段。 2 使用python程式設計解決,具體程式碼如下 # 求出最大子段和, 以及最大子段和 對應的位置
最大欄位和 動態規劃
最大子段和 給定由n個整數(可能有負整數)組成的序列(a1,a2,…,an),最大子段和問題要求該序列形如 的最大值(1<=i<=j<=n),當序列中所有整數均為負整數時,其最大子段和為0。 #include<stdio.h> #include<
演算法 | 最大欄位和
#include <stdio.h> int a[100001],dp[100001]; int main() { int T,n; while(~scanf("%d",&n)) {
HDU 1231 簡單DP之最大欄位和
原題地址:http://acm.hdu.edu.cn/showproblem.php?pid=1231 演算法核心: 動態規劃, 陣列為vec[]vec[],設dp[i]dp[i] 是以vec[i]
關於最大欄位和的若干解法和優化
最大欄位和是常見的一個入門演算法問題,根據演算法的優化程度,這裡分為了四種方法: 第一種:複雜度為O(N ^ 2),兩個用於語句巢狀 int summax_1(int *a,int tem) { int temp=0,temp_maxi=0,temp_maxj=
POJ 1050 To the Max 最大子矩陣和(二維的最大欄位和)
傳送門: To the Max Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 52306 Accepted: 27646 Description Given a two-dimensional array of positive
poj1050最大欄位和及其衍生
每天做poj都會感覺到自己的收穫,今天做的是poj1050,以前沒接觸這些演算法類的東西,也就在資料結構課上水過兩把,所以每天接觸到這些新的東西覺得挺有意思,也確實感覺自己收穫了不少。 poj1050是一個欄位和的題,什麼是欄位和以及他的具體實現我是在這篇部落格上學到的,點
最大欄位和的3中解法
問題描述: 給定n個整數,組成序列a[1], a[2], a[3], ... a[n],求形如a[i]+a[i+1]+...+a[j]的欄位和的最大值。 // 最大子段求和,窮舉法,複雜度O(n^2) // 輸入引數:a[]儲存資料,其中a[0]儲存資料個數 //
【演算法設計與分析】6、最大欄位和
/** * 書本:《演算法分析與設計》 * 功能:若給定n個整陣列成的序列a1, a2, a3, ......an, 求該序列形如ai+a(i+1)+......+an的最大值 * 檔案:MaxSum.cpp * 時間:2014年11月30日17:37:26 * 作者:cu
最大欄位和——動態規劃
最大欄位和,常規解法有四種,分別是: 1、三重for迴圈; 2、兩重for迴圈; 3、分治解法; 4、動態規劃; 從時間複雜度的角度講,動態規劃是最優演算法,故對其簡單介紹: #include<iostream> using namespace std;
求陣列最大欄位和最簡潔有效的演算法
直接上程式碼:public static int max(int[] a){ int max = 0;int zmax = 0; for (int i = 0;i<a.length;i++){ zmax += a[
最大欄位和 衝出暴力列舉
這篇解題報告是對我最近一些題的總結,裡面的程式碼都是我解題,優化,再優化的過程的記錄,記錄了自己對演算法的完善與優化思路,還有對程式設計哲學的理解:do it,do it well。 很感謝孫老師您,讓自己可以找到利用計算機作比只是單純玩遊戲更有意義又更有趣的事
基礎演算法--B最大欄位和
Description Given a sequencea[1],a[2],a[3]......a[n], your job is to calculate the max sum of asub-sequence. For example, given (6,-1,5,4