LeetCode刷题记 3

本文详细介绍了如何通过优化算法复杂度、改进代码结构和利用高效数据结构来提升LeetCode解题速度。从手写复杂度为O(n^3)的原始算法,到引入双指针技巧实现O(n)复杂度的优化,作者分享了从初学者到进阶者的编程思考过程,并探讨了如何有效利用数组进行字符访问状态的快速判断。此外,文章还反思了个人在编程基础、思维方式和逻辑清晰度方面的不足,并提出了改进计划。
LeetCode 3 Longest Substring Without Repeating Characters

做的有点慢,都称不上刷题了,所以加快点速度,一天至少五道啊

原题

Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for “abcabcbb” is “abc”, which the length is 3. For “bbbbb” the longest substring is “b”, with the length of 1.

中文翻译
在字符串中找最长无重复字母的子串,举例:abcabcbb的是abc,长度是3;bbbb的是b长度是1。

分析


还是用手想了一个解法,复杂度为O(n3)

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        int length=1;
        int flag = 0;
        for(int i=0;i<s.length();i++){
            char c1 = s.charAt(i);
            for(int j=i+1;j<s.length();j++){
                char c2 = s.charAt(j);
                for(int q=i;q<j;q++){
                    char c3 = s.charAt(q);
                    if(c2==c3){
                        length = j-i>length?j-i:length;
                        flag=1;
                        break;
                    }
                    else{
                        flag=0;
                    }
                }
                if(flag==1)
                    break;
            }
        }
        return length;
    }
}

就OJ这尿性肯定超时..
所以分析下怎么降低时间开销
上面的解法有很多的无用判断
如abcdecd
i=0 c1=a j=5 c2=c p=2 c3=c时结束判断
已经能判断出abcdec不是一个解
那么接下来的i=1,i=2都是没有必要的了
可以直接跳过,从i=3开始
所以我们得到一个简化方案
扩张字符串长度,当遇到重复字符时,记录长度
重复字符对中第一个字符的下一个开始继续扩张
简单的说就是这个字符a被重复的他:a2代替了
而且没必要再去管开始字符到a之间的字符了
因为他们起始的解长度必然没有父串长

点开show tags 看到标签是hash,two pointers,string
two pointers进行标记的作用,一个负责移动起始,一个负责判断重复


public class Solution {
    public int lengthOfLongestSubstring(String s) {
        int i,j;
        i=0;j=0;
        int n=s.length();
        boolean exist[]=new boolean[256];
        for(boolean e:exist){
            e=false;
        }
        int length = 0;
        while(j<n){ 
            if(exist[s.charAt(j)]){
                length = Math.max(length,j-i);
                while(s.charAt(i)!=s.charAt(j)){
                    exist[s.charAt(i)]=false;
                    i++;
                }
                i++;
                j++;
            }
            else{
                exist[s.charAt(j)] = true;
                j++;
            }
        }
        length = Math.max(length,n-i);
        return length;
    }
}

时间复杂度为O(n)
这是我照题解改改过的代码,比自己写的优美多了
首先,我没想到能用一个数组存下字符是否被访问过这个信息
这也算是变相的hash方式了吧。


总结一下这几天的OJ经历,边写微博边做题感觉可以…
但在编程上遇到一些问题
1. 基础不好,指针什么的不敢用所以就java…代码不严谨很难做到想的写出来一次就过。
2. 思维简单,想不到好的解法,考虑不到时间复杂度的问题。究其原因就是题做的少,以后会遇到应用成熟算法解决的题,到时再看看。估计动态规划什么的都忘差不多了…
3. 逻辑混乱,一直有这个弱点,循环啊什么的,掰楞手指头都查不明白

接下来要注意这些问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值