lintcode循环数组之连续子数组求和
給定一個(gè)整數(shù)循環(huán)數(shù)組(頭尾相接),請(qǐng)找出一個(gè)連續(xù)的子數(shù)組,使得該子數(shù)組的和最大。輸出答案時(shí),請(qǐng)分別返回第一個(gè)數(shù)字和最后一個(gè)數(shù)字的值。如果多個(gè)答案,請(qǐng)返回其中任意一個(gè)。
v 樣例?給定?[3, 1, -100, -3, 4], 返回?[4,0].
v 思路1.如果不是循環(huán)數(shù)組,求解連續(xù)子區(qū)間和的思路如下: 首先設(shè)一個(gè)累加變量和sum和最大值變量maxN,[ld, rd]表示當(dāng)前正在累加的區(qū)間,[lt,rt]表示最大和的區(qū)間。從左邊開(kāi)始一直累加,并初始當(dāng)前區(qū)間[ld, rd]的左右兩端的值。如果在累加之前發(fā)現(xiàn)sum<0,那么更新sum為當(dāng)前的要累加的數(shù)字,并且重置新的區(qū)間左右兩端的值(即[ld, rd]的值)。另外在累加的過(guò)程中,如果sum的值大于maxN,更新maxN的值,并且更新最大值區(qū)間(即[lt, rt]改變成[ld, rd])。
2.現(xiàn)在是循環(huán)數(shù)組,最大和的區(qū)間可能會(huì)出現(xiàn)在數(shù)組的兩端,也就是數(shù)組的左邊一段和數(shù)組的右邊的一段組成。那么中間的那一部分就是區(qū)間和最小的部分。假設(shè)一下左端區(qū)間[l1, r1]和右端區(qū)間[l2, r2]組成最大和的區(qū)間,如果[r1+1, l2-1]不是最小和區(qū)間,那么存在區(qū)間[lx, rx]的和比[r1+1, l2-1]區(qū)間和更小(其中有l(wèi)x>r1+1, rx<l2-1),那么也就是區(qū)間[r1+1, lx-1](或者[rx+1, l2-1])和一定大于0,這樣必然會(huì)導(dǎo)致左端區(qū)間[l1, r1]區(qū)間和 +?區(qū)間[r1+1, lx-1]和更大。所以區(qū)間[r1+1, l2-1]一定是最小區(qū)間和。
如?[-1, 2, -1, 2, -1, 10, -100, 10, 9, 8, 7], 這個(gè)例子中,最小的區(qū)間和是-100,區(qū)間[6, 6], 區(qū)間[7, 5](注意是循環(huán)數(shù)組)就是最大的區(qū)間和。
v AC代碼 class Solution { public:/*** @param A an integer array* @return A list of integers includes the index of * the first number and the index of the last number*/vector<int> continuousSubarraySumII(vector<int>& A) {// Write your code hereint ld=0, rd=0, lt=0, rt=0;int sum = 0, maxN = -0x3f3f3f3f;for(int i=0; i<A.size(); ++i){if(sum < 0){sum = A[i];if(maxN < sum){maxN = sum;lt = rt = i;}ld = rd = i;} else {sum += A[i]; rd = i;if(maxN < sum){maxN = sum;lt = ld;rt = rd;}}}ld = rd = 0;int lx=0, rx=0;int sumx = 0, minN = 0x3f3f3f3f, summ = 0;for(int i=0; i<A.size(); ++i){summ += A[i];if(sumx > 0){sumx = A[i];if(minN > sumx){minN = sumx;lx = rx = i;}ld = rd = i;} else {sumx += A[i]; rd = i;if(minN > sumx){minN = sumx;lx = ld;rx = rd;}}}vector<int> ans;if(summ-minN > maxN && lx>0 && rx+1<A.size()){//兩端組成的區(qū)間和最大,并且所有的數(shù)不都是負(fù)數(shù)的情況ans.push_back(rx+1);ans.push_back(lx-1);} else {ans.push_back(lt);ans.push_back(rt);}return ans;} };?
轉(zhuǎn)載于:https://www.cnblogs.com/hujunzheng/p/5027248.html
總結(jié)
以上是生活随笔為你收集整理的lintcode循环数组之连续子数组求和的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 余额宝收益怎么算
- 下一篇: vim配置之snippets代码块