国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

算法leetcode|76. 最小覆蓋子串(rust重拳出擊)

這篇具有很好參考價(jià)值的文章主要介紹了算法leetcode|76. 最小覆蓋子串(rust重拳出擊)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。



76. 最小覆蓋子串:

給你一個(gè)字符串 s 、一個(gè)字符串 t 。返回 s 中涵蓋 t 所有字符的最小子串。如果 s 中不存在涵蓋 t 所有字符的子串,則返回空字符串 ""

注意

  • 對(duì)于 t 中重復(fù)字符,我們尋找的子字符串中該字符數(shù)量必須不少于 t 中該字符數(shù)量。
  • 如果 s 中存在這樣的子串,我們保證它是唯一的答案。

樣例 1:

輸入:
	
	s = "ADOBECODEBANC", t = "ABC"
	
輸出:
	
	"BANC"
	
解釋:
	
	最小覆蓋子串 "BANC" 包含來自字符串 t 的 'A'、'B' 和 'C'。

樣例 2:

輸入:
	
	s = "a", t = "a"
	
輸出:
	
	"a"
	
解釋:
	
	整個(gè)字符串 s 是最小覆蓋子串。

樣例 3:

輸入: 
	
	s = "a", t = "aa"
	
輸出: 
	
	""
	
解釋:

	 t 中兩個(gè)字符 'a' 均應(yīng)包含在 s 的子串中,
	因此沒有符合條件的子字符串,返回空字符串。

提示:

  • m == s.length
  • n == t.length
  • 1 <= m, n <= 105
  • st 由英文字母組成

進(jìn)階:

你能設(shè)計(jì)一個(gè)在 o(m + n) 時(shí)間內(nèi)解決此問題的算法嗎?


分析:

  • 面對(duì)這道算法題目,二當(dāng)家的再次陷入了沉思。
  • 直接采用雙層循環(huán)暴力解決的話,時(shí)間復(fù)雜度會(huì)比較高,恐怕過不了用例,沒有去試。
  • 題目并不要求字符的順序,只要求了每種字符的數(shù)量,那首先就想到要做計(jì)數(shù)。
  • 接下來考慮如何降低時(shí)間復(fù)雜度,每次循環(huán)都從新匹配子串是低效的,要盡可能復(fù)用,滑動(dòng)窗口在這里非常合適,使用雙指針,先直接移動(dòng)右指針找到第一個(gè)滿足條件的子串,記下長度作為備選結(jié)果,接下來移動(dòng)左指針,當(dāng)不滿足覆蓋子串的條件時(shí)就繼續(xù)移動(dòng)右置針直到滿足覆蓋子串的條件,并比較子串的長度,取較小的子串長度作為備選結(jié)果,重復(fù)該操作,直到循環(huán)遍歷完畢。
  • 如何高效判斷遍歷的子串已經(jīng)滿足覆蓋子串呢?字符計(jì)數(shù)這時(shí)候就要大展拳腳了,先在遍歷字符串 s 之前,先對(duì)字符串 t 進(jìn)行一次遍歷,做初始化計(jì)數(shù),記錄下每種字符的個(gè)數(shù)(題解中這里使用了減法,使用加法也是可以的,只是后面的加減法就要變),在遍歷 s 時(shí),移動(dòng)右指針就是延長了覆蓋子串,同時(shí)修改計(jì)數(shù),這里的加減法計(jì)算要和前面初始化的相反,判斷計(jì)數(shù)是否為0,如果變?yōu)?則表示,這種字符的個(gè)數(shù)已經(jīng)沒有差異了,但是我們需要覆蓋了 t 中的每一種字符,所以需要判斷 26 個(gè)字符的個(gè)數(shù)是不是都?jí)蛄?,如果都?jí)蛄耍褪菨M足了覆蓋子串,接下來就移動(dòng)左指針,同時(shí)修改計(jì)數(shù),這里的加減計(jì)算要和右指針移動(dòng)的相反。
  • 當(dāng)某個(gè)字符的計(jì)數(shù)變?yōu)?時(shí),我們需要判斷 26 種字符的字符個(gè)數(shù)是不是都滿足了,這里就需要26次循環(huán),是否有更高效的辦法呢?我們可以額外增加一個(gè)變量記錄有差異的字符種類數(shù)(記錄有差異的字符數(shù)也是可以的,但是后面的邏輯會(huì)有一點(diǎn)區(qū)別,思想大致相同), 初始化時(shí)順便初始化該變量,在遍歷匹配中,每當(dāng)有字符計(jì)數(shù)變?yōu)?,就修改這個(gè)變量,如果這個(gè)變量變?yōu)?則表示完全覆蓋,從而提高效率。
  • 只看文字可能不便理解,建議對(duì)照著熟悉的語言的題解一起看,希望可以有助學(xué)習(xí)理解。

算法leetcode|76. 最小覆蓋子串(rust重拳出擊),LeetCode力扣算法題目,rust,golang,數(shù)據(jù)結(jié)構(gòu),算法,后端,leetcode

題解:

rust:

impl Solution {
    pub fn min_window(s: String, t: String) -> String {
        // 少于目標(biāo)字符串中數(shù)量的字符數(shù)量
        let mut diff_char_count = 0;
        // 字符計(jì)數(shù)器
        let mut cnt = vec![0; 128];

        // 初始化
        t.as_bytes().iter().for_each(|&b| {
            // 計(jì)數(shù)減少
            cnt[b as usize] -= 1;
            if cnt[b as usize] == -1 {
                // 差異字符數(shù)增加
                diff_char_count += 1;
            }
        });

        // 覆蓋子串結(jié)果信息
        let (mut ans_len, mut ans_l) = (usize::MAX, usize::MAX);

        // 開始滑動(dòng)窗口
        let s_len = s.len();
        let (mut l, mut r) = (0, 0);
        while r < s_len {
            // 計(jì)數(shù)增加
            cnt[s.as_bytes()[r] as usize] += 1;

            // 向右移動(dòng)右邊界后,可能該字符數(shù)量沒有差異了
            if cnt[s.as_bytes()[r] as usize] == 0 {
                // 差異字符數(shù)減少
                diff_char_count -= 1;
                // 差異字符數(shù)減少后可能為0了
                if diff_char_count == 0 {
                    // 向右滑動(dòng)左邊界,直到會(huì)有差異,取滿足要求的最小串
                    while cnt[s.as_bytes()[l] as usize] > 0 {
                        cnt[s.as_bytes()[l] as usize] -= 1;
                        l += 1;
                    }

                    // 更新結(jié)果
                    if r - l + 1 < ans_len {
                        ans_len = r - l + 1;
                        ans_l = l;
                    }

                    // 向右移動(dòng)左邊界,差異字符數(shù)增加
                    cnt[s.as_bytes()[l] as usize] -= 1;
                    l += 1;
                    diff_char_count += 1;
                }
            }
            r += 1;
        }

        return if ans_l == usize::MAX {
            "".to_string()
        } else {
            s[ans_l..ans_l + ans_len].to_string()
        }
    }
}

go:

func minWindow(s string, t string) string {
    // 少于目標(biāo)字符串中數(shù)量的字符數(shù)量
	diffCharCount := 0
	// 字符計(jì)數(shù)器
	cnt := make([]int, 128)

	// 初始化
	for _, c := range t {
		// 計(jì)數(shù)減少
		cnt[c]--
		if cnt[c] == -1 {
			// 差異字符數(shù)增加
			diffCharCount++
		}
	}

	// 覆蓋子串結(jié)果信息
	ansLen, ansL := math.MaxInt32, -1

	// 開始滑動(dòng)窗口
	sLen := len(s)
	l, r := 0, 0
	for r < sLen {
		// 計(jì)數(shù)增加
		cnt[s[r]]++

		// 向右移動(dòng)右邊界后,可能該字符數(shù)量沒有差異了
		if cnt[s[r]] == 0 {
			// 差異字符數(shù)減少
			diffCharCount--
			// 差異字符數(shù)減少后可能為0了
			if diffCharCount == 0 {
				// 向右滑動(dòng)左邊界,直到會(huì)有差異,取滿足要求的最小串
				for cnt[s[l]] > 0 {
					cnt[s[l]]--
					l++
				}

				// 更新結(jié)果
				if r-l+1 < ansLen {
					ansLen = r - l + 1
					ansL = l
				}

				// 向右移動(dòng)左邊界,差異字符數(shù)增加
				cnt[s[l]]--
				l++
				diffCharCount++
			}
		}
		r++
	}

	if ansL == -1 {
		return ""
	} else {
		return s[ansL : ansL+ansLen]
	}
}

c++:

class Solution {
public:
    string minWindow(string s, string t) {
        // 少于目標(biāo)字符串中數(shù)量的字符數(shù)量
        int diffCharCount = 0;
        // 字符計(jì)數(shù)器
        int cnt[128];
        memset(cnt, 0, sizeof(cnt));

        // 初始化
        const int tLen = t.length();
        for (int i = 0; i < tLen; ++i) {
            if (--cnt[t[i]] == -1) {
                // 差異字符數(shù)增加
                ++diffCharCount;
            }
        }

        // 覆蓋子串結(jié)果信息
        int ansLen = INT_MAX, ansL = -1;

        // 開始滑動(dòng)窗口
        const int sLen = s.length();
        int l = 0, r = -1;
        while (++r < sLen) {
            // 向右移動(dòng)右邊界后,可能該字符數(shù)量沒有差異了
            if (++cnt[s[r]] == 0) {
                // 差異字符數(shù)減少后可能為0了
                if (--diffCharCount == 0) {
                    // 向右滑動(dòng)左邊界,直到會(huì)有差異,取滿足要求的最小串
                    while (--cnt[s[l++]] >= 0) {
                        // nothing
                    }

                    // 差異字符數(shù)增加
                    ++diffCharCount;

                    // 更新結(jié)果
                    if (r - l + 2 < ansLen) {
                        ansLen = r - l + 2;
                        ansL = l - 1;
                    }
                }
            }
        }

        return ansL == -1 ? "" : s.substr(ansL, ansLen);
    }
};

python:

class Solution:
    def minWindow(self, s: str, t: str) -> str:
        # 少于目標(biāo)字符串中數(shù)量的字符數(shù)量
        diff_char_count = 0
        # 字符計(jì)數(shù)器
        cnt = collections.defaultdict(int)

        # 初始化
        for c in t:
            # 計(jì)數(shù)減少
            cnt[c] -= 1
            if cnt[c] == -1:
                # 差異字符數(shù)增加
                diff_char_count += 1

        # 覆蓋子串結(jié)果信息
        ans_len, ans_l = float("inf"), -1

        # 開始滑動(dòng)窗口
        s_len = len(s)
        l, r = 0, 0
        while r < s_len:
            # 計(jì)數(shù)增加
            cnt[s[r]] += 1

            # 向右移動(dòng)右邊界后,可能該字符數(shù)量沒有差異了
            if cnt[s[r]] == 0:
                # 差異字符數(shù)減少
                diff_char_count -= 1
                # 差異字符數(shù)減少后可能為0了
                if diff_char_count == 0:
                    # 向右滑動(dòng)左邊界,直到會(huì)有差異,取滿足要求的最小串
                    while cnt[s[l]] > 0:
                        cnt[s[l]] -= 1
                        l += 1

                    # 更新結(jié)果
                    if r - l + 1 < ans_len:
                        ans_len = r - l + 1
                        ans_l = l

                    # 向右移動(dòng)左邊界,差異字符數(shù)增加
                    cnt[s[l]] -= 1
                    l += 1
                    diff_char_count += 1
            r += 1

        return "" if ans_l == -1 else s[ans_l: ans_l + ans_len]


java:

class Solution {
    public String minWindow(String s, String t) {
        // 少于目標(biāo)字符串中數(shù)量的字符數(shù)量
        int diffCharCount = 0;
        // 字符計(jì)數(shù)器
        final int[] cnt = new int[128];

        // 初始化
        final int tLen = t.length();
        for (int i = 0; i < tLen; ++i) {
            if (--cnt[t.charAt(i)] == -1) {
                // 差異字符數(shù)增加
                ++diffCharCount;
            }
        }

        // 覆蓋子串結(jié)果信息
        int ansLen = Integer.MAX_VALUE, ansL = -1;

        // 開始滑動(dòng)窗口
        final int sLen = s.length();
        int       l    = 0, r = -1;
        while (++r < sLen) {
            // 向右移動(dòng)右邊界后,可能該字符數(shù)量沒有差異了
            if (++cnt[s.charAt(r)] == 0) {
                // 差異字符數(shù)減少后可能為0了
                if (--diffCharCount == 0) {
                    // 向右滑動(dòng)左邊界,直到會(huì)有差異,取滿足要求的最小串
                    while (--cnt[s.charAt(l++)] >= 0) {
                        // nothing
                    }

                    // 差異字符數(shù)增加
                    ++diffCharCount;

                    // 更新結(jié)果
                    if (r - l + 2 < ansLen) {
                        ansLen = r - l + 2;
                        ansL = l - 1;
                    }
                }
            }
        }

        return ansL == -1 ? "" : s.substring(ansL, ansL + ansLen);
    }
}

非常感謝你閱讀本文~
歡迎【點(diǎn)贊】【收藏】【評(píng)論】三連走一波~
放棄不難,但堅(jiān)持一定很酷~
希望我們大家都能每天進(jìn)步一點(diǎn)點(diǎn)~
本文由 二當(dāng)家的白帽子:https://le-yi.blog.csdn.net/ 博客原創(chuàng)~文章來源地址http://www.zghlxwxcb.cn/news/detail-694988.html


到了這里,關(guān)于算法leetcode|76. 最小覆蓋子串(rust重拳出擊)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 算法leetcode|60. 排列序列(rust重拳出擊)

    給出集合 [1,2,3,...,n] ,其所有元素共有 n! 種排列。 按大小順序列出所有排列情況,并一一標(biāo)記,當(dāng) n = 3 時(shí), 所有排列如下: \\\"123\\\" \\\"132\\\" \\\"213\\\" \\\"231\\\" \\\"312\\\" \\\"321\\\" 給定 n 和 k ,返回第 k 個(gè)排列。 1 = n = 9 1 = k = n! 面對(duì)這道算法題目,二當(dāng)家的再次陷入了沉思。 如果模擬,按順序生成k個(gè)

    2024年02月12日
    瀏覽(19)
  • 算法leetcode|72. 編輯距離(rust重拳出擊)

    算法leetcode|72. 編輯距離(rust重拳出擊)

    給你兩個(gè)單詞 word1 和 word2 , 請返回將 word1 轉(zhuǎn)換成 word2 所使用的最少操作數(shù) 。 你可以對(duì)一個(gè)單詞進(jìn)行如下三種操作: 插入一個(gè)字符 刪除一個(gè)字符 替換一個(gè)字符 0 = word1.length, word2.length = 500 word1 和 word2 由小寫英文字母組成 面對(duì)這道算法題目,二當(dāng)家的再次陷入了沉思。 編

    2024年02月12日
    瀏覽(26)
  • 算法leetcode|62. 不同路徑(rust重拳出擊)

    算法leetcode|62. 不同路徑(rust重拳出擊)

    一個(gè)機(jī)器人位于一個(gè) m x n 網(wǎng)格的左上角 (起始點(diǎn)在下圖中標(biāo)記為 “Start” )。 機(jī)器人每次只能向下或者向右移動(dòng)一步。機(jī)器人試圖達(dá)到網(wǎng)格的右下角(在下圖中標(biāo)記為 “Finish” )。 問總共有多少條不同的路徑? 1 = m, n = 100 題目數(shù)據(jù)保證答案小于等于 2 * 10 9 面對(duì)這道算法

    2024年02月17日
    瀏覽(23)
  • 算法leetcode|54. 螺旋矩陣(rust重拳出擊)

    算法leetcode|54. 螺旋矩陣(rust重拳出擊)

    給你一個(gè) m 行 n 列的矩陣 matrix ,請按照 順時(shí)針螺旋順序 ,返回矩陣中的所有元素。 m == matrix.length n == matrix[i].length 1 = m, n = 10 -100 = matrix[i][j] = 100 面對(duì)這道算法題目,二當(dāng)家的再次陷入了沉思。 可以每次循環(huán)移動(dòng)一步,判斷移到邊界就變換方向,巧用數(shù)組可以減少邏輯判斷

    2024年02月08日
    瀏覽(20)
  • 算法leetcode|70. 爬樓梯(rust重拳出擊)

    假設(shè)你正在爬樓梯。需要 n 階你才能到達(dá)樓頂。 每次你可以爬 1 或 2 個(gè)臺(tái)階。你有多少種不同的方法可以爬到樓頂呢? 1 = n = 45 面對(duì)這道算法題目,二當(dāng)家的再次陷入了沉思。 可以爬一階或者兩階臺(tái)階,那也就是說,除了初始位置,和第一階臺(tái)階,到達(dá)其他階臺(tái)階 n 的方式

    2024年02月12日
    瀏覽(19)
  • 算法leetcode|55. 跳躍游戲(rust重拳出擊)

    給定一個(gè)非負(fù)整數(shù)數(shù)組 nums ,你最初位于數(shù)組的 第一個(gè)下標(biāo) 。 數(shù)組中的每個(gè)元素代表你在該位置可以跳躍的最大長度。 判斷你是否能夠到達(dá)最后一個(gè)下標(biāo)。 1 = nums.length = 3 * 10 4 0 = nums[i] = 10 5 面對(duì)這道算法題目,二當(dāng)家的再次陷入了沉思。 可能想到要暴力嘗試或者是雙循環(huán)

    2024年02月08日
    瀏覽(49)
  • 算法leetcode|85. 最大矩形(rust重拳出擊)

    算法leetcode|85. 最大矩形(rust重拳出擊)

    給定一個(gè)僅包含 0 和 1 、大小為 rows x cols 的二維二進(jìn)制矩陣,找出只包含 1 的最大矩形,并返回其面積。 rows == matrix.length cols == matrix[0].length 1 = row, cols = 200 matrix[i][j] 為 ‘0’ 或 ‘1’ 面對(duì)這道算法題目,二當(dāng)家的再次陷入了沉思。 要不是剛做過 84. 柱狀圖中最大的矩形 這

    2024年02月08日
    瀏覽(17)
  • 算法leetcode|89. 格雷編碼(rust重拳出擊)

    n 位格雷碼序列 是一個(gè)由 2 n 個(gè)整數(shù)組成的序列,其中: 每個(gè)整數(shù)都在范圍 [0, 2 n - 1] 內(nèi)(含 0 和 2 n - 1) 第一個(gè)整數(shù)是 0 一個(gè)整數(shù)在序列中出現(xiàn) 不超過一次 每對(duì) 相鄰 整數(shù)的二進(jìn)制表示 恰好一位不同 ,且 第一個(gè) 和 最后一個(gè) 整數(shù)的二進(jìn)制表示 恰好一位不同 給你一個(gè)整數(shù)

    2024年02月04日
    瀏覽(29)
  • 算法leetcode|71. 簡化路徑(rust重拳出擊)

    給你一個(gè)字符串 path ,表示指向某一文件或目錄的 Unix 風(fēng)格 絕對(duì)路徑 (以 \\\'/\\\' 開頭),請你將其轉(zhuǎn)化為更加簡潔的規(guī)范路徑。 在 Unix 風(fēng)格的文件系統(tǒng)中,一個(gè)點(diǎn)( . )表示當(dāng)前目錄本身;此外,兩個(gè)點(diǎn) ( .. ) 表示將目錄切換到上一級(jí)(指向父目錄);兩者都可以是復(fù)雜相

    2024年02月12日
    瀏覽(19)
  • 算法leetcode|75. 顏色分類(rust重拳出擊)

    給定一個(gè)包含紅色、白色和藍(lán)色、共 n 個(gè)元素的數(shù)組 nums , 原地 對(duì)它們進(jìn)行排序,使得相同顏色的元素相鄰,并按照紅色、白色、藍(lán)色順序排列。 我們使用整數(shù) 0 、 1 和 2 分別表示紅色、白色和藍(lán)色。 必須在不使用庫內(nèi)置的 sort 函數(shù)的情況下解決這個(gè)問題。 n == nums.length

    2024年02月10日
    瀏覽(16)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包