乘风破浪:LeetCode真题_003_Longest Substring Without Repeating Characters
乘风破浪:LeetCode真题_003_Longest Substring Without Repeating Characters
一、前言
在算法之中出现最多的就是字符串方面的问题了,关于字符串的模式匹配,回文字符串,等等问题都是非常经典的,同样的在字符串之中寻找最长的不重复的字符串的长度也是比较有意义的。
二、LeetCode真题_003_Longest Substring Without Repeating Characters
2.1 问题

2.2 分析与解决
问题是非常清晰的,我们最先想到的就是使用暴力算法,通过读取当前的字符和已经读取过的字符进行比较,如果冲突则调整开始的位置,并记录当前的最大长度,直至遍历结束,这样的时间复杂度就要到达O(n~3)了。那么有没有比较好的解决方案的,我们又想到了hash算法,这样就省去了比较需要花费的遍历时间,增加了程序需要占用的空间。
首先看看官方的作答:
暴力算法:

public class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length();
int ans = 0;
for (int i = 0; i < n; i++)
for (int j = i + 1; j <= n; j++)
if (allUnique(s, i, j)) ans = Math.max(ans, j - i);
return ans;
}
public boolean allUnique(String s, int start, int end) {
Set<Character> set = new HashSet<>();
for (int i = start; i < end; i++) {
Character ch = s.charAt(i);
if (set.contains(ch)) return false;
set.add(ch);
}
return true;
}
}

使用HashSet:

public class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length();
Set<Character> set = new HashSet<>();
int ans = 0, i = 0, j = 0;
while (i < n && j < n) {
// try to extend the range [i, j]
if (!set.contains(s.charAt(j))){
set.add(s.charAt(j++));
ans = Math.max(ans, j - i);
}
else {
set.remove(s.charAt(i++));
}
}
return ans;
}
}

使用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;
}
}
假设只有ASCII的字符出现,没有中文:

public class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length(), ans = 0;
int[] index = new int[128]; // current index of character
// try to extend the range [i, j]
for (int j = 0, i = 0; j < n; j++) {
i = Math.max(index[s.charAt(j)], i);
ans = Math.max(ans, j - i + 1);
index[s.charAt(j)] = j + 1;
}
return ans;
}
}

我们的算法:
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map; public class Solution { // 可以处理所有的UTF-8字符
public int lengthOfLongestSubstring(String s) {
// 字符串输入不合法
if (s == null) {
return 0;
} // 当前处理的开始位置
int start = 0;
// 保存结果
int result = 0;
// 访问标记,记录最新一次访问的字符和位置
Map<Character, Integer> map = new HashMap<>(s.length()); for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
// 如果字符已经出现过(在标记开位置算起),就重新标记start
if (map.containsKey(ch) && map.get(ch) >= start) {
start = map.get(ch) + 1;
}
// 如果没有出现过就求最大的非重复子串的长度
else {
result = Math.max(result, i - start + 1);
} // 更新访问记录
map.put(ch, i);
}
return result;
} // 只考虑ASCII字符
public int lengthOfLongestSubstring2(String s) {
// 字符串输入不合法
if (s == null) {
return 0;
} // 标记字符是否出现过,并且记录是的最新一次访问的元素的位置
int[] appear = new int[256];
// 初始化为-1
Arrays.fill(appear, -1);
// 当前处理的开始位置
int start = 0;
// 保存结果
int result = 0; for (int i = 0; i < s.length(); i++) {
// 如果字符已经出现过(在标记开位置),就重新标记start
if (appear[s.charAt(i)] >= start) {
start = i + 1;
}
// 如果没有出现过就求最大的非重复子串的长度
else {
result = Math.max(result, i - start + 1);
}
// 标记第i个字符已经被访问过(最新是第i个位置)
appear[s.charAt(i)] = i;
} return result;
}
}

三、总结
字符串方面的问题我们要非常熟悉String的一些工具函数,以及考虑到hash算法的数据结构来优化和解决问题。
乘风破浪:LeetCode真题_003_Longest Substring Without Repeating Characters的更多相关文章
- LeetCode 第 3 题(Longest Substring Without Repeating Characters)
LeetCode 第 3 题(Longest Substring Without Repeating Characters) Given a string, find the length of th ...
- leetcode第三题--Longest Substring Without Repeating Characters
Problem:Given a string, find the length of the longest substring without repeating characters. For e ...
- leetcode第三题Longest Substring Without Repeating Characters java
Longest Substring Without Repeating Characters Given a string, find the length of the longest substr ...
- LeetCode第三题—— Longest Substring Without Repeating Characters(最长无重复子字符串)
题目描述 Given a string, find the length of the longest substring without repeating characters. Example ...
- 【一天一道LeetCode】 #3 Longest Substring Without Repeating Characters
一天一道LeetCode (一)题目 Given a string, find the length of the longest substring without repeating charac ...
- 【LeetCode OJ】Longest Substring Without Repeating Characters
题目链接:https://leetcode.com/problems/longest-substring-without-repeating-characters/ 题目:Given a string ...
- 【LeetCode】003. Longest Substring Without Repeating Characters
Given a string, find the length of the longest substring without repeating characters. Examples: Giv ...
- 【LeetCode】3. Longest Substring Without Repeating Characters 无重复字符的最长子串
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 公众号:负雪明烛 本文关键词:无重复字符,最长子串,题解,leetcode, 力扣,py ...
- 【LeetCode】3.Longest Substring Without Repeating Characters 最长无重复子串
题目: Given a string, find the length of the longest substring without repeating characters. Examples: ...
随机推荐
- WPF简单MVVM实现
1. MVVM介绍: MVVM就是: Model -- 模型(现实中对象的抽象) View -- UI(用户界面) ViewModel -- UI界面的抽象(给View提供数据,并响应View的操作) ...
- ARM和X86架构
重温下CPU是什么 中央处理单元(CPU)主要由运算器.控制器.寄存器三部分组成.运算器起着运算的作用,控制器负责发出CPU每条指令所需要的信息,寄存器保存运算或者指令的一些临时文件以保证更高的速度. ...
- 747_Largest-Number-At-Least-Twice-of-Others
目录 747_Largest-Number-At-Least-Twice-of-Others Description Solution Java solution Python solution 74 ...
- 使用 Angular 和 RxJS 实现的无限滚动加载
无限滚动加载应该是怎样的? 无限滚动加载列表在用户将页面滚动到指定位置后会异步加载数据.这是避免寻主动加载(每次都需要用户去点击)的好方法,而且它能真正保持应用的性能.同时它还是降低带宽和增强用户体验 ...
- Spring----有关bean的配置
1.单例类的配置如果我们想创建一个单例类的bean,只能会通过静态工厂来创建.下图为一个单例类: Stage并没有提供公开的构造方法,构造方法都是私有的,必须通过getInstance()方法获得已经 ...
- 用INFORMATION_SCHEMA逻辑MySQL的索引
分库分表的场景下,变更目前还不知道有哪个表变更索引失败,是不是所有的表都变更成功了,所以可以从INFORMATION_SCHEMA通过罗列索引个数,或者查看索引行,就可以知道是不是所有的都变更成功了: ...
- 在用户控件(ASCX)创建用户控件(ASCX)
"我建了两个ascx,ascxA,ascxBascxA中放了一个PlaceHold,ascxB中放了一个textBoxascxA在page_load中动态创建了5个ascxB但是页面上什么都 ...
- Golang报错mixture of field:value and value initializers
Golang 在使用匿名成员初始化时,如果出现 mixture of field:value and value initializers 是因为初始化的方式不对,见代码: package main ...
- UVA1583(最小生成元)
对于这种需要一遍遍枚举求解的,打表可以提高很多效率 #include <iostream> #include <string> #include <cstring> ...
- .NET 垃圾回收浅解
在说明垃圾回收的实现机制之前,先说明一下垃圾回收存在的背景. 垃圾回收器(GC)是.NET平台中一个很重要的组成部分,.NET垃圾回收机制降低了编写程序的复杂程度,使程序员不用耗费精力去处理析构,成功 ...