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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

LeetCode题库整理【Java】—— 3 无重复字符的最长子串

發(fā)布時間:2025/3/11 java 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LeetCode题库整理【Java】—— 3 无重复字符的最长子串 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

LeetCode題庫整理【Java】

## 3 無重復(fù)字符的最長子串
題目
:給定一個字符串,請你找出其中不含有重復(fù)字符的 最長子串 的長度。

示例 1:
輸入: “abcabcbb”
輸出: 3
解釋: 因?yàn)闊o重復(fù)字符的最長子串是 “abc”,所以其長度為 3。

示例 2:
輸入: “dvdf”
輸出: 1
解釋: 因?yàn)闊o重復(fù)字符的最長子串是 “vdf”,所以其長度為 3。

示例 3:
輸入: “pwwkew”
輸出: 3
解釋: 因?yàn)闊o重復(fù)字符的最長子串是 “wke”,所以其長度為 3。
請注意,你的答案必須是 子串 的長度,“pwke” 是一個子序列,不是子串。

方法:滑動窗口
我們先用一個例子來想一想如何在較優(yōu)的時間復(fù)雜度內(nèi)通過本題。

我們不妨以示例一中的字符串a(chǎn)bcabcbb 為例,找出 從每一個字符開始的,不包含重復(fù)字符的最長子串,那么其中最長的那個字符串即為答案。對于示例一中的字符串,我們列舉出這些結(jié)果,其中括號中表示選中的字符以及最長的字符串:

以(a)bcabcbb 開始的最長字符串為 (abc)abcbb;
以a(b)cabcbb 開始的最長字符串為 a(bca)bcbb;
以ab(c)abcbb 開始的最長字符串為 ab(cab)cbb;
以abc(a)bcbb 開始的最長字符串為 abc(abc)bb;
以abca(b)cbb 開始的最長字符串為 abca(bc)bb;
以abcab(c)bb 開始的最長字符串為 abcab(cb)b;
以abcabc(b)b 開始的最長字符串為 abcabc(b)b;
以abcabcb(b) 開始的最長字符串為 abcabcb(b)。

從中可以發(fā)現(xiàn),如果我們依次遞增地枚舉子串的起始位置,那么子串的結(jié)束位置也是遞增的!這里的原因在于,假設(shè)我們選擇字符串中的第 i 個字符作為起始位置,并且得到了不包含重復(fù)字符的最長子串的結(jié)束位置為 rp。那么當(dāng)我們選擇第 i+k 個字符作為起始位置時,首先從 i+k 到 rp 的字符顯然是不重復(fù)的,并且由于少了原本的第 k 個字符,我們可以嘗試?yán)^續(xù)增大 rp ,直到右側(cè)出現(xiàn)了重復(fù)字符為止。

我們使用兩個指針表示字符串中的某個子串的左右邊界。其中左指針代表著上文中**「枚舉子串的起始位置 i」**,而右指針即為上文中的 rp ;

在每一步的操作中,我們會將左指針向右移動一格,表示 我們開始枚舉下一個字符作為起始位置,然后我們可以不斷地向右移動右指針,但需要保證這兩個指針對應(yīng)的子串中沒有重復(fù)的字符。在移動結(jié)束后,這個子串就對應(yīng)著 以左指針開始的,不包含重復(fù)字符的最長子串。我們記錄下這個子串的長度;

在枚舉結(jié)束后,我們找到的最長的子串的長度即為答案。

在上面的流程中,我們還需要使用一種數(shù)據(jù)結(jié)構(gòu)來判斷是否有重復(fù)的字符,常用的數(shù)據(jù)結(jié)構(gòu)為哈希集合(即 C++ 中的 std::unordered_set,Java 中的 HashSet,Python 中的 set, JavaScript 中的 Set)。在左指針向右移動的時候,我們從哈希集合中移除一個字符,在右指針向右移動的時候,我們往哈希集合中添加一個字符。

LeetCode的官網(wǎng)中關(guān)于 滑動窗口 也有視頻及文字題解

以下代碼與官網(wǎng)版本略有差異,并通過了測試,僅供參考

class Solution {public int lengthOfLongestSubstring(String s) {//len記錄窗口滑動過程中存儲的當(dāng)前無重復(fù)字符的最長子串長度int len=0;//哈希集合,記錄每個字符是否出現(xiàn)過HashSet<Character> set = new HashSet<Character>();int n = s.length();//右指針,初始值為0,相當(dāng)于我們在字符串的左邊界,還未開始移動int rp = 0;for(int i=0; i<n; i++) { //i就相當(dāng)于左指針,從0開始if(i!=0) {set.remove(s.charAt(i-1));}while(rp<n && !set.contains(s.charAt(rp)) ) {set.add(s.charAt(rp));++rp;}len = Math.max(len, (rp-1)-i+1);}return len;} }

測試結(jié)果

在代碼調(diào)試過程中,尤其需要注意指針rp的位置,防止數(shù)組越界及使用哈希表判斷有無重復(fù)字符時出現(xiàn)異常錯誤

使用自己的Eclipse測試的完整代碼

/*003 無重復(fù)字符的最長子串*/ package leet.code;import java.util.HashSet; import java.util.Scanner;public class LongestSubstring {public static void main(String[] args) {// TODO Auto-generated method stubLongestSubstring ls = new LongestSubstring();@SuppressWarnings("resource")Scanner sc = new Scanner(System.in);String str = sc.nextLine();int len = ls.lengthOfLongestSubstring(str);System.out.println(len);}public int lengthOfLongestSubstring(String s) {//len記錄窗口滑動過程中存儲的當(dāng)前無重復(fù)字符的最長子串長度int len=0;//哈希集合,記錄每個字符是否出現(xiàn)過HashSet<Character> set = new HashSet<Character>();int n = s.length();//右指針,初始值為-1,相當(dāng)于我們在字符串的左邊界,還未開始移動int rp = 0;for(int i=0; i<n; i++) { //i就相當(dāng)于左指針,從0開始if(i!=0) {//左指針右移時,要移除哈希表中的一個字符,在s中下標(biāo)為i-1set.remove(s.charAt(i-1));}while(rp<n && !set.contains(s.charAt(rp)) ) {//指針右移過程中,若字符不重復(fù),則往哈希表中添加一個字符set.add(s.charAt(rp));++rp;}len = Math.max(len, (rp-1)-i+1);//rp跳出while時向右移到了有重復(fù)字符的地方,計算Len時需要減1}return len;} }

總結(jié)

以上是生活随笔為你收集整理的LeetCode题库整理【Java】—— 3 无重复字符的最长子串的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。