zoukankan      html  css  js  c++  java
  • 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.

    解答:

    方法一:遍历所有可能的截取字符串,判断是否为不包含重复元素的字符串

    java代码实现

    import java.util.HashSet;
    import java.util.Set;
    
    public class LongestSubstring {
    
        private static int lengthOfLongestSubstring(String s){
            int n = s.length();
            int ans = 0;
            for(int i = 0; i < n; i++){
                for(int j = i+1; j <= n; j++){
                    if(allUnique(s, i, j)){
                        ans = Math.max(j - i, ans);
                    }
                }
            }
            return ans;
        }
    
        private static boolean allUnique(String s, int start, int end){
            Set<Character> set = new HashSet<>();
            for(int i = start; i < end; i++){
                Character ch = s.charAt(i);
                // set.contains(Object o)底层依赖equals()方法和hashcode()方法,如果是对象可以重写这两个方法
                // 参见https://blog.csdn.net/gao2628688/article/details/80947588
                // Character源码:public static int hashCode(char value) {return (int)value;}
                if(set.contains(ch)) return false;
                set.add(ch);
            }
            return true;
        }
    
        public static void main(String[] args){
            int i = lengthOfLongestSubstring("mnsopakjn");
            System.out.println(i);
        }
    }

    c++实现:

    方法二:滑动窗口:最长的字符串肯定出现在两个相同的元素中间,或者在最前面,或者在最后面,滑动窗口的范围[i, j),当发现当前的集合包含重复元素时,可以将左边界向右移动,直到左边界到达该重复元素的前一个元素为止,并删除集合中左边界的元素,将右边界中该元素添加进集合,再继续统计最长的长度。

    java实现:

    public class Solution {
        public int lengthOfLongestSubstring(String s) {
            int n = s.length();
            int i = 0, j = 0, ans = 0;
            Set<Character> set = new HashSet<>();
            while(i < n && j < n){
                if(!set.contains(s.charAt(j))){
                    set.add(s.charAt(j++));
                    ans = Math.max(ans, j - i);
                }else{
                    set.remove(s.charAt(i++));
                }
            }
            return ans;
        }
    }

     方法三:优化的滑动窗口:遇到重复的元素时,之间将左边界移动到该重复元素出现的上次位置

    java实现:

    public class Solution {
        public int lengthOfLongestSubstring(String s) {
            int n = s.length(), ans = 0;
            Map<Character, Integer> map = new HashMap<>(); // current index of character
            // try to extend the range [i, j]
            for (int j = 0, i = 0; j < n; j++) {
                if (map.containsKey(s.charAt(j))) {
                    i = Math.max(map.get(s.charAt(j)), i);    // 防止出现 baab这种情况,检测到最后一个b,又将左边界移动到最左边的b,左边界只能向前移动
                }
                ans = Math.max(ans, j - i + 1);
                map.put(s.charAt(j), j + 1);     // 没有插入,已经存在更新键对应的元素值
            }
            return ans;
        }
    }
  • 相关阅读:
    读《梦断代码》有感
    The Third Group Meeting!
    第一次课程作业项目报告
    第四次读后感
    个人作业进度(五)
    个人作业进度(四)
    个人作业进度(三)
    个人进度(二)
    个人作业进度(一)
    java中类的封装与继承
  • 原文地址:https://www.cnblogs.com/feng-ying/p/10491933.html
Copyright © 2011-2022 走看看