小白编程Day06

无重复字符的最长子串

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(哈希集合)

  1. 几个函数实现增删查

  • unordered_set::insert

  • unordered_set::find

  • unordered_set::erase

  1. 上列函数平均复杂度为O(1),最坏的平均复杂度为O(N),N是指元素数量

  2. 是容器的集合,插入重复相同的值无效

  3. 它是一种无序的集合

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();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值