LeetCode第三题 “无重复字符的最长子串” 从低效率到高效率.md

400 阅读1分钟

这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战

3. 无重复字符的最长子串

题目来源:力扣(LeetCode)
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:

输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3

示例 2:

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1

示例 3:

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

补全代码:

class Solution {
    public int lengthOfLongestSubstring(String s) {

    }
}

看到题目,还是老样子,不管会不会,我们先添加上所必须的初始化和返回值。

int num = 0;
//TODO
return num;

看到这个问题第一个想法,就是把所有不重复的字符串数字段取出,比较每个大大小取最大的。
例如:

"abcabcbb"

"adc"
"bca"
"cab"
"abc"
"bc"
"cb"
"b"
"b"

所以结果是3。
好了那就上代码吧。

public static int lengthOfLongestSubstring(String s) {
    int num = 0;
    //用于存放字符串
    HashSet<Character> hashSet;
    //从最开始循环到最后
    for (int i = 0; i < s.length(); i++) {
        hashSet = new HashSet<>();
        //每次从i个开始循环
        for (int j = i; j < s.length(); j++) {
            //如果存在则退出
            if (hashSet.contains(s.charAt(j))) {
                break;
            }
            //不存在添加
            hashSet.add(s.charAt(j));
            //判断集合的大小
            if (num < hashSet.size()) {
                num = hashSet.size();
            }
        }
    }
    return num;
}

果然不出所望,这效率。哈哈哈,虽然不怎么样,但是功能实现了。接下里开始我们的一点点优化。

优化

我们可以列出每一个,我们只要列出不重复的所有字段,如

"abcabcbb"

"adc"
//遇到a踢出a以及a之前的
"bca"
//遇到b踢出b以及b之前的
"cab"
遇到c踢出c以及c之前的
"abc"
遇到b踢出b以及b之前的
"cb"
遇到a踢出b以及b之前的
"b"

看上面结果少了两次。下面用代码实现。

public static int lengthOfLongestSubstring(String s) {
    int num = 0;
    //记录从第几个元素开始移除
    int count = 0;
    HashSet<Character> hashSet = new HashSet<>();
    for (int i = 0; i < s.length(); i++) {
        //如果集合以包含
        while (hashSet.contains(s.charAt(i))) {
            hashSet.remove(s.charAt(count));
            count++;
        }
        //添加新的元素
        hashSet.add(s.charAt(i));
        //判断集合的大小
        if (num < hashSet.size()) {
            num = hashSet.size();
        }
    }
    return num;
}

嗯嗯,可以的效果刚刚的。哈哈。虽然只击败了50%多用户,但是我感觉,他们应该是用c++写。(给自己一个小小的开脱)