无重复字符的最长子串
1.问题描述
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 示例 2:
输入: s = "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。 示例 3:
输入: s = "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。 示例 4:
输入: s = "" 输出: 0
提示:
0 <= s.length <= 5 * 104 s 由英文字母、数字、符号和空格组成
2.预备知识
1)unordered_set(哈希集合)
-
几个函数实现增删查
-
unordered_set::insert
-
unordered_set::find
-
unordered_set::erase
-
上列函数平均复杂度为O(1),最坏的平均复杂度为O(N),N是指元素数量
-
是容器的集合,插入重复相同的值无效
-
它是一种无序的集合
3.思路
滑动窗口
用一个指针指向窗口右边,一个指向窗口左边,如果字符没有出现过就向右滑动窗口,如果出现过,则想左滑动窗口,直到现有窗口中无重复出现的字符,每次变向滑动前记录并比较子串长度
4.代码
c++
int lengthOfLongestSubstring(string s){
unordered_set<char> occ;
int rk=-1;//右指针初始化为-1,相当于窗口的左边界的左侧,还没有开始滑动
int ans=0;//子串长度
int n=s.size();
for(int i=0;i<n;i++){//i即为左边界
if(i!=0)//i不为0则出现重复字符
{
occ.erase(s[i-1]);//执行此条语句时i的初始值为1
}
while(rk+1<n&&!occ.count(s[rk+1]))//向右移动指针,右指针没有出界并且现有子串没有包含重复的值
{
occ.insert(s[rk+1]);
rk++;
}
ans=max(ans,rk-i+1);//从第i到第rk+1的极长无重复字符串
}
return ans;
}
Java初始并发问题
package exercise;
public class e5 implements Runnable {
//多个线程同时操作一个对象
//买火车票的例子
//发现问题:多个线程操作同一个资源的情况下,线程不安全,数据紊乱(这里会有多人拿到同一张票)
private int TicketNumbers=10;//票数
private int millis=200;//模拟延时时间(毫秒)
public void run() {
while(true) {
if(TicketNumbers<=0) {
break;
}
try {
Thread.sleep(millis);//模拟延时
}catch(InterruptedException e) {
System.out.println("InterruptedException");
}
System.out.println(Thread.currentThread().getName()+"-->拿到了第"+TicketNumbers+"票");
TicketNumbers--;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
e5 text=new e5();
new Thread(text,"cathy").start();
new Thread(text,"Nathy").start();
new Thread(text,"Teacher").start();
}
}
实例
package exercise;
//龟兔赛跑
public class a implements Runnable{
private static String winner;
@Override
public void run() {
for (int i = 1; i <=100; i++) {
//兔子睡觉
if(Thread.currentThread().getName().equals("兔子")&&i%50==0){
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
boolean flag=gameover(i);//判断程序是否停止
if(flag) {
break;
}
System.out.println(Thread.currentThread().getName()+"-->跑了"+i+"步");
}
}
//游戏结束
private boolean gameover(int step){
if(winner!=null){
return true;
}
if(step>=100){
winner=Thread.currentThread().getName();
System.out.println("winner is"+winner);
return true;
}
return false;
}
public static void main(String[] args) {
a race=new a();
new Thread(race,"兔子").start();
new Thread(race,"乌龟").start();
}
}