题目:

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

示例:

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.

问题的难点在于光标移动过程中,一旦遇到重复需要重新开始计算长度

第一次提交的代码如下:

class Solution {
public int lengthOfLongestSubstring(String s) {
int longestLength = 0;
int currentLength = 0;
String longestStr = "";
char tmpChar;
int repeatIndex = 0; for(int i = 0; i < s.length(); i++){
tmpChar = s.charAt(i);
repeatIndex = longestStr.indexOf(tmpChar, 0);
// 遇到重复,从重复的下一位开始
if(repeatIndex >= 0) {
if(longestLength < currentLength){
longestLength = currentLength;
}
longestStr = longestStr.substring(repeatIndex + 1) + tmpChar;
currentLength = longestStr.length();
} else {
longestStr += s.charAt(i);
currentLength++;
}
} if(longestLength < currentLength) {
return currentLength;
} return longestLength;
}
}

提交后执行效率只击败了15.65%

为提高效率,考虑更新如下方面:

1. String 用StringBuilder替换(不需要线程安全,所以不使用开销大的StringBuffer)

2. char用String替换(是为了避免循环中char到String转换时的开销)

修改后的代码如下:

class Solution {
public int lengthOfLongestSubstring(String s) {
int longestLength = 0;
int currentLength = 0;
StringBuilder builder = new StringBuilder();
String charStr;
int repeatIndex; for(int i = 0; i < s.length(); i++){
charStr = s.substring(i, i + 1);
repeatIndex = builder.indexOf(charStr, 0);
// 遇到重复,从重复的下一位开始
if(repeatIndex >= 0) {
if(longestLength < currentLength){
longestLength = currentLength;
}
builder.delete(0, repeatIndex + 1);
builder.append(charStr);
currentLength = builder.length();
} else {
builder.append(charStr);
currentLength++;
}
} if(longestLength < currentLength) {
return currentLength;
} return longestLength;
}
}

提交后执行效率只击败了65.57%

如何再进一步提高效率呢?因为循环里面有查询字符存在的功能,考虑替换数据结构,用HashMap替换StringBuffer,

但是在思考了一会没有找到使用HashMap的写法,于是直接参考了现有的方案,如下:

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;
}
}

其实实现的逻辑跟之前的思路一致,j 作为整个字符串的额游标,i 作为遇到重复元素后重新开始位置的游标,ans记录最大值

这样的写法不但是用HashMap来代替String查找,而且不用单独存储子字符串。

复杂度如下:

Complexity Analysis

  • Time complexity : O(n)O(n). Index jj will iterate nn times.

  • Space complexity (HashMap) : O(min(m, n)).

参考:

https://leetcode.com/problems/longest-substring-without-repeating-characters

LeeCode(No3 - Longest Substring Without Repeating Characters)的更多相关文章

  1. 最长子串(Leetcode-3 Longest Substring Without Repeating Characters)

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

  2. LeeCode Algorithm #3 Longest Substring Without Repeating Characters

    一开始以为是不连续的,其实要求子串是连续的.想法:two-pointer O(n)时间,再借助256大小的int数组.两个下标i,j(i<=j).对于i=0,找到最右侧的字符不重复的下标的后一位 ...

  3. LeetCode 3. 无重复字符的最长子串(Longest Substring Without Repeating Characters)

    题目描述 给定一个字符串,找出不含有重复字符的最长子串的长度. 示例: 给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是3. ...

  4. LeetCode:Longest Substring Without Repeating Characters(最长不重复子串)

    题目链接 Given a string, find the length of the longest substring without repeating characters. For exam ...

  5. Longest Substring Without Repeating Characters(Difficulty: Medium)

    题目: Given a string, find the length of the longest substring without repeating characters. Examples: ...

  6. LeetCode 3 Longest Substring Without Repeating Characters(最长不重复子序列)

    题目来源:https://leetcode.com/problems/longest-substring-without-repeating-characters/ Given a string, f ...

  7. 【leetcode】Longest Substring Without Repeating Characters (middle)

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

  8. 3. Longest Substring Without Repeating Characters (ASCII码128个,建立哈西表)

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

  9. LeetCode OJ:Longest Substring Without Repeating Characters(最长无重复字符子串)

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

随机推荐

  1. ztree 树的模糊搜索

    (转载),有个坑记录下: (原文)实现类似下面这种: /** * 展开树 * @param treeId */ function expand_ztree(treeId) { var treeObj ...

  2. 30-盐水(分段dfs)

    链接:https://www.nowcoder.com/acm/contest/94/K来源:牛客网 时间限制:C/C++ 5秒,其他语言10秒 空间限制:C/C++ 131072K,其他语言2621 ...

  3. 25-Fibonacci(矩阵快速幂)

    http://poj.org/problem?id=3070     Fibonacci Time Limit: 1000MS   Memory Limit: 65536K Total Submiss ...

  4. Evil Book -- CodeChef

    传送门 分析 对于这道题,我们首先思考一个贪心策略,即对于所有我们要打败的厨师我们肯定可以先打败需使用帮助次数少的厨师再打败需使用帮助次数多的厨师 ,因为这样可以使得能支付得起帮助费用的可能性尽可能的 ...

  5. setTimeout()和setInterval() 何时被调用执行(非多线程).RP

    定义 setTimeout()和setInterval()经常被用来处理延时和定时任务.setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式,而setInterval()则可以在每隔 ...

  6. 数据结构--树--AVL树

    详情查看:http://www.cnblogs.com/skywang12345/p/3577360.html

  7. MyBatis基本查询、条件查询、查询排序

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-/ ...

  8. Zinterstore 命令

    先来看一下这个命令的定义: Redis Zinterstore 命令计算给定的一个或多个有序集的交集,其中给定 key 的数量必须以 numkeys 参数指定,并将该交集(结果集)储存到 destin ...

  9. 树莓派(Raspberry Pi 3) - 系统烧录及xshell连接

    树莓派(Raspberry pi)是一块集成度极高的ARM开发板,不仅包含了HDMI,RCA,CSI,HDMI,GPIO等端口,还支持蓝牙以及无线通信.由于 Raspberry Pi 几乎是为 Lin ...

  10. sizeof的用法与字节对齐

    一.sizeof是什么? sizeof是一种预编译处理,不是函数,不是一元表达式.也即,作用阶段在编译期. 二.功能是什么? sizeof返回变量或类型的字节数. 三.调用方式 sizeof(obje ...