LeetCode3. Longest Substring Without Repeating Characters

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kevinjqy/article/details/78657478

题目

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

Examples:

Given “abcabcbb”, the answer is “abc”, which the length is 3.

Given “bbbbb”, the answer is “b”, with the length of 1.

Given “pwwkew”, 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.

找出一个字符串的不含有重复字符的最长子串,注意,子串需要连续而子序列不需要。

解题思路

这题的思路很明显是动态规划,O(n^2)的方法很容易想到,即用一个bool类型的二维数组表示一个子串是否是非重复子串,然后一路递推就可以,但这明显不是我们想要的。
可不可以一次便利得出结果?可以

public int lengthOfLongestSubstring(String s) {
        //指向正在遍历的字母的指针
        int start = 0;
        int end = -1;
        //指向最长的子串的开头结尾的指针
        int resStart = 0;
        int resEnd = -1;
        //指向上一个子串的指针
        int tmpStart = 0;
        int tmpEnd = -1;
        //用来存储不重复的字符,值表示字符所在位置
        HashMap<Character, Integer> set = new HashMap<>();
        for (int i = 0; i < s.length(); i++) {
            //如果发现字符重复,进行一系列操作
            if (set.containsKey(s.charAt(i))) {
                //先保留这个子串,方便map删除
                tmpStart = start;
                tmpEnd = end;
                //如果正在遍历的子串长度大于之前的最大值,就替换
                if (end - start + 1 >= resEnd - resStart + 1) {
                    resStart = start;
                    resEnd = end;
                }
                //重新设置开始值为重复的字符的下一位
                start = set.get(s.charAt(i)) + 1;
                end = i;

                //如果与前一位相同,直接清空map
                if (s.charAt(i) == s.charAt(i - 1))
                    set.clear();
                else {
                    //否则仅清空相同位之前的字符
                    int index = set.get(s.charAt(i));
                    for (int k = tmpStart; k <= index; k++) {
                        set.remove(s.charAt(k));
                    }
                }
            } else {
                //不重复,直接向后遍历
                end++;
            }
            //把不重复的字符加入map
            set.put(s.charAt(i), i);
        }
        //因为存在最后一位字符所在的子串刚好是最长的可能,而这时又不会触发上方的语句,所以需要在结尾加个判断
        return resEnd - resStart + 1 > end - start + 1 ? resEnd - resStart + 1 : end - start + 1;
    }
阅读更多

Longest Palindromic Substring 最长回文子串问题?JAVA

06-20

rnrn```rnpublic class Solution rn public String longestPalindrome(String s) rn String ret = "";rn for (int i = 0; i < s.length(); i++) rn for (int j = 0; i - j >= 0 && i + j < s.length(); j++) rn if (s.charAt(i - j) == s.charAt(i + j)) rn if (j * 2 + 1 > ret.length()) rn ret = s.substring(i - j, i + j + 1);rn rn else rn break;rn rn rn for (int j = 0; i - j >= 0 && i + 1 + j < s.length(); j++) rn if (s.charAt(i - j) == s.charAt(i + j + 1)) rn if ((j + 1) * 2 + 1 > ret.length()) rn ret = s.substring(i - j, i + j + 2);rn rn else rn break;rn rn rn rn return ret;rn rnrn public static void main(String[] args) rn String s = "cdabbaef";rn Solution a = new Solution();rn System.out.println(a.longestPalindrome(s));rn rn rn```rnrnrnrn思路就是 因为回文字符串是以中心轴对称的,所以如果我们从下标 i 出发,用2个指针向 i 的两边扩展判断是否相等,那么只需要对0到rnn-1的下标都做此操作,就可以求出最长的回文子串。但需要注意的是,回文字符串有奇偶对称之分,即"abcba"与"abba"2种类型,rn因此需要在代码编写时都做判断。 rn编译也通过了。rn但是后来想到一个问题 例如:cdabbaef 里abba的子串 改成abea 源字符串变成cdabeaef 时 按照偶数情况的代码 结果也会输出abea 因为abea里的e没有比较 但是运行是发现 这个问题 已经被解决了 但是我想不通哪里避免了这种情况 请帮我分析一下

没有更多推荐了,返回首页