【每日一题】Day0005:力扣题库NO.3. 无重复字符的最长子串

今天的签到题确实有点难了,想了很久没有实现,遂放弃,随便找了个中等难度的题目做。(毕竟还处于学习阶段,不能浪费太长时间~加上正好最近学到String类和相关类,就找了个字符串的题目做)老规矩链接如下:

https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/icon-default.png?t=LA92https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/这次的题目描述十分简单,基本不会存在任何歧义。

思路1:

直接想到就是递归。依次判断当前串是否无重复字符,如果是,返回当前串长度,否则将当前串开头去掉1个字符后继续判断,同时将结尾去掉1个字符后的子串继续判断,两者较大者为串的最长长度。

代码如下:

    public static int lengthOfLongestSubstring(String s) {
        if(s.length() <= 1){ //当长度小于等于1,递归结束
            return s.length();
        }
        for(int i=0; i<s.length(); i++){
            // 如果当前串存在重复字符则不是无重复子串
            if(s.indexOf(s.charAt(i)) != s.lastIndexOf(s.charAt(i))){ 
                // 判断开头去掉一个字符的子串是否符合
                int leftLength = lengthOfLongestSubstring(s.substring(1)); 
                // 判断最右面去掉一个字符的子串是否符合
                int rightLength = lengthOfLongestSubstring(s.substring(0,s.length()-1));
                // 将两者长度较长者长度返回
                return Math.max(leftLength,rightLength); 
            }
        }
        // 出循环代表是无重复子串,返回长度
        return s.length();
    }

问题很大,效率极低,递归次数太多果不其然最后一个测试用例超时,开始其他方法。

思路2:

依旧是递归,但是在原有思路上减少递归次数,观察部分复杂用例,我们从字符串开头开始向右遍历,当出现带重复的子串时,记录目前不重复子串的长度,并从重复字符第一次出现的位置开始递归,与之前记录的长度比较,将将两者中较大者返回即可。递归次数大大减小,不过效率依旧较低,好歹满足需求了~代码如下:

package cn.daycode.leetcode;

public class LengthOfLongestSubstring {
    public static void main(String[] args) {
        String s = "dgaijvwcyaubwewpjvygehljxe";
        System.out.println(lengthOfLongestSubstring(s));

    }

    public static int lengthOfLongestSubstring(String s) {
        if(s.length() <= 1){
            return s.length();
        }
        int firstIndex = 0;

        for (int i = 0; i < s.length(); i++) {
            // 当某个字符的下标不是第一次出现则为重复
            if(s.indexOf(s.charAt(i)) != i){
                // 记录一下当前字符第一次出现的位置,+1后作为递归函数参数子串的起始位置
                firstIndex = s.indexOf(s.charAt(i));
                // 将当前串长度与firstIndex下标开始的子串里最长无重复子串比较,返回较大者
                return Math.max(i, lengthOfLongestSubstring(s.substring(firstIndex+1)));
            }
        }

        return s.length();
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值