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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

无重复字符的最长子串【三种解法】--LeetCode

發布時間:2025/4/16 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 无重复字符的最长子串【三种解法】--LeetCode 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述

給定一個字符串,請你找出其中不含有重復字符的 最長子串 的長度。

輸入: "abcabcbb" 輸出: 3 解釋: 因為無重復字符的最長子串是 "abc",所以其長度為 3。 輸入: "bbbbb" 輸出: 1 解釋: 因為無重復字符的最長子串是 "b",所以其長度為 1。 輸入: "pwwkew" 輸出: 3 解釋: 因為無重復字符的最長子串是 "wke",所以其長度為 3。請注意,你的答案必須是 子串 的長度,"pwke" 是一個子序列,不是子串。

算法簡析

  • 通過i,j構建滑動窗口。(因為只能是連續的子串)達到O(n)。
  • 每一步需要找到,添加對應的一個點,是否已經在原表中存在了。在cpp上,我這里用了一個隊列的出入隊列來進行模擬。同時構建一個hash表來用O(1)的復雜度來進行定位。

改進思路:隊列在這個步驟中似乎用處不大。直接用游標i來記錄左窗口的數值即可。

原版代碼

#include <queue> class Solution { public:int lengthOfLongestSubstring(string s) {int ans = 0, i = 0, j = 0, max_=0, n=s.size();for(i = 0; i < s.size(); ++i) {max_ = (max_ > s[i]) ? max_ : s[i];}bool * b_ptr = new bool[max_+1];for(i = 0; i <= max_; ++i) {b_ptr[i] = false;}i = 0, j = 0;int tmp;queue<int> q;while (i < n && j < n) {if(!b_ptr[s[j]]) {b_ptr[s[j]]=true;q.push(s[j]);j++;ans = (ans > j - i) ? ans : j - i;} else {tmp = q.front();q.pop();i++;b_ptr[tmp]=false;}}delete[] b_ptr;return ans;} };

改進版代碼

  • 將隊列去掉,直接用i來定位之前的序列

再改進思路:數組規模過大。初始化時間或稱為最大的下限。

class Solution { public:int lengthOfLongestSubstring(string s) {int ans = 0, i = 0, j = 0, max_=0, n=s.size();for(i = 0; i < s.size(); ++i) {max_ = (max_ > s[i]) ? max_ : s[i];}bool * b_ptr = new bool[max_+1];for(i = 0; i <= max_; ++i) {b_ptr[i] = false;}i = 0, j = 0;int tmp;while (i < n && j < n) {if(!b_ptr[s[j]]) {b_ptr[s[j]]=true;j++;ans = (ans > j - i) ? ans : j - i;} else {tmp = s[i++];b_ptr[tmp]=false;}}delete[] b_ptr;return ans;} };

再改進

  • 將數組的規模變得更小
  • 但是添加了每次都要進行一次加法的運算,這樣很影響時間效率。

根據估算,ascii碼的長度其實有限,所以空間大小不會有太的的變化,但是,時間上的增加卻是不可原諒的。

class Solution { public:int lengthOfLongestSubstring(string s) {if (s.size() == 0) return 0;int ans = 0, i = 0, j = 0, max_=0, n=s.size(), min_;for(i = 0; i < s.size(); ++i) {max_ = (max_ > s[i]) ? max_ : s[i];min_ = (min_ < s[i]) ? min_ : s[i];}bool * b_ptr = new bool[max_ - min_ + 1];for(i = 0; i <= max_ - min_; ++i) {b_ptr[i] = false;}i = 0, j = 0;int tmp;while (i < n && j < n) {if(!b_ptr[s[j] - min_]) {b_ptr[s[j] - min_]=true;j++;ans = (ans > j - i) ? ans : j - i;} else {tmp = s[i++];b_ptr[tmp - min_]=false;}}delete[] b_ptr;return ans;} };

總結

以上是生活随笔為你收集整理的无重复字符的最长子串【三种解法】--LeetCode的全部內容,希望文章能夠幫你解決所遇到的問題。

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