LeetCode 第三题 Longest Substring Without Repeating Characters java/python写法

先贴题目

Given a string, find the length of the longest substring without repeating characters.

Examples:

Given “abcabcbb”, the answer is “abc”, which the length is 3.

Given “bbbbb”, the answer is “b”, with the length of 1.

Given “pwwkew”, the answer is “wke”, with the length of 3. Note that the answer must be a substring, “pwke” is a subsequence and not a substring.


思路:用char遍历String,如果有重复的字符,则根据此重复字符拆分字符串,并且每循环一次就用list的长度与max的长度进行比较。

class Solution {
    public int lengthOfLongestSubstring(String s) {
        List list = new ArrayList(s.length());
        int max = 0;
        char c ;
        for (int i=0;i<s.length();i++){
            c = s.charAt(i);
            if(list.contains(c)){
                //根据相同的字符来分割
                list=list.subList(list.indexOf(c)+1,list.size());
            }
            list.add(c);
            if(list.size()>max){
                max=list.size();
            }
        }
        return max;
    }
}

用此方法可以实现,但是时间过长 Time Limit Exceeded 。考虑在每一次循环后都比较长度确实耗费时间。
因此做以下修改,在每次遇到重复字符时进行比较最大长度和当前Listsize的关系。并且在最后没有重复字符时进行比较。减少长度比较次数。提高执行效率。

class Solution {
    public int lengthOfLongestSubstring(String s) {
        List list = new ArrayList(s.length());
        int max = 0;

        char c ;
        for (int i=0;i<s.length();i++){
            c = s.charAt(i);
            if(list.contains(c)){
                max = Math.max(max,list.size());
                list =list.subList(list.indexOf(c)+1,list.size());
            }
            list.add(c);

        }
        max = Math.max(max,list.size());
        return max;
    }
}

用此方法后依旧时间过长 Time Limit Exceeded 。考虑到list.sublist(int,int)方法可能比较耗费时间。进而与答案做比较。答案使用Map,不需要进行sublist拆分。直接map中的key进行长度比较。缩短时间。
贴答案

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        int n = s.length(), ans = 0;
        Map<Character, Integer> map = new HashMap<>(); // current index of character
        // try to extend the range [i, j]
        for (int j = 0, i = 0; j < n; j++) {
            if (map.containsKey(s.charAt(j))) {
                i = Math.max(map.get(s.charAt(j)), i);
            }
            ans = Math.max(ans, j - i + 1);
            map.put(s.charAt(j), j + 1);
        }
        return ans;
    }
}

Python写法 作为一个python萌新写出来真不容易 百度半天

class Solution:
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        dict ={}
        m=ans=0
        for i,j in enumerate(s):
            if dict.get(j,None)!=None:
                m = max(i+1,m)
            ans = max(ans,i+1-m)
            dict[j]=i+1
        return ans

验证后发现对于字符串’abcabcbb’可以通过,对于’pwwkew’无法通过 调试后查看错误 在m赋值时 因为我认为dict[j]=i+1了 所以我直接写了max(i+1,m)实际上不对的。此处的j还未赋值到dict中,故dict[j]还是前一个重复字符的value值。
因为python中的dict和java中的map相同不允许有重复的key值,所以当你重复赋值时会将前一个重复key的value值取代。修改后如下

class Solution:
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        dict ={}
        m=ans=0
        for i,j in enumerate(s):
            if dict.get(dict.get(j),None)!=None:
                m = max(i+1,m)
            ans = max(ans,i+1-m)
            dict[j]=i+1
        return ans

dict.get(j)也可以写成dict[j]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值