zoukankan      html  css  js  c++  java
  • 3. Longest Substring Without Repeating Characters

    3. Longest Substring Without Repeating Characters

    Given a string, find the length of the longest substring without repeating characters.

    Example 1:

    Input: "abcabcbb"
    Output: 3 
    Explanation: The answer is "abc", with the length of 3. 
    

    Example 2:

    Input: "bbbbb"
    Output: 1
    Explanation: The answer is "b", with the length of 1.
    

    Example 3:

    Input: "pwwkew"
    Output: 3
    Explanation: The answer is "wke", with the length of 3. 
                 Note that the answer must be a substring, "pwke" is a subsequence and not a substring.
    

    分析:

    题目要求的是一个字符串里最长的不包含重复字符的子串,这个子串的位置可以任意的,返回这个子串的长度。

    1. 常规解法:暴力比较

      1. 得到这个字符串的每一个子串
      2. 计算他们的长度,得到最大值

      分析:

      1. 姑且不论这种方法是否够好,在for循环的条件里最好还是不要进行计算长度,先在循环外进行一次计算就好。
      2. 最大的问题还是时间复杂度太高,求子串的时间复杂度是O(n2),内部内嵌套一个时间复杂度为O(n)的判断该子串是否包含重复字符的循环,那么最终时间复杂度会是O(n3),在LeetCode无法通过。

      Solution 1:

      class Solution {
          public int lengthOfLongestSubstring(String s) {
              int ans = 0;
              String substr = null;
              for(int i = 0; i < s.length(); i++) {
                  for(int j = i + 1; j < s.length() + 1; j++) {
                      substr = s.substring(i, j);// 子串为i-j,不包括j
                      if(unique(substr)) {
                          ans = Math.max(ans, substr.length());
                      }
                  }
              }
              return ans;
          }
          
          
          public static boolean unique(String str) {
              Set<Character> set = new HashSet<>();
              for(int i = 0; i < str.length(); i++) {
                  char c = str.charAt(i);
                  if(set.contains(c)) {
                      return false;
                  }
                  set.add(c);
              }
              return true;
          }
      }
      
    2. 改进方法:类似于滑动窗口

            分别使用i,j表示窗口的左端和右端,每当j++窗口右端右移,加入一个新的字符时就判断是否有重复的字符,如果没有就更新ans的值,否则窗口的左端也右移 i++,窗口的左端也右移之后也是还要继续判断是不是还有重复的字符,如此窗口一直右移直到一端移除边界。

      分析:

            时间复杂度为O(n)。

      Solution 2:

      public class Solution {
          public int lengthOfLongestSubstring(String s) {
              if(s == null || s.length() == 0) {
                  return 0;
              }
              
              Set<Character> set = new HashSet<>();
              int i = 0, j = 0, ans = 0;
              int n = s.length();
              
              while(j < n) {
                  if(set.contains(s.charAt(j))) {
                      set.remove(s.charAt(i++));
                  } else {
                      set.add(s.charAt(j++));// 如果窗口里还有j,就将j加入窗口
                      ans = Math.max(ans, set.size());// 并更新窗口的最大值
                  }
              } 
              return ans;
          }
      }
      
  • 相关阅读:
    HDU--4548 美素数
    【思维】南阳理工 14 会场安排问题
    【思维】【水】 南阳oj 喷水装置(一)
    【思维】南阳理工91 阶乘之和
    【转】哈夫曼树 九度1172
    Array
    HDU--1702 ACboy needs your help again!
    栈和队列
    3.Compound data types
    4.Object Oriented Programming
  • 原文地址:https://www.cnblogs.com/zhuobo/p/10759344.html
Copyright © 2011-2022 走看看