簡體   English   中英

Java 滑動窗口問題:給定一個字符串,找出最長的子字符串的長度,它包含所有不同的字符。 比較解決方案

[英]Java Sliding Window Problem: Given a string, find the length of the longest substring, which has all distinct characters. Comparing Solutions

我正在上一門課程來准備編碼面試,它的工作原理是我嘗試一個問題然后提出解決方案。

問題:給定一個字符串,找出所有不同字符的最長子字符串的長度。

示例:輸入:String="aabccbb" 輸出:3 解釋:具有不同字符的最長子字符串是“abc”。

我想知道在這個問題上是否有任何理由使用 HashMap 而不是 ArrayList? 我將展示這兩種解決方案,我想知道我的解決方案是否因任何原因出錯或效率低下?

我的解決方案有效並且輸出匹配(3,2,3)。 這就是為什么我想知道我是否做錯了什么,因為他們的解決方案似乎比需要的復雜得多?

我的解決方案:

import java.util.*;
class NoRepeatSubstring {
  public static int findLength(String str) {
    // TODO: Write your code here
    List<Character> charList = new ArrayList<Character>();
    int maxLength = 0;

    for(int windowEnd = 0; windowEnd < str.length(); windowEnd++) {
      
      while(charList.contains(str.charAt(windowEnd))) {
        charList.remove(0);
      }
      
      charList.add(str.charAt(windowEnd));
      
      if(charList.size() > maxLength) {
        maxLength = charList.size();
      }
    }
    return maxLength;
  }

  public static void main(String[] args) {
    System.out.println("Length of the longest substring: " + NoRepeatSubstring.findLength("aabccbb"));
    System.out.println("Length of the longest substring: " + NoRepeatSubstring.findLength("abbbb"));
    System.out.println("Length of the longest substring: " + NoRepeatSubstring.findLength("abccde"));
  }

}



他們的解決方案:

import java.util.*;

class NoRepeatSubstring {
  public static int findLength(String str) {
    int windowStart = 0, maxLength = 0;
    Map<Character, Integer> charIndexMap = new HashMap<>();
    // try to extend the range [windowStart, windowEnd]
    for (int windowEnd = 0; windowEnd < str.length(); windowEnd++) {
      char rightChar = str.charAt(windowEnd);
      // if the map already contains the 'rightChar', shrink the window from the beginning so that
      // we have only one occurrence of 'rightChar'
      if (charIndexMap.containsKey(rightChar)) {
        // this is tricky; in the current window, we will not have any 'rightChar' after its previous index
        // and if 'windowStart' is already ahead of the last index of 'rightChar', we'll keep 'windowStart'
        windowStart = Math.max(windowStart, charIndexMap.get(rightChar) + 1);
      }
      charIndexMap.put(rightChar, windowEnd); // insert the 'rightChar' into the map
      maxLength = Math.max(maxLength, windowEnd - windowStart + 1); // remember the maximum length so far
    }

    return maxLength;
  }

  public static void main(String[] args) {
    System.out.println("Length of the longest substring: " + NoRepeatSubstring.findLength("aabccbb"));
    System.out.println("Length of the longest substring: " + NoRepeatSubstring.findLength("abbbb"));
    System.out.println("Length of the longest substring: " + NoRepeatSubstring.findLength("abccde"));
  }
}


charList.contains(str.charAt(windowEnd))是 O(n) 而charIndexMap.containsKey(rightChar)是( 通常) O(1)。

charList.contains遍歷整個列表以檢查字符是否在列表中。 charIndexMap.containsKey對字符/鍵進行哈希處理,該字符/鍵在時間上是恆定的。

(使用固定大小為 2^8(=可能的字符數)的布爾數組並將字符用作數組的索引會更快。這將保證為 O(1) 並且使用小字符串也更快,因為沒有時間浪費在計算哈希上。)

ArrayList 的 contains 方法是 O(N),但 HashMap 的主要是 O(1)。 事實上,你甚至不需要在這里使用 HashMap,甚至 HashSet 都可以。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM