leetcode 第三题:标准容器set与map的使用

题目大意:给出一个字符串,找到该字符串中不含重复字符的最长子串,返回其长度。

示例:给出子串:abcabcbb,其最长子串是“abc”,则返回其长度值3。

解题思路:看到题目,首先想到的最“笨”的方法就是从第一个字符开始,逐个向后遍历,遇见相同字符则停止,循环该过程,记录并更新子串的最大长。但这么做算法复杂度很高,不推荐使用。

        随后我开始寻找其他解决方法。最初是希望能建立一个表格,记录不同的字符以及它们在字符串中的位置,但这样做并不能有效减少复杂度。随后参考了Solution中给出的解法,用c++对其实现,获得AC。如下:

leetcode 第三题:标准容器set与map的使用_第1张图片

        这种解法称为“滑动窗”法,在数组与字符串的处理中经常用到。具体的思路是:滑动窗是当前处理的子串,初始为空。用两个变量记录窗口左右边界在整个字符串中的下标作为窗口的特征值。随后将窗口右边界逐渐向右移动,窗口拉长,直到窗口中出现重复元素。此时再将窗口左边界向右移,直到窗口中没有重复元素。在这个过程中,记录并更新窗口的长度,并保留最大长度作为返回值。

        这种方法的好处就在于不需要对已经遍历过的元素进行重复遍历。基于此,选择了元素不可重复的数据结构set对其处理。在书写代码时我有一点担心:set中的元素都是按序排好的,如果将窗口左边界右移(即删除重复元素)时,会不会误删别的元素?事实证明我多虑了:

                                                       leetcode 第三题:标准容器set与map的使用_第2张图片

        输入“acbdbefgh”。在程序遍历到第二个‘b’时,打印出删除掉一个元素后的窗口,即“bcd”;再打印出删除掉两个元素后的窗口,为“bd”。不难发现,虽然窗口元素是按序排列的,但删除是按照它们在原来字符串中的顺序进行的,先删‘a’,再删‘c’而非‘b’,因此并不会对最终结果造成影响。

        在Solution中还提供了第二种方法,即使用map存储数据。这样做的好处在于窗口左边界右移时,不再是一个元素一个元素的移动,而是直接移动到重复元素的下一个位置,从而进一步降低了算法复杂度。如下所示: 

                                                       leetcode 第三题:标准容器set与map的使用_第3张图片    

        滑动窗法作为一种常见的数据处理手段,值得我在日后的学习过程中多多注意。       

你可能感兴趣的:(leetcode解题记录)