可以先想下这两个问题:

1、怎样使用滑动窗口?

2、如何快速的解决字符查重问题?

滑动窗口

可以想象一下有两个指针,一个叫begin,一个叫now

这两个指针就指定了当前正在比较无重复的字符串,当再往后读取一个字符的时候,就需要比较该字符在begin到now之间是否有重复,如果有重复的话,则记录当前字符串长度,然后把begin往后移动,继续寻找后面的无重复字符子串。

例如,这里的字符串是:“fabcade”。

1、当开始比较字符串的时候,begin指向了第一个字符f,now也指向了第一个字符f,当前只有一个字符,也就不需要比较是否重复。

2、然后读取第二个字符,begin依然指向f,now指向了字符a,这个就需要比较一下a是否与之前的相同,没有相同的就继续读取。

3、当now指向第二个a的时候,begin指向f,此时发现前面已经有了一个a了,(这里可以先记录一下当前字符串长度)所以begin就需要往后移动到a后面的b的位置,则当前的字符串为:bca,之后继续读取d,等等等。

总而言之,滑动窗口记录了当前无重复的字符串,当遇到重复的时候,就把begin指针往后移动到不重复的位置(也就是前面那个重复字符的后面),然后继续遍历字符串到最后。

如何快速字符查重

因为这里都是字符,可以直接把该字符作为数组下标,当读取到一个字符的时候,直接把该字符下标对应的值置为1,表示当前已经存在一个字符(其实就是相当于把字符作为hash的key),例如:

char array[127] = {0};
char data = 'a';
if (0 == array[data]) // 说明之前没有读到过该字符
{
array[data] = 1; // 置位,表示已经读到过该字符
}
else
{
// 说明此字符重复
}

我们可以先想一下思路:

先初始化begin和now,然后循环读取字符串,每读取一个字符串,就在数组里查找一下,如果数组里不为0,就说明有重复的字符,需要把当前的字符串长度记录下来,然后begin往后移动到不重复的字符上,然后把该数组全部位置为0,再把begin后面的字符对应的数组置位1,最后再继续比较。

这么写当然也是可以,但不停的把数组置1再清0再置1,会很浪费时间,可以有其他方法吗?

当然是有的,我们可以这么写:

置位的时候,不填1,而填写当前字符所在的位置。

这样有什么好处呢?因为前面的begin,已经记录了当前字符串比较的起始位置,当读取到一个字符串:

如果他出现的位置在begin之前,就说明,虽然以前已经有了该字符,但那个是之前的事情了,不在现在的这个字符串范围之内,所以它还是不算重复的;

如果他上次出现的位置在begin之后,就说明在当前比较的字符串中已经有一个和他相同的字符了。

这样的话,通过位置信息就能够知道该字符在当前比较位置是否重复,就不需要反复的对数字进行清零和置位了。

在leetcode上,提高了9倍!(使用置位和清零花费44ms,使用位置标记花费4ms)


int lengthOfLongestSubstring(char * s){ int local[127] = {0}, data; // local数组就是用来记录每个字符出现的位置
int lenNow = 0, lenMax = 0;
int len = strlen(s);
int begin = 1;
for (int i=0; i<len; i++)
{
data = s[i];
if ((0 == local[data]) || (begin > local[data]))
{
lenNow ++;
}
else
{
if (lenNow > lenMax) lenMax = lenNow;
lenNow = i + 1 - local[data];
begin = local[data] + 1; // 更新begin的位置
}
local[data] = i + 1;
// 这里记录的位置是下标加1,也就是从1开始记录,为什么不从0开始记录呢?
// 如果从0开始,那么0就有两种意思:该字符从没出现过,该字符出现的位置是0。当0正好又是begin的时候,比如字符串:"abca"
}
if (lenNow > lenMax) lenMax = lenNow;
return lenMax;
}

leetcode的Hot100系列--3. 无重复字符的最长子串--滑动窗口的更多相关文章

  1. [LeetCode]3. 无重复字符的最长子串(滑动窗口)

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

  2. LeetCode 第 3 题:无重复字符的最长子串(滑动窗口)

    LeetCode 第 3 题:无重复字符的最长子串 (滑动窗口) 方法:滑动窗口 滑动窗口模板问题:右指针先走,满足了一定条件以后,左指针向前走,直到不满足条件. 特点:左右指针的方向是一致的,并且是 ...

  3. leetcode刷题笔记-3. 无重复字符的最长子串(java实现)

    题目描述 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb"输出: 3 解释: 因为无重复字符的最长子串是 "ab ...

  4. LeetCode随缘刷题之无重复字符的最长子串

    欢迎评论区交流. package leetcode.day_12_04; /** * 给定一个字符串 s ,请你找出其中不含有重复字符的最长子串的长度. * <p> * 示例1: * &l ...

  5. LeetCode(3):无重复字符的最长子串

    Medium! 题目描述: 给定一个字符串,找出不含有重复字符的 最长子串 的长度. 示例: 给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ...

  6. 【leetcode】 算法题3 无重复字符的最长子串

      问题      给定一个字符串,找出不含有重复字符的最长子串的长度. 示例: 给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度 ...

  7. Leetcode(三)无重复字符的最长子串

    3. 无重复字符的最长子串 题目描述 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最 ...

  8. 【LeetCode题解】3_无重复字符的最长子串(Longest-Substring-Without-Repeating-Characters)

    目录 描述 解法一:暴力枚举法(Time Limit Exceeded) 思路 Java 实现 Python 实现 复杂度分析 解法二:滑动窗口(双指针) 思路 Java 实现 Python 实现 复 ...

  9. Newtonsoft.Json C# Json序列化和反序列化工具的使用、类型方法大全 C# 算法题系列(二) 各位相加、整数反转、回文数、罗马数字转整数 C# 算法题系列(一) 两数之和、无重复字符的最长子串 DateTime Tips c#发送邮件,可发送多个附件 MVC图片上传详解

    Newtonsoft.Json C# Json序列化和反序列化工具的使用.类型方法大全   Newtonsoft.Json Newtonsoft.Json 是.Net平台操作Json的工具,他的介绍就 ...

随机推荐

  1. PHP获得指定日期所在月的第一天和最后一天

    function getdays($day){ $firstday = date('Y-m-01',strtotime($day)); $lastday = date('Y-m-d',strtotim ...

  2. 图像滤镜艺术---流行艺术风滤镜特效PS实现

    原文:图像滤镜艺术---流行艺术风滤镜特效PS实现 今天,本人给大家介绍一款新滤镜:流行艺术风效果,先看下效果吧! 原图 流行艺术风效果图 上面的这款滤镜效果是不是很赞,呵呵,按照本人以往的逻辑,我会 ...

  3. 《芒果TV》UWP版利用Windows10通用平台特性,率先支持Xbox One平台

    在Windows开发者中心开放提交Xbox平台应用之后,<芒果TV>UWP版迅速更新v3.1.2版,通过升级兼容目标,利用Windows10通用平台特性,率先覆盖Xbox平台用户. 芒果T ...

  4. Android零基础入门第16节:Android用户界面开发概述

    原文:Android零基础入门第16节:Android用户界面开发概述 相信通过前面15期的学习,Android的开发环境已经基本掌握了,如果仍有问题,欢迎到Android零基础入门技术讨论微信群交流 ...

  5. oracle 12c连接pdb

    12c中,如何连接pluggable database: 使用默认的service连接pdb,创建pdb之后,在监听中自动添加以pdb为名的service: 用户在cluster中创建service, ...

  6. Android零基础入门第66节:RecyclerView点击事件处理

    前面两期学习了RecyclerView的简单使用,并为其item添加了分割线.在实际运用中,无论是List还是Grid效果,基本都会伴随着一些点击操作,那么本期就来一起学习RecyclerView的点 ...

  7. UBUNTU 16.04 + CUDA8.0 + CUDNN6.0 + OPENCV3.2 + MKL +CAFFE + tensorflow

    首先说一下自己机子的配置 CPU:Intel(R) Core(TM) i5-5600 CUP @3.20GHz *4 GPU : GTX 1060 OS : 64bit Ubuntu16.04LTS ...

  8. C# winform 主界面打开并关闭登录界面

    在winform 界面编程中,我们有时候要在主界面打开之前先显示登录界面,当登录界面用户信息校验正确后才打开主界面,而这时登陆界面也完成使命该功成身退了. 目前有两种方法可实现: 方法1. 隐藏登录界 ...

  9. Ceph OpenSSL

    Ceph OpenSSL 1. SSL介绍 SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信 ...

  10. Delphi下IOC 模式的实现(反转模式,即Callback模式)

    IOC英文为 Inversion of Control,即反转模式,这里有著名的好莱坞理论:你呆着别动,到时我会找你.Ioc模式是解决调用者和被调用者之间关系的模式,可以有效降低软件的耦合度,并适合团 ...