1. 程式人生 > 實用技巧 >LeetCode 第 32 場雙週賽

LeetCode 第 32 場雙週賽

手速過慢,手感不穩,掛 4 發。

1539.第 k 個缺失的正整數

題目連結:1539.第 k 個缺失的正整數

給你一個 嚴格升序排列 的正整數陣列 arr 和一個整數 k

請你找到這個數組裡第 k 個缺失的正整數。

示例 Sample

示例 1:

輸入: arr = [2,3,4,7,11], k = 5
輸出: 9
解釋: 缺失的正整數包括 [1,5,6,8,9,10,12,13,...] 。第 5 個缺失的正整數為 9 。

示例 2:

輸入: arr = [1,2,3,4], k = 2
輸出: 6
解釋: 缺失的正整數包括 [5,6,7,...] 。第 2 個缺失的正整數為 6 。

提示:

  • 1 <= arr.length <= 1000
  • 1 <= arr[i] <= 1000
  • 1 <= k <= 1000
  • 對於所有 1 <= i < j <= arr.lengthij 滿足 arr[i] < arr[j]

我的題解

class Solution {
 public:
  int findKthPositive(vector<int>& arr, int k) {
    vector<bool>vis(arr.size() + k + 1);
    for(int i = 0; i < arr.size(); i++)
      if(arr[i] < vis.size())
        vis[arr[i]] = true;
    for(int i = 1, c = 0; i < vis.size(); i++) {
      if(!vis[i])
        c++;
      if(c == k)
        return i;
    }
    return vis.size();
  }
};

1540.K 次操作轉變字串

題目連結:1540.K 次操作轉變字串

給你兩個字串 st ,你的目標是在 k 次操作以內把字串 s 轉變成 t

在第 i 次操作時(1 <= i <= k),你可以選擇進行如下操作:

  • 選擇字串 s 中滿足 1 <= j <= s.length 且之前未被選過的任意下標 j (下標從 1 開始),並將此位置的字元切換 i 次。
  • 不進行任何操作。

切換 1 次字元的意思是用字母表中該字母的下一個字母替換它(字母表環狀接起來,所以 'z' 切換後會變成 'a')。

請記住任意一個下標 j 最多隻能被操作 1 次。

如果在不超過 k 次操作內可以把字串 s

轉變成 t ,那麼請你返回 true ,否則請你返回 false

示例 Sample

示例 1:

輸入: s = "input", t = "ouput", k = 9
輸出: true
解釋: 第 6 次操作時,我們將 'i' 切換 6 次得到 'o' 。第 7 次操作時,我們將 'n' 切換 7 次得到 'u' 。

示例 2:

輸入: s = "abc", t = "bcd", k = 10
輸出: false
解釋: 我們需要將每個字元切換 1 次才能得到 t 。我們可以在第 1 次操作時將 'a' 切換成 'b' ,但另外 2 個字母在剩餘操作中無法再轉變為 t 中對應字母。

示例 3:

輸入: s = "aab", t = "bbb", k = 27
輸出: true
解釋: 第 1 次操作時,我們將第一個 'a' 切換 1 次得到 'b' 。在第 27 次操作時,我們將第二個字母 'a' 切換 27 次得到 'b' 。

提示:

  • 1 <= s.length, t.length <= 10^5
  • 0 <= k <= 10^9
  • st 只包含小寫英文字母。

我的題解

class Solution {
 public:
  bool canConvertString(string s, string t, int k) {
    if(s.length() != t.length())
      return false;
    map<int, int>vis;
    for(int i = 0, c; i < s.length(); i++) {
      if(s[i] == t[i])
        continue;
      if(s[i] < t[i])
        c = t[i] - s[i];
      else
        c = 26 - s[i] + t[i];
      if(c + vis[c] * 26 > k)
        return false;
      vis[c]++;
    }
    return true;
  }
};

1541.平衡括號字串的最少插入次數

題目連結:1541.平衡括號字串的最少插入次數

給你一個括號字串 s ,它只包含字元 '('')' 。一個括號字串被稱為平衡的當它滿足:

  • 任何左括號 '(' 必須對應兩個連續的右括號 '))'
  • 左括號 '(' 必須在對應的連續兩個右括號 '))' 之前。

比方說 "())""())(())))""(())())))" 都是平衡的, ")()""()))"
"(()))" 都是不平衡的。

你可以在任意位置插入字元 '(' 和 ')' 使字串平衡。

請你返回讓 s 平衡的最少插入次數。

示例 Sample

示例 1:

輸入: s = "(()))"
輸出: 1
解釋: 第二個左括號有與之匹配的兩個右括號,但是第一個左括號只有一個右括號。我們需要在字串結尾額外增加一個 ')' 使字串變成平衡字串 "(())))" 。

示例 2:

輸入: s = "())"
輸出: 0
解釋: 字串已經平衡了。

示例 3:

輸入: s = "))())("
輸出: 3
解釋: 新增 '(' 去匹配最開頭的 '))' ,然後新增 '))' 去匹配最後一個 '(' 。

示例 4:

輸入: s = "(((((("
輸出: 12
解釋: 新增 12 個 ')' 得到平衡字串。

示例 5:

輸入: s = ")))))))"
輸出: 5
解釋: 在字串開頭新增 4 個 '(' 並在結尾新增 1 個 ')' ,字串變成平衡字串 "(((())))))))" 。

提示:

  • 1 <= s.length <= 10^5
  • s 只包含 '('')'

我的題解

class Solution {
 public:

  int gao(string &s)const {
    int l(0), r(0);
    for(int i = 0; i < s.length(); i++) {
      if(s[i] == '(')
        l++;
      else if(s[i] == ')') {
        if(l > 0)
          l--;
        else
          r++;
      }
    }
    return 2 * l + r;
  }

  int minInsertions(string s) {
    string t;
    int ans(0);
    for(int i = 0; i < s.length(); i++) {
      t += s[i];
      if(s[i] == ')') {
        if((i + 1 < s.length() && s[i + 1] == ')'))
          i++;
        else
          ans++;
      }
    }
    return ans + gao(t);
  }
};

1542.找出最長的超讚子字串

題目連結:1542.找出最長的超讚子字串

給你一個字串 s 。請返回 s 中最長的 超讚子字串 的長度。

「超讚子字串」需滿足滿足下述兩個條件:

  • 該字串是 s 的一個非空子字串
  • 進行任意次數的字元交換後,該字串可以變成一個迴文字串

示例 Sample

示例 1:

輸入: s = "3242415"
輸出: 5
解釋: "24241" 是最長的超讚子字串,交換其中的字元後,可以得到迴文 "24142"

示例 2:

輸入: s = "12345678"
輸出: 1

示例 3:

輸入: s = "213123"
輸出: 6
解釋: "213123" 是最長的超讚子字串,交換其中的字元後,可以得到迴文 "231132"

示例 4:

輸入: s = "00"
輸出: 2

提示:

  • 1 <= s.length <= 10^5
  • s 僅由數字組成

我的題解

class Solution {
 public:
  int longestAwesome(string s) const {
    vector<int>a(s.length() + 1, 0);
    vector<int>g((1 << 11), -1);
    for(int i = 0; i < s.length(); i++) {
      a[i + 1] = a[i] ^ (1 << (s[i] - '0'));
    }
    int ans(0);
    for(int i = 0; i <= s.length(); i++) {
      if(g[a[i]] == -1)
        g[a[i]] = i;
      ans = max(ans, i - g[a[i]]);
      int t = a[i];
      for(int j = 0; j < 10; j++) {
        t = a[i] ^ (1 << j);
        if(g[t] != -1)
          ans = max(ans, i - g[t]);
      }
    }

    return ans;
  }
};