Find longest substring without repeating characters

前端 未结 30 2243
轻奢々
轻奢々 2020-12-12 18:07

Given a string S of length N find longest substring without repeating characters.

Example:

Input:

相关标签:
30条回答
  • 2020-12-12 19:01

    This is my solution, and it was accepted by leetcode. However, after I saw the stats, I saw whole lot solutions has much faster result....meaning, my solution is around 600ms for all their test cases, and most of the js solutions are around 200 -300 ms bracket.. who can tell me why my solution is slowwww??

    var lengthOfLongestSubstring = function(s) {
      var arr = s.split("");
    
      if (s.length === 0 || s.length === 1) {
        return s.length;
      }
    
      var head = 0,
        tail = 1;
      var str = arr[head];
      var maxL = 0;
      while (tail < arr.length) {
        if (str.indexOf(arr[tail]) == -1) {
          str += arr[tail];
          maxL = Math.max(maxL, str.length);
          tail++;
        } else {
          maxL = Math.max(maxL, str.length);
          head = head + str.indexOf(arr[tail]) + 1;
          str = arr[head];
          tail = head + 1;
        }
      }
      return maxL;
    };

    0 讨论(0)
  • 2020-12-12 19:03

    Here are two ways to approach this problem in JavaScript.

    A Brute Force approach is to loop through the string twice, checking every substring against every other substring and finding the maximum length where the substring is unique. We'll need two functions: one to check if a substring is unique and a second function to perform our double loop.

    // O(n) time
    const allUnique = str => {
      const set = [...new Set(str)];
      return (set.length == str.length) ? true: false;
    }
    
    // O(n^3) time, O(k) size where k is the size of the set
    const lengthOfLongestSubstring = str => {
      let result = 0,
          maxResult = 0;
      for (let i=0; i<str.length-1; i++) {
        for (let j=i+1; j<str.length; j++) {
          if (allUnique(str.substring(i, j))) {
            result = str.substring(i, j).length;
            if (result > maxResult) {
              maxResult = result;
            }
          }
        }
      return maxResult;
      }
    }
    

    This has a time complexity of O(n^3) since we perform a double loop O(n^2) and then another loop on top of that O(n) for our unique function. The space is the size of our set which can be generalized to O(n) or more accurately O(k) where k is the size of the set.

    A Greedy Approach is to loop through only once and keep track of the maximum unique substring length as we go. We can use either an array or a hash map, but I think the new .includes() array method is cool, so let's use that.

    const lengthOfLongestSubstring = str => {
      let result = [],
          maxResult = 0;
    
      for (let i=0; i<str.length; i++) {
        if (!result.includes(str[i])) {
          result.push(str[i]);
        } else {
          maxResult = i;
        }
      }
    
      return maxResult;
    }
    

    This has a time complexity of O(n) and a space complexity of O(1).

    0 讨论(0)
  • 2020-12-12 19:04

    I was asked the same question in an interview.

    I have written Python3 code, to find the first occurrence of the substring with all distinct chars. In my implementations, I start with index = 0 and iterate over the input string. While iterating used a Python dict seems to store indexes of chars in input-string those has been visited in the iteration.

    In iteration, if char c, does not find in current substring – raise KeyError exception

    if c found to be a duplicate char in the current substring (as c previously appeared during iteration – named that index last_seen) start a new substring

    def lds(string: str) -> str:
        """ returns first longest distinct substring in input `string` """
        seens = {}
        start, end, curt_start = 0, 0, 0
        for curt_end, c in enumerate(string):
            try:
                last_seen = seens[c]
                if last_seen < curt_start:
                    raise KeyError(f"{c!r} not found in {string[curt_start: curt_end]!r}")
                if end - start <  curt_end - curt_start:
                    start, end = curt_start, curt_end
                curt_start = last_seen + 1
            except KeyError:
                pass
            seens[c] = curt_end
        else: 
            # case when the longest substring is suffix of the string, here curt_end
            # do not point to a repeating char hance included in the substring
            if string and end - start <  curt_end - curt_start + 1:
                start, end = curt_start, curt_end + 1
        return string[start: end]
    
    0 讨论(0)
  • 2020-12-12 19:04

    Question: Find the longest substring without repeating characters. Example 1 :

        import java.util.LinkedHashMap;
        import java.util.Map;
    
        public class example1 {
    
            public static void main(String[] args) {
                String a = "abcabcbb";
                   // output => 3
                System.out.println( lengthOfLongestSubstring(a));
    
            }
    
            private static int lengthOfLongestSubstring(String a) {
                   if(a == null  || a.length() == 0) {return  0 ;}  
                   int res = 0 ;
                Map<Character , Integer> map = new LinkedHashMap<>();
                  for (int i = 0; i < a.length(); i++) {
                      char ch = a.charAt(i);
                    if (!map.containsKey(ch)) {
           //If ch is not present in map, adding ch into map along with its position
                        map.put(ch, i);
    
                    }else {
    /*
    If char ch is present in Map, reposition the cursor i to the position of ch and clear the Map.
    */ 
                        i = map.put(ch, i);// updation of index
                         map.clear();
                    }//else
    
                    res = Math.max(res, map.size());
    
                }
    
    
    
                return res;
            }
    
        }
    

    if you want the longest string without the repeating characters as output then do this inside the for loop:

    String res ="";// global
        int len = 0 ;//global
     if(len < map.size()) {
         len = map.size();
        res = map.keySet().toString();
     }
    System.out.println("len -> " + len);
    System.out.println("res => " + res);
    
    0 讨论(0)
  • 2020-12-12 19:05

    I am posting O(n^2) in python . I just want to know whether the technique mentioned by Karoly Horvath has any steps that are similar to existing search/sort algorithms ?

    My code :

    def main():
        test='stackoverflow'
        tempstr=''
        maxlen,index=0,0
        indexsubstring=''
        print 'Original string is =%s\n\n' %test
    
        while(index!=len(test)):
            for char in test[index:]:
                if char not in tempstr:
                    tempstr+=char
                    if len(tempstr)> len(indexsubstring):
                       indexsubstring=tempstr
                elif (len(tempstr)>=maxlen):
                       maxlen=len(tempstr)
                       indexsubstring=tempstr
                       break
            tempstr=''
            print 'max substring length till iteration with starting index =%s is %s'%(test[index],indexsubstring)
            index+=1
    
    if __name__=='__main__':
        main()
    
    0 讨论(0)
  • 2020-12-12 19:05

    Not quite optimized but simple answer in Python

    def lengthOfLongestSubstring(s):
          temp,maxlen,newstart = {},0,0
          for i,x in enumerate(s):
                if x in temp:
                      newstart = max(newstart,s[:i].rfind(x)+1)
                else:
                      temp[x] = 1
                maxlen = max(maxlen, len(s[newstart:i + 1]))
          return maxlen
    

    I think the costly affair is rfind which is why it's not quite optimized.

    0 讨论(0)
提交回复
热议问题