【leetcode 】003.无重复字符的最长子串 C语言版

        003题为无重复字符的最长字串,这一题不是很难,但我还是做了不少时间,因此还是写下来作为记录,同时为各位需要的朋友留下一点或许有用的信息吧。

        接下来,就先读一下题目。

题目:

                题目的描述已经很清楚了 ,我们在此就不再过多的再去解释了,直接进入正题吧。

                在这一题中,我们要使用滑动窗口。

       解题思路:滑动窗口

        滑动窗口大概意思是两个指向两端的指针,使中间的字符串形成一个类似“窗口”的容器,窗口的大小可以随着指针的移动而发生变化。在现实生活中也有着实际类似的运用,如在计算机网络中,tcp协议在流量通信中会使用滑动窗口来实现流量控制。

        首先确定窗口的最大值,即字符串的总长度,用len表示,用来作为结束标志,当右端的指针到达字符串尾部的时候,可认为判断结束。

        在这一题中,我们可以利用滑动窗口的两端来计算当前无重复字串的长度。将左边指针设置为left,初始值为 0,右边指针设置为right,初始值为1。再将max值初始化为0.

    int left = 0;
    int right = 1;
    int i = 0;
    int len = 0;
    int max = 0;

    while(s[i] != NULL) {
        i++;
    }
    len = i;

        随后进入第一层循环——窗口右端是否到达串尾,若达到则结束循环。现在窗口已经建立,需要检查是否有重复字符,此处在套一个循环,设置检查标志flag,从left处开始检查,向右移动到right处停止。

        若出现重复字符串则向left向右移动一位,若没有则right向右移动一位。

        除此之外,在进行移位前需要进行计算当前长度,若flag = 0,窗口内的无重复字符串长为right + 1 - left,若flag = -1,则串长为right - left。

源代码如下:

int lengthOfLongestSubstring(char * s){
    int left = 0;
    int right = 0;
    int i = 0;
    int len = 0;
    int max = 0;
    int middle = 1;

    while(s[i] != NULL) {
        i++;
    }
    len = i;


    while(right < len) {
        int flag = 0;
        for(int j = left; j < right; j++) {
            if(s[right] != s[j]) {
                continue;
            }
            else {
                flag = -1;
                break;
            }
        }
        if(flag == 0) {
            int son_string_len = right + 1 - left;
            if(son_string_len > max) {
                max = son_string_len;
            }
            right++;
        }
        if(flag == -1) {
            int son_string_len = right - left;
            if(son_string_len > max) {
                max = son_string_len;
            }
            left++;
        }
    }
    return max;
}

        很明显,上面两种情况的区别无非是当前right所指的字符是否属于重复字符,即串长是否加一。

               综上所述,我们只需要依次判断最右端的字符是否与前面的字符串有重复,并通过将情况分为有和没有来进行判断作不同处理。

不足与反思

                我们在查询对比时,用的是在循环中进行,这样的查询效率较低,从而导致程序的执行速度变慢,对此我们可以通过数组来保存窗口内的字符。

                利用对应字符的ASCII值,0表示无重复,1表示重复,当不发生重复时,将新加入的字符记录对应的数组位置,这样在查询的时候,我们就只需要O(1)的时间复杂度,就可以判断字符串是否重负。发生重复就可以将最左端的字符去除,并将left右移,直到字符串中无重复字符。

                各位如果做过001.两数之和的话,其中的快速计算的方法和这个相当相似,理论上是可以提高计算的效率,但是本人并未尝试,有兴趣的话,可以进行尝试。

                注:水平不足,还望包含,希望说错的地方还请各位在评论区指点一二,谢谢了!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值