LeetCode第[3]题(Java):Longest Substring Without Repeating Characters 标签:Linked List

题目中文:没有重复字符的最长子串

题目难度:Medium

题目内容

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.

翻译

给定一个字符串,计算得到最长子字符串的长度,而子串内不能重复字符。

例子:

给定“abcabcbb”,答案是“abc”,长度为3。

给定“bbbbb”,答案是“b”,长度为1。

给定“pwwkew”,答案是“wke”,长度为3。注意,答案必须是子字符串(连续的),“pwke”是子序列,而不是子字符串。

思路:应为需要的是子串(连续),所以双重循环就可以遍历每一个子串,再用一个函数来判断这个子串内部是否有重复,没有则更新最新的长度

我的代码

 1     public int lengthOfLongestSubstring(String s) {
 2         int n = s.length();  // size(),length()这类函数不像变量length,这也是要计算的,当调用一次以上,赋值给一个变量减少复杂度
 3         int ans = 0;
 4         for (int i = 0; i < n; i++) {
 5             for (int j = i + 1; j <= n; j++) {
 6                 if (isUnique(s, i, j)) {
 7                     ans = Math.max(ans, j - i);        // 如果唯一,则更新ans
 8                 }
 9             }
10         }
11         return ans;
12     }
13
14     public static boolean isUnique(String s, int start, int end) {
15         Set<Character> hset = new HashSet<Character>();
16         for (int i = start; i < end; i++) {
17             hset.add(s.charAt(i));
18         }
19         return hset.size() == (end - start) ? true : false;        // 如果Set的大小没变说明都是唯一的
20     }

982 / 983 test cases passed.  Status: Time Limit Exceeded

超时了。。。明显这个算法复杂度为O(n3),确实大了点。。。

编码期间问题

1、程序的边界问题困扰了很久,一开始isUnique方法我是设置从 i 到 j 都判断,j到n-1结束,结果发现这样子需要加很多边界判断条件,例如输入是“C”就一个,那么 j 从下标1开始直接就越界根本不会进入循环体。又或者全是同一个字符“cccccccccc”,isUnique只会一直false,ans也不会更新。偷看了下参考答案,发现第一个和我几乎一样,仔细一看发现它的判唯一范围是从 i 到 j 的前一个字符, j的范围从 i+1 一直到 n,这样一来就总会进入循环体,并且ans至少更新一次。

答案一

code略

和我的几乎一样就是判断唯一的方法里它是这么写的:

    public boolean allUnique(String s, int start, int end) {
        Set<Character> set = new HashSet<Character>();
        for (int i = start; i < end; i++) {
            Character ch = s.charAt(i);
            if (set.contains(ch)) return false;
            set.add(ch);
        }
        return true;
    }

可能比我的算法复杂度低一点,因为发现重复的时候它可以直接返回,而我那个是全部添加后才能判断重复。记住set、map都有contains功能。

答案二

 1     public static int lengthOfLongestSubstring2(String s) {
 2         int n = s.length(), ans = 0;
 3         Map<Character, Integer> map = new HashMap<Character, Integer>();
 4         for (int j = 0, i = 0; j < n; j++) {
 5             if (map.containsKey(s.charAt(j))) {
 6                 i = Math.max(map.get(s.charAt(j)), i);
 7             }
 8             ans = Math.max(ans, j - i + 1);
 9             map.put(s.charAt(j), j + 1);
10         }
11         return ans;
12     }

983 / 983 test cases passed.  Runtime: 66 ms    beats  25.38%   算法复杂度:O(N)

思路:利用map的key-value结构存储值以及对应顺位(下标+1),然后每次指针(j)下移的时候都判断是否已经包含了此字符,如果是则将 i 的值更新,所以每次ans都是取最大的 i 到 j (包括j)的长度。

  所以而 i 指向的一直是不包含重复的子串开头,而 j 指向就是结尾。ans的每次更新,保证了ans是最大的长度。

  例如 abcdaa

  当 j = 4时,发现map内有此时 j 指向的a,所以更新 i 的值,表明之前的a在顺位第 1 个,所以ans就等于新a的位置(j)减去老a的位置(顺位 i -1),所以相当于 j - i +1 = 4。

  当 j = 5时,发现map内有此时 j 指向的a,所以更新 i 的值,表明之前的a在顺位第 5 个,所以ans_temp = 5-5+1 = 1,取max ,ans最终等于4.

为什么不直接存下标?

  如果存储的是下标,那么最后更新的ans也只能是 j - i (新位置减去老位置),假如此时整个字符串内都没有重复,那么最后的答案就是length - 1 - 0 ,因为只有当有更新的时候才能下标直接相减。

答案三

 1     public int lengthOfLongestSubstring(String s) {
 2         int n = s.length(), ans = 0;
 3         int[] index = new int[256]; // current index of character
 4         // try to extend the range [i, j]
 5         for (int j = 0, i = 0; j < n; j++) {
 6             i = Math.max(index[s.charAt(j)], i);
 7             ans = Math.max(ans, j - i + 1);
 8             index[s.charAt(j)] = j + 1;
 9         }
10         return ans;
11     }

983 / 983 test cases passed.  Runtime: 66 ms    beats  83.43%   算法复杂度:O(N)

其实思想和方法二差不多,有点取巧性质。。。因为字符都能用ascall码表示,而ascall码一共就256个,每一个代表一个字符,(因为后128个键盘输入不了,用128也行)所以直接使用一个int数组当哈希表使用,降低了哈希表的寻址时间复杂度。

以后遇见hash表的key为单个字符时,都可以想到用int[256]来替代map.get(*);

原文地址:https://www.cnblogs.com/Xieyang-blog/p/8529870.html

时间: 2024-11-06 09:58:27

LeetCode第[3]题(Java):Longest Substring Without Repeating Characters 标签:Linked List的相关文章

LeetCode 第三题,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 s

【LeetCode每天一题】Longest Substring Without Repeating Characters(最长无重复的字串)

Given a string, find the length of the longest substring without repeating characters. Example 1:           Input: "abcabcbb"                              Output: 3                           Explanation: The answer is "abc", with the l

【LeetCode刷题系列 - 003题】Longest Substring Without Repeating Characters

题目: Given a string, find the length of the longest substring without repeating characters. Example 1: Input: "abcabcbb" Output: 3 Explanation: The answer is "abc", with the length of 3. Example 2: Input: "bbbbb" Output: 1 Exp

LeetCode解题思路:3. Longest Substring Without Repeating Characters

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.

刷题3. Longest Substring Without Repeating Characters

一.题目 Longest Substring Without Repeating Characters,具体请自行搜索. 这个题目,我看了一下,经过一番思考,我觉得实现起来不是很复杂. 但要做到bug free有点难度,主要是边界的问题. 二.这个题目,我自己实现,没有参考代码 提交了5次: 第1次: Wrong Answer,主要是" "这个空串不对 第2次.第3次:Runtime Error,"au" out of Range 第4次:Wrong Answer,

lintcode 中等题:longest substring without repeating characters 最长无重复字符的子串

题目 最长无重复字符的子串给定一个字符串,请找出其中无重复字符的最长子字符串. 例如,在"abcabcbb"中,其无重复字符的最长子字符串是"abc",其长度为 3. 对于,"bbbbb",其无重复字符的最长子字符串为"b",长度为1. 解题 利用HashMap,map中不存在就一直加入,存在的时候,找到相同字符的位置,情况map,更改下标 public class Solution { /** * @param s: a s

第三题:Longest Substring Without Repeating Characters

题目链接:题目链接 找到最长不重复子串,使用hash方法来做是极好的!遍历string,找到一个字符,然后会判断这个字符是不是已经在当前的这个子串中,这个使用hash方法,因为可见字符最多256个,那么使用hash[256]就可以!初始化为-1,保存的是相应的字符在string中的位置.如果遇到在前面存在的字符,那么需要将这个子串的start位置移动到已经存在的位置后面一位,然后继续遍历,直到遍历结束. 具体看下面的代码: class Solution { public: int lengthO

Longest Substring Without Repeating Characters leetcode java

题目: 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 s

[LeetCode] Longest Substring Without Repeating Characters 最长无重复字符的子串 C++语言 java语言实现

Given a string, find the length of the longest substring without repeating characters. Example 1: Input: "abcabcbb" Output: 3 Explanation: The answer is "abc", with the length of 3. Example 2: Input: "bbbbb" Output: 1 Explana