• 3.无重复字符的最长字串


    给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
    示例 1:
    输入: "abcabcbb"
    输出: 3
    解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

    示例 2:
    输入: "bbbbb"
    输出: 1
    解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

    示例 3:
    输入: "pwwkew"
    输出: 3
    解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
         请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
    1.自己的解法
    class Solution {
       public int lengthOfLongestSubstring(String s) {
                HashMap map=new HashMap();
                int max=0,start=0,len=0;
                for(int i=0;i<s.length();i++) {
                    if(map.containsKey(s.charAt(i))) {
                        start=Math.max((int) map.get(s.charAt(i))+1, start);
                    }
                    map.put(s.charAt(i), i);
                    len=i-start+1;
                    if(len>max) {
                        max=len;
                    }
                }
                return max; 
            }
    }

    记录每一个字符下次出现的位置,根据位置的更新最长长度会改变,start开始端的更新1.不能比当前的小2.再原始位置后移一个;一开始想要设置一个end位记录最长字符串的末尾,但是发现应该就是i对应的,所以没有设置,而之前的长度记录在max中

    2.官方题解:
    1.暴力解法:

    对每个子字符判断是否含有不同的字符:

    public class Solution {
        public 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(ans, j - i);
            return ans;
        }
    
        public 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);
                if (set.contains(ch)) return false;
                set.add(ch);
            }
            return true;
        }
    }

    2.滑动窗口:

    对[i,j)的字符都不在set中,判断[i,j+1)在不在即右移窗口,当j在set中时,把i对应的字符从set中去除,i++对每个i重复操作:

    class Solution {
        public int lengthOfLongestSubstring(String s) {
            int n = s.length();
            Set<Character> set = new HashSet<>();
            int ans = 0, i = 0, j = 0;
            while (i < n && j < n) {
                // try to extend the range [i, j]
                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;
        }
    }

    3.优化的滑动窗口(同我的做法):

    与(2)相同,只不过将i更新为j+1

    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);
                }
                ans = Math.max(ans, j - i + 1);
                map.put(s.charAt(j), j + 1);
            }
            return ans;
        }
    }

    4.ascii码解法:

    用ascii码代替hashmap:

     public int lengthOfLongestSubstring(String s) {
            int n = s.length(), ans = 0;
            int[] index = new int[128]; // current index of character
            // try to extend the range [i, j]
            for (int j = 0, i = 0; j < n; j++) {
                i = Math.max(index[s.charAt(j)], i);
                ans = Math.max(ans, j - i + 1);
                index[s.charAt(j)] = j + 1;
            }
            return ans;
        }

    ------------------------------------------------------------------------------------------------

     
  • 相关阅读:
    分享上大学时CCTV5经常播放的一段宣传片
    嗯, 在Vista下面post一篇, 快过年的二三事
    [转自天涯]很多年以前,我是一个中锋
    关于Anthem的Button控件, 为啥仍然会PostBack?
    小白三下杭州
    搜狗, 谷歌, 紫光, 3大输入法互打结果.
    2008春节回家流水账
    早上拍的雪景.
    如果安装.net framework 3.5出错, 可以这样解决
    我那幸福的坐车偶记...
  • 原文地址:https://www.cnblogs.com/code-fun/p/12489741.html
Copyright © 2020-2023  润新知