【LeetCode】Longest Substring Without Repeating Characters && 【九度】题目1530:最长不重复子串

121 篇文章 2 订阅
108 篇文章 0 订阅

1、Longest Substring Without Repeating Characters 
Total Accepted: 5010 Total Submissions: 22089 My Submissions
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.
注意该题之前的测试用例是1001个,最近又增加了一个。
2、题目1530:最长不重复子串
时间限制:1 秒内存限制:128 兆特殊判题:否提交:873解决:284
题目描述:
最长不重复子串就是从一个字符串中找到一个连续子串,该子串中任何两个字符都不能相同,且该子串的长度是最大的。
输入:
输入包含多个测试用例,每组测试用例输入一行由小写英文字符a,b,c...x,y,z组成的字符串,字符串的长度不大于10000。
输出:
对于每组测试用例,输出最大长度的不重复子串长度。
样例输入:
absd
abba
abdffd
样例输出:
4
2
4
来源:
阿尔卡特2013年实习生招聘笔试题
【解题思路】
1、暴力搜索
针对每个点都搜索一次,每次比较求最大长度。
因为是字母,所以可以考虑用数组记录每个字母是否出现了。
声明一个长度为128的数组appear[]。
从i开始统计,开始是appear[array[i]] = 1; 临时长度tempLen = 1;
然后从j = i+1,循环统计,如果appear[array[i] - 'a'] = 0,那么tempLen++;
否则的话,就比较临时长度和maxLen,将其中的大值赋给maxLen,appear全部赋值为0;
再回到主循环。
【LeetCode】Java AC

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        int len = s.length();
        int size = 128;
        char array[] = s.toCharArray();
        int appear[] = new int[size];
        int maxLen = 0;
        for(int i = 0; i < len; i++){
            int num = array[i];
            appear[num] = 1;
            int tempLen = 1;
            for(int j = i+1; j < len ; j++){
                int numj = array[j];
                if(appear[numj] == 0) {
                    tempLen++;
                    appear[numj] = 1;
                }else{
                    if(tempLen > maxLen){
                        maxLen = tempLen;
                    }
                    appear = new int[size];
                    break;
                }
            }
            if(tempLen > maxLen){
                maxLen = tempLen;
            }
        }
        return maxLen;
    }
}
【九度】Java AC
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
 
public class Main {
    /*
     * 1531
     */
    public static void main(String[] args) throws Exception {
        StreamTokenizer st = new StreamTokenizer
					(new BufferedReader(new InputStreamReader(System.in)));
        while (st.nextToken() != StreamTokenizer.TT_EOF) {
            String a = st.sval;
            int appear[] = new int[26];
            char[] array = a.toCharArray();
            int len = array.length;
            int maxLen = 0;
            for (int i = 0; i < len; i++) {
                appear[array[i] - 'a'] = 1;
                int tempLen = 1;
                for (int j = i+1; j < len; j++) {
                    int num = (int)(array[j] - 'a');
                    if (appear[num] == 0) {
                        tempLen ++;
                        appear[num] = 1;
                    }else {
                        if (tempLen > maxLen) {
                            maxLen = tempLen;
                        }
                        appear = new int[26];
                        break;
                    }
                }
                if (tempLen > maxLen) {
                    maxLen = tempLen;
                }
            }
            System.out.println(maxLen);
        }
    }
}
/**************************************************************
    Problem: 1530
    User: wzqwsrf
    Language: Java
    Result: Accepted
    Time:530 ms
    Memory:25640 kb
****************************************************************/
2、最小滑动窗口
声明一个长度为128的数组appear[]。
1)、初始状态,start = 0,end = 0,从点开始扫描,当发现有一个字符在之前已经出现过,说明已经有一个长度已经出现了,就是end - start。
2)、从start开始查找,一直找到重复字符第一次出现的位置,这样就可以进行下一次扫描了。
具体思路就是这样的,比如有这样一个字符串abcdcabem。
第一次扫描到index = 4,'c'处发现'c'在之前就已经出现过了,那么abcd就是一个长度,4。
接下来start++,一直到index = 2,'c'处,从'c'的下一个位置'd'开始扫描。

图示


Java AC

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s == null || "".equals(s)){
            return 0;
        }
        int len = s.length();
        int array[] = new int[256];
        Arrays.fill(array, -1);
        int start = 0;
        int maxLen = 0;
        array[(int)(s.charAt(0))] = 0;
        for(int i = 1; i < len; i++){
            int num = (int)(s.charAt(i));
            if(array[num] != -1){
                int tempLen = i - start;
                maxLen = maxLen > tempLen ? maxLen : tempLen;
                start = array[num] + 1;
                i = start;
                Arrays.fill(array, -1);
                array[(int)(s.charAt(start))] = start;
            }else{
                array[num] = i;
            }
        }
        int tempLen = len - start;
        maxLen = maxLen > tempLen ? maxLen : tempLen;
        return maxLen;
    }
}
Python AC 速度太慢,考虑优化。。。

class Solution:
    # @return an integer
    def lengthOfLongestSubstring(self, s):
        if not s:
            return 0
        sLen = len(s)
        sDict = {}
        start = 0
        maxLen = 0
        sDict[s[0]] = 0
        k = 1
        while k < sLen:
            if s[k] in sDict:
                tempLen = k - start
                maxLen = maxLen if maxLen > tempLen else tempLen
                start = sDict[s[k]] + 1
                k = start + 1
                sDict = {}
                sDict[s[start]] = start
            else:
                sDict[s[k]] = k
                k += 1
        tempLen = sLen - start
        maxLen = maxLen if maxLen > tempLen else tempLen
        return maxLen

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值