日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

美团--最长全1串

發布時間:2024/4/11 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 美团--最长全1串 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

美團–最長全1串

文章目錄

  • 美團--最長全1串
    • 一、問題描述
    • 二、分析
    • 三、代碼

一、問題描述

給你一個01字符串,定義答案=該串中最長的連續1的長度,現在你有至多K次機會,每次機會可以將串中的某個0改成1,現在問最大的可能答案

  • 輸入描述:
輸入第一行兩個整數N,K,表示字符串長度和機會次數第二行輸入N個整數,表示該字符串的元素( 1 <= N <= 300000 , 0 <= K <= N )
  • 輸出描述:
輸出一行表示答案輸入例子1: 10 2 1 0 0 1 0 1 0 1 0 1輸出例子1: 5

二、分析

這道題和很多題類似:

  • 力扣424. 替換后的最長重復字符:替換后的最長重復字符
  • 字節-字符串翻轉:字符串翻轉

這幾道題基本上是一樣的,這道題也是:力扣1004. 最大連續1的個數 III:最大連續1的個數

  • 首先考慮本問題的最直觀樸素的想法:枚舉出每一個子串,逐個驗證其有效性并且更新最大值。
  • 這種做法的時間復雜度是O(n^3),在這一數據規模下是一定會超時的,超時的原因是做了非常多重復的驗證計算,且枚舉了非常多沒有意義的串
  • 那么基于我們在這類連續子數組性質問題的經驗,使用雙指針(滑動窗口)會是一個非常好的想法
  • 雙指針解法
  • 雙指針解法的重點在于維護兩個指針:
  • 設置兩個指針(表現為數組下標值),左指針指向當前子串左邊界,右指針指向當前子串右邊界,我們通過某種方法使得左右指針之間的當前子串符合要求:即 '0' 的數目小于等于 K
  • 又:我們很容易知道,最長串一定出現在串內 '0' 的數目飽和(如果'0'比較多)或者最大(如果 K 比較大)的情況下,因此我們需要盡可能地把右指針右移
  • 那么固定左指針時,什么情況下可以使右指針右移呢?轉化次數K有剩余 或右指針的下一位是'1'
  • 如此移動右指針,即可找到每一個左指針所對應的最長有效串,而且右指針指向的元素的下一位一定是’0’
  • 那么我們可以把每一個數組元素作為左指針,以上述方式枚舉出最長有效串,然后返回結果
  • 但是還是不夠快
  • 不夠快的原因還是做了重復計算,在左指針變化時,右指針從左指針處開始右移,沒有有效利用上一次操作的結果,造成了大量沒有必要的操作;那么如何避免重復計算呢?
  • 我們的關鍵在于剛剛提到的“0數飽和”。即:可能成為最長串的串,它內部'0'的數量一定是飽和或者最大的
  • 那么我們可以通過某種操作來使得在左指針右移之后,我們立即就能獲得新左指針對應的'0'數飽和串/'0'數最大串
  • 首先我們考察左指針右移一位時的情況:
  • 首先我們需要清楚一個事實:當右指針到達串尾部時,左指針沒有任何必要繼續右移,因為左指針右移的話子串的長度一定會減小,并且飽和性質無法保證
  • 就是說,左指針右移的條件是:右指針沒有觸碰串的右邊界
  • 那么我們會得到一個推論:當左指針需要右移時,串中的'0'一定是飽和的而不是最大的(“飽和”指子串中0的數目與K相等,不可以再轉化0為1;“最大”指整個串中所有的0均已被轉化為1)既飽和又最大的情況也不需要右移
  • 得到這個推論,我們就可以來考慮左指針右移時的情況:
  • 當前左指針指向的元素是'0'時:當左指針右移時子串內的'0'數減一,為了維護其飽和性質,我們剛剛提到“右指針指向的元素的下一位一定是'0'”,所以右指針一定可以右移至少一位(如果右移之后的下一位是'1'則可以繼續右移)
  • 當前左指針指向的元素是'1'時:當左指針右移時子串內的'0'數不變,由于我們維護了每一個子串的飽和性質,右指針不可以右移
  • 每一次左指針移動及之后右指針移動的一系列操作結束之后,更新最大值。通過以上的操作,遍歷直到右指針觸碰數組右邊界,即可得到全局的最大符合條件串的長度
  • 開銷分析
  • 平均漸進時間復雜度O(n)
  • 漸近額外空間O(1)

三、代碼

class Solution { public:int longestOnes(vector<int>& A, int K) {//在這個實現中,right指的是當前子串末尾的下一位int left(0), right(0);int max(0);while (left <= right && right < A.size()) {//如果right沒有走到結尾,并且right位置為1(可以直接++)或者//right位置為0(如果k不等于0)那么可以進行一次0-》1轉變,//繼續++)while (right < A.size() && (A[right] || K != 0)) {//如果是0,那么k的值需要--if (!A[right]) K--;right++;}//更新結果max = std::max(right - left, max);//如果left位置為1,只需要left++if (A[left]) left++;//反之代表left位置為0,那么我們需要同時++else {left++, right++;}}return max;} };

總結

以上是生活随笔為你收集整理的美团--最长全1串的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。