dart實(shí)現(xiàn)leetcode_53

[toc]

題目:https://leetcode-cn.com/problems/maximum-subarray/

1.暴力法


  ///
  /// Author: liyanjun
  /// description: 暴力法
  ///
  int maxSubArray(List<int> nums) {
    if (nums == null || nums.length == 0) {
      return 0;
    }

    int maxNumber = nums.first;
    for (var begin = 0; begin < nums.length; begin++) {
      for (var end = begin + 1; end < nums.length; end++) {
        int sum = 0;
        for (var i = begin; i <= end; i++) {
          sum += nums[i];
        }
        maxNumber = max(sum, maxNumber);
      }
    }
    return maxNumber;
  }

空間復(fù)雜度:O(1)褪猛,時(shí)間復(fù)雜度:O(n^3)

1.1 暴力法優(yōu)化

重復(fù)利用前面計(jì)算過(guò)的結(jié)果


// ? 重復(fù)利用前面計(jì)算過(guò)的結(jié)果
   int maxSubArray1(List<int> nums) {
    if (nums == null || nums.length == 0) {
      return 0;
    }
    int maxNumber = nums.first;
    for (var begin = 0; begin < nums.length; begin++) {
      int sum = 0;
      for (var end = begin; end < nums.length; end++) {
        sum +=nums[end];
        maxNumber = max(sum, maxNumber);
      }
    }
    return maxNumber;
  }
}

空間復(fù)雜度:O(1),時(shí)間復(fù)雜度:O(n^2)

2.分治法

將序列均勻地分割成 2 個(gè)子序列

  • [begin , end) = [begin , mid) + [mid , end),mid = (begin + end) >> 1

假設(shè) [begin , end) 的最大連續(xù)子序列和是 S[i , j) 猜惋,那么它有 3 種可能

  • [i , j) 存在于 [begin , mid) 中尽狠,同時(shí) S[i , j) 也是 [begin , mid) 的最大連續(xù)子序列和
  • [i , j) 存在于 [mid , end) 中署驻,同時(shí) S[i , j) 也是 [mid , end) 的最大連續(xù)子序列和
  • [i , j) 一部分存在于 [begin , mid) 中丹拯,另一部分存在于 [mid , end) 中
    • [i , j) = [i , mid) + [mid , j)
    • S[i , mid) = max { S[k , mid) }离陶,begin ≤ k < mid
    • S[mid , j) = max { S[mid , k) }澎迎,mid < k ≤ end

代碼

///
  /// Author: liyanjun
  /// description: [begin]到[end]連續(xù)子序列的和 左閉右開
  ///
  int divideConquer(List<int> nums, int begin, int end) {
    if (end - begin < 2) return nums[begin];
    int mid = (end + begin) >> 1;
    int leftMax = nums[mid - 1];
    //計(jì)算從mid-1開始往左遍歷 最大值
    int leftSum = leftMax;
    for (int i = mid - 2; i >= begin; i--) {
      leftSum += nums[i];
      leftMax = max(leftMax, leftSum);
    }
    //計(jì)算從mid開始開始往右遍歷 最大值
    int rightMax = nums[mid];
    int rightSum = rightMax;
    for (int i = mid + 1; i < end; i++) {
      rightSum += nums[i];
      rightMax = max(rightMax, rightSum);
    }
    return max(
        leftMax + rightMax, //橫跨左右兩邊的最大子序列和
        max(
            divideConquer(nums, begin, mid), //左邊最大子序列和
            divideConquer(nums, mid, end))); //右邊最大子序列和
  }
}

空間復(fù)雜度:O(logn)庐杨,
時(shí)間復(fù)雜度$T(n)=2T(n/2)+O(n) = O(n*logn)

3.動(dòng)態(tài)規(guī)劃

狀態(tài)定義:
假設(shè) dp(i) 是以 nums[i] 結(jié)尾的最大連續(xù)子序列和(nums是整個(gè)序列)

  • 以 nums[0] –2 結(jié)尾的最大連續(xù)子序列是 –2,所以 dp(0) = –2
  • 以 nums[1] 1 結(jié)尾的最大連續(xù)子序列是 1夹供,所以 dp(1) = 1
  • 以 nums[2] –3 結(jié)尾的最大連續(xù)子序列是 1灵份、–3,所以 dp(2) = dp(1) + (–3) = –2
  • 以 nums[3] 4 結(jié)尾的最大連續(xù)子序列是 4哮洽,所以 dp(3) = 4
  • 以 nums[4] –1 結(jié)尾的最大連續(xù)子序列是 4填渠、–1,所以 dp(4) = dp(3) + (–1) = 3
  • 以 nums[5] 2 結(jié)尾的最大連續(xù)子序列是 4鸟辅、–1氛什、2,所以 dp(5) = dp(4) + 2 = 5
  • 以 nums[6] 1 結(jié)尾的最大連續(xù)子序列是 4匪凉、–1枪眉、2、1再层,所以 dp(6) = dp(5) + 1 = 6
  • 以 nums[7] –5 結(jié)尾的最大連續(xù)子序列是 4贸铜、–1堡纬、2、1蒿秦、–5烤镐,所以 dp(7) = dp(6) + (–5) = 1
  • 以 nums[8] 4 結(jié)尾的最大連續(xù)子序列是 4、–1棍鳖、2炮叶、1、–5渡处、4镜悉,所以 dp(8) = dp(7) + 4 = 5

狀態(tài)轉(zhuǎn)移方程:

  • 如果 dp(i – 1) ≤ 0,那么 dp(i) = nums[i]
  • 如果 dp(i – 1) > 0骂蓖,那么 dp(i) = dp(i – 1) + nums[i]

初始狀態(tài)

  • dp(0) 的值是 nums[0]

最終的解

  • 最大連續(xù)子序列和是所有 dp(i) 中的最大值 max { dp(i) }积瞒,i ∈ [0, nums.length)

代碼

int maxSubArray3(List<int> nums) {
    if (nums == null || nums.length == 0) {
      return 0;
    }
    List<int> dp = List(nums.length);
    dp[0] = nums[0];
    int maxDp = dp[0];
    for (var i = 1; i < nums.length; i++) {
      if (dp[i - 1] <= 0) {
        dp[i] = nums[i];
      } else {
        dp[i] = dp[i - 1] + nums[i];
      }
      maxDp = max(maxDp, dp[i]);
    }
    return maxDp;
  }

3.1 動(dòng)態(tài)規(guī)劃優(yōu)化

優(yōu)化空間,不需要數(shù)組


///
/// Author: liyanjun
/// description: 動(dòng)態(tài)規(guī)劃優(yōu)化
/// 優(yōu)化空間
///
int maxSubArray4(List<int> nums) {
    if (nums == null || nums.length == 0) {
      return 0;
    }
    int dp = nums[0];
    int maxDp =dp;
    for (var i = 1; i < nums.length; i++) {
      if (dp <= 0) {
        dp = nums[i];
      } else {
       dp = dp + nums[i];
      }
      maxDp = max(maxDp, dp);
    }
    return maxDp;
  }

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末登下,一起剝皮案震驚了整個(gè)濱河市茫孔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌被芳,老刑警劉巖缰贝,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異畔濒,居然都是意外死亡剩晴,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門侵状,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)赞弥,“玉大人,你說(shuō)我怎么就攤上這事趣兄≌雷螅” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵艇潭,是天一觀的道長(zhǎng)拼窥。 經(jīng)常有香客問(wèn)我,道長(zhǎng)蹋凝,這世上最難降的妖魔是什么鲁纠? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮鳍寂,結(jié)果婚禮上改含,老公的妹妹穿的比我還像新娘。我一直安慰自己迄汛,他們只是感情好捍壤,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布刃唤。 她就那樣靜靜地躺著,像睡著了一般白群。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上硬霍,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天帜慢,我揣著相機(jī)與錄音,去河邊找鬼唯卖。 笑死粱玲,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拜轨。 我是一名探鬼主播抽减,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼橄碾!你這毒婦竟也來(lái)了卵沉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤法牲,失蹤者是張志新(化名)和其女友劉穎史汗,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拒垃,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡停撞,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了悼瓮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片戈毒。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖横堡,靈堂內(nèi)的尸體忽然破棺而出埋市,到底是詐尸還是另有隱情,我是刑警寧澤翅萤,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布恐疲,位于F島的核電站,受9級(jí)特大地震影響套么,放射性物質(zhì)發(fā)生泄漏培己。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一胚泌、第九天 我趴在偏房一處隱蔽的房頂上張望省咨。 院中可真熱鬧,春花似錦玷室、人聲如沸零蓉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)敌蜂。三九已至箩兽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間章喉,已是汗流浹背汗贫。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留秸脱,地道東北人落包。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像摊唇,于是被迫代替她去往敵國(guó)和親咐蝇。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 技術(shù)交流QQ群:1027579432巷查,歡迎你的加入有序! 歡迎關(guān)注我的微信公眾號(hào):CurryCoder的程序人生 1....
    CurryCoder閱讀 1,847評(píng)論 0 2
  • 53. 最大子序和 給定一個(gè)整數(shù)數(shù)組 nums ,找到一個(gè)具有最大和的連續(xù)子數(shù)組(子數(shù)組最少包含一個(gè)元素)岛请,返回其...
    傅晨明閱讀 234評(píng)論 0 0
  • 算法思想貪心思想雙指針排序快速選擇堆排序桶排序荷蘭國(guó)旗問(wèn)題二分查找搜索BFSDFSBacktracking分治動(dòng)態(tài)...
    第六象限閱讀 3,095評(píng)論 0 0
  • 他人的整理與總結(jié): https://leetcode.wang/ 1. & 15. K-sum 問(wèn)題 此類問(wèn)題的解...
    oneoverzero閱讀 1,851評(píng)論 0 1
  • d1 leet1: 兩數(shù)之和 https://leetcode-cn.com/problems/two-sum給定...
    十里江城閱讀 3,282評(píng)論 0 0