Leetcode | Longest Substring Without Repeating Characters

题目链接:(https://leetcode.com/problems/longest-substring-without-repeating-characters/)

这道题简单的题意就是要我们找出一串字符串中最长的没包含重复字符的子字符串的长度,输入一段字符串,输出子字符串的长度。

这道题刚一看上去以为挺简单的,但仔细一想还有许多细节问题要处理,像大多数人一样,做这种题我一开始还是用最笨的办法,最容易想到的就是,通过一个for循环逐渐遍历整个字符串,在遍历的过程中,与之前的所有字符逐一比较,如果相同,则所选取的子字符串的起点要重新更换,长度也要重新计数。


具体在编程的时候要处理好两层循环之间的关系,第一层是用来遍历整个字符串的,第二层是用来比较是否存在重复字符的,在下面给出的代码中我会用到几个比较关键的变量,point是指当前子字符串的起始位置,i是当前第一层循环所遍历到的字符位置,j是用来比较当前子字符串中i之前的字符位置,len是用来计数字符串的长度,max_len是用来计数最终输出子字符串的长度,在每一次遍历字符串时都会对其值进行更新。


class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if (s.length() == 0) return 0;//空字符串返回0
        int len = 1;//不为空时默认为1
        int max_len = 1;
        int point = 0;//从0开始遍历
        int flag = 0;//用来区分是否找到相同字符
        for (int i = point+1; i < s.length(); ) {
            flag = 0;
            for (int j = point; j < i; j++) {
                if (s[j] == s[i]) {
                    if (max_len <= len) max_len = len;
                    point = j + 1; //若找到相同字符,则起点位置加1            
                    len = 1;
                    flag = 1;
                    break;
                }
            }
            if (flag == 1) {
                i = point+1; //若找到相同字符,则起点位置加1              
            } else {
                i++; //若没找到,继续遍历
                len++; //长度正常增加
                if (max_len <= len) max_len = len;
            }
        }
        return max_len;
    }
};

编写完上述代码后,虽然成功accept了,但还是觉得代码有些繁琐且比较难理解,所以就从网站上找了一些大神的答案进行学习并理解,以下是大神的9行代码

int lengthOfLongestSubstring(string s) {
        vector<int> dict(256, -1);
        int maxLen = 0, start = -1;
        for (int i = 0; i != s.length(); i++) {
            if (dict[s[i]] > start)
                start = dict[s[i]];
            dict[s[i]] = i;
            maxLen = max(maxLen, i - start);
        }
        return maxLen;
    }

上述代码整体上用的是类似桶排序的思想,用vector向量来存储各个字母出现的最新位置,并在遍历的过程中进行更新,从而将寻找重复字符的过程简化为O(n)级别的一重循环,这个方法既高效又简单,是这道题最为简单且易于理解的解法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值