無重複字符的最長子串

給定一個字符串,請你找出其中不含有重複字符的最長子串的長度。(LeetCode題目)

示例 1:

輸入: "abcabcbb"
輸出: 3 
解釋: 因爲無重複字符的最長子串是 "abc",所以其長度爲 3。

示例 2:

輸入: "bbbbb"
輸出: 1
解釋: 因爲無重複字符的最長子串是 "b",所以其長度爲 1。

示例 3:

輸入: "pwwkew"
輸出: 3
解釋: 因爲無重複字符的最長子串是 "wke",所以其長度爲 3。

請注意,你的答案必須是 子串 的長度,"pwke" 是一個子序列,不是子串。

方法一:暴力法

  • 思路
    • 逐個檢查所有的子字符串,看它是否不含有重複的字符。
  • 算法
    • 1.爲了枚舉給定字符串的所有子字符串,我們需要枚舉它們開始和結束的索引。假設開始和結束的索引分別爲 i 和 j。那麼我們有 0≤i<j≤n。因此,使用 i從 0 到 n−1以及 j從 i+1到n這兩個嵌套的循環,我們可以枚舉出 s 的所有子字符串。

    • 2.判斷索引從i~j的字串是否包含重複的字符,若不包含則更新最大長度.

沒使用Hash表,判斷字符處可使用Hash表來降低時間複雜度
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if (s.size() == 0)
            return 0;
        int len = 1;
        for (int i = 0; i < s.size(); ++i) {
            bool f = true;
            for (int j = i + 1; j < s.size(); ++j) {
                if (!f) //已檢測到當前重複字符,則從當前j~i+1的後續字符不必再檢測
                    break;
                for (int k = i; k < j; ++k) { //判斷從i~j+1的字符是否存在重複
                    if (s[k] == s[j]) {
                        f = false;
                        break;
                    }
                }
                if (f)
                    len = len > (j - i + 1) ? len : (j - i + 1); //更新最大長度
            }
        }
        return len;
    }
};

方法二:滑動窗口

  • 算法
    • 滑動窗口是數組/字符串問題中常用的抽象概念。 窗口通常是在數組/字符串中由開始和結束索引定義的一系列元素的集合,即 [i,j)(左閉,右開)。而滑動窗口是可以將兩個邊界向某一方向“滑動”的窗口。使用 Hash表將字符存儲在當前窗口 [i,j)(最初 j=i)中。 然後我們向右側滑動索引 j,如果它不在 Hash表中,我們會繼續滑動 j。直到 s[j] 已經存在於 Hash表中。此時,我們找到的沒有重複字符的最長子字符串將會以索引 i開頭。
    class Solution {
    public:
      //以字符作爲key,以下表作爲value
      struct Hash_data {
          int key, value;
      };
      struct Hash_table {
          Hash_data** table;
          int width;
          Hash_table(int width) {
              this->width = width;
              table = (Hash_data**)malloc(sizeof(Hash_data*) * width);
              memset(table, NULL, sizeof(Hash_data*) * width);
          }
          int addr(int key) {
              return key % width;
          }
          void insert(char ch, int index) {
              Hash_data* data = new Hash_data();
              data->key = ch;
              data->value = index;
              int k = addr(ch);
              table[k] = data;
          }
          void remove(char ch) {
              int k = addr(ch);
              table[k] = NULL;
          }
          bool contain(char ch) {
              int k = addr(ch);
              Hash_data* data = table[k];
              if (data)
                  return true;
              else
                  return false;
          }
    
      };
      int lengthOfLongestSubstring(string s) {
          int maxlen = 0;
          int len = s.size();
          int i, j;
          i = j = 0;
          Hash_table table(256);//初始化Hash表大小爲256(char型大小)
          while (i<len&&j<len)
          {
              if (table.contain(s[j])) {
                  table.remove(s[i]);
                  i++;
              }
              else {
                  table.insert(s[j], j);
                  maxlen = maxlen > (j - i+1) ? maxlen : (j - i+1);
                  j++;
              }
    
          }
          return maxlen;
      }
    };
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章