Leetcode #3 Longest Substring Without Repeating Characters 解题小结

1 题目理解

题目原题:Longest Substring Without Repeating Characters

这道题的意思,其实也就是给定一个字符串的输入,找出一个最长的子串,而特殊要求呢,就是这个子串不能有重复的字符存在。

而这道题的解题思维主要是如何界定这个子串?我总结了有如下的判断方式:

最长子串一定是:
* 1、要么从一开始就完全没有重复字符
* 2、从某个位置开始,就完全没有重复字符,直到出现了重复或结束

什么意思呢,其实就是在符合[开头or上一次出现该字符]~[当次出现字符串or结尾]的条件内的子串中选择一个最大的输出。

而我们要做的也就是设立两个指针,start和end,一个指向当前子串的起始位置,另一个是end,表示当前的技术为止,当end扫描到某一个位置上,判断这个位置的字符之前是否出现过,如果没有那么end可以继续往后,反之,则必须要start移动到end所在位置字符上一次出现的位置之后。

如何判断上一次出现,可以用哈希的方式,不过对于字符,貌似开销太大,反正char只有0~255的取值,直接开数组保存记录就好。

记得当start移动的时候,需要消除新老start位置之间出现的字符的标记。

2 原题

Given a string, find the length of the longest substring without repeating characters.
For example, the longest substring without repeating letters for “abcabcbb” is “abc”, which the length is 3. For “bbbbb” the longest substring is “b”, with the length of 1.

Subscribe to see which companies asked this question

3 AC解(Java)

public class Solution {
    /**
     * 基本思想,追踪上一个出现的值
     * 最长的子串有如下情况:
     *  1、要么从一开始就完全没有重复字符
     *  2、从某个位置开始,就完全没有重复字符,直到出现了重复或结束
     * 
     *  因此,我们需要在截取所有1、2状况的,选择最长的长度
     *  因此我们使用exist判断字符(char 只有0~255个)是否出现,如果出现则使用last追踪上一次出现的位置
     *  没有出现,继续前进
     *  如果出现,计算当前的长度,移动子串开始位置到上一次出现该位置的后一个上,并更新exits和last
     * */
    public int lengthOfLongestSubstring(String s) {
        /**
         * 使用last追踪对应字符上一次出现的位置
         * 使用exist表示当前子串匹配过程中,是否出现了该字符
         * */
        int last[] = new int[256];
        boolean exist[] =  new boolean[256];
        int longest=0,i,j;
        int start,end,position;
        int tmp;
        for (i=0;i<256;i++){ //初始化
            last[i]=-1;
            exist[i]=false;
        }
        start=end=-1;
        /**
         * 在start(不包含,子串实际从start+1开始)-end(包含)的区间内,对于最新匹配的哪一个字符,是否在start-end中出现
         * 如果出现了,则start则需要切换到上一次出现的后一个位置之后,并更新last和exist
         * */
        while(++end<s.length()){ 
            tmp = s.charAt(end);
            if(exist[tmp]){
                for(i=start+1;i<=last[tmp];i++){
                    exist[s.charAt(i)]=false;
                }
                start=last[tmp];
            }
            longest=Math.max(end-start,longest);
            exist[tmp]=true;
            last[tmp]=end;
        }
        return longest;
    }

4 题外话

写的比较早了,似乎描述的也不是特别清楚,但是这题本身不难。。当时我题目里也有留注释,直接看代码起来也会很容易。

有问题请戳我私信

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值