無重復字符的最長子串算法(滑動窗口)- OC

昨天被網易二面投屏算法虐了一番,痛定思痛,每日一道算法題。下面來看看這道算法題:

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

輸入: "abcabcbb"

輸出: 3,abc,bca,cab

解釋: 因為無重復字符的最長子串是 "abc",所以其長度為 3。

這道題其實是一道經典的滑動窗口應用的題目,但是上網查了一下,結果很多的OC算法代碼其實都是錯誤的,例如點擊最多的這位(【iOS每日算法】無重復字符的最長子串(滑動窗口):給定一個字符串,請你找出其中不含有重復字符的 最長子串 的長度。 - 簡書),下面先上代碼:

`- (NSInteger)checkTheStringScan:(NSString *)content {

? ? //abdfhabcojdsnagjsu

? ? NSInteger length = content.length;

? ? // 記錄已經遍歷過的字符所在位置的字典

? ? NSMutableDictionary *checkedDict = [[NSMutableDictionary alloc]init];

? ? //設置我們需要得到的最長子串的長度

? ? NSInteger maxLength = 0;

? ? //記錄子串起始位置的指針

? ? NSInteger start = 0;

? ? // 循環字符串 i 為右邊指針,不斷向右移動,像一個往右劃的窗口

? ? for (NSInteger i = 0; i < length ; i++) {

? ? ? ? NSRange letterRange = NSMakeRange(i, 1);

? ? ? ? NSString *letter = [content substringWithRange:letterRange];

? ? ? ? // 判斷是否含有滑動加入的字符

? ? ? ? if([[checkedDict allKeys]containsObject:letter]) {

? ? ? ? ? ? // 如果有將記錄子串起始位置的start移動到該字符之前出現的位置的下一個位置

? ? ? ? ? ? // 相當于把左邊指針向右拉,直到不包含當前遍歷的字符,這樣這個子串中就沒有重復字符了

? ? ? ? ? ? start = [[checkedDict objectForKey:letter] integerValue] + 1;

? ? ? ? }

? ? ? ? //注意這里必須也是網上常常錯誤的地方,每個i即右指針都需要經過計算得到當前子串長度

? ? ? ? NSInteger tempLength = i - start + 1;

? ? ? ? // 取最長的子串

? ? ? ? if(tempLength >=maxLength) {

? ? ? ? ? ? maxLength = tempLength;

? ? ? ? ? ? NSLog(@"%@",[content substringWithRange:NSMakeRange(start, maxLength)]);

? ? ? ? }

? ? ? ? // 更新子串中該字符位置

? ? ? ? [checkedDict setObject:@(i) forKey:letter];

? ? }

? ? return maxLength;

}`

實現思路的話,主要就是通過for循環,以i為右指針開始滑動,當遇到相同字符的時候,對兩者后面的一個進行位置i的記錄(這里使用了字典的key來實現的,也可以使用Set實現,唯一性保證),記錄完相同字符后,左指針start記錄相同字符前者的后一個字符位置,取左右指針的中間長度tempLength計算方式:i-start+1,記錄完成后遍歷自校tempLength的最大長度即最長不重復子串的長度,start即最長子串起始位置,得出最長子串內容如下:

`2021-07-15 15:40:19.677857+0800 arithmeticTest[19183:2180250] fhabcojdsn

2021-07-15 15:40:19.678016+0800 arithmeticTest[19183:2180250] 10`

第二種更簡單的NSMutableSet實現的滑動窗口,直接代碼:

`- (void)checkTheStringScanTwo {

? ? NSString *str = @"abdfhabcojdsnagjsu";

? ? NSMutableSet *set = [NSMutableSet new];

? ? long n = str.length;

? ? //ans:最長子串長度,j:右指針,i:左指針

? ? int ans = 0, i = 0, j = 0 ,index = 0;

? ? while (i<n && j<n) {

? ? ? ? //和上一個算法相反,判斷不包含則添加更合理

? ? ? ? if (![set containsObject:[str substringWithRange:NSMakeRange(j,1)]]) {

? ? ? ? ? ? //右指針滑動

? ? ? ? ? ? [set addObject:[str substringWithRange:NSMakeRange(j++, 1)]];

? ? ? ? ? ? //取指針區間內最大值

? ? ? ? ? ? if (j - i > ans) {

? ? ? ? ? ? ? ? ans = j - i;

? ? ? ? ? ? ? ? index = i;

? ? ? ? ? ? }

? ? ? ? }else{

? ? ? ? ? ? //出現相同字符則刪除前一個,并i++,左指針右偏移一

? ? ? ? ? ? [set removeObject:[str substringWithRange:NSMakeRange(i++, 1)]];

? ? ? ? }

}

? ? NSLog(@"%@",[str substringWithRange:NSMakeRange(index, ans)]);

}`

平時多積累,面試別緊張,冷靜思考,其實都不難。

不念過往,砥礪前行。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容