LeetCode第3题---无重复字符的最长子串

                     LeetCode第3题---无重复字符的最长子串


题目描述 

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

暴力解题法:

首先,我们假设我们有一个函数,可以判断一个字符串中是否有相同的字符,allUnique();

然后我们再把这个string的所有可能的情况都截取下来,放进去这个函数里面判断,最后求得最大的值就可以了。

class Solution {
    //假设我们有一个函数,可以来判断这个字符串的单词都是唯一的,unique()
    public boolean allUnique(String s,int start,int end){
        //创建一个字符hashSet来存储
        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;
        }

    public int lengthOfLongestSubstring(String s) {
        //有一个num来计数
        int num=0;
        /*
        *从第i个到第length()-1个,结束位置从i+1个到length()
        */
        for(int i=0;i<s.length();i++){
            for(int j=i+1;j<=s.length();j++){
                if(allUnique(s,i,j)) num=Math.max(num,j-i);
            }
            
        }
        return num;
    }
}

但是,这种方法时间太久了,系统不通过。

滑动窗口法:

一个很厉害的想法,滑动窗口法:

我们先举一个例子:

abccd

一开始指针i和指针j都指向a,

字符串(java里我们用一个hashSet存储)为a,还没有重复,我们记录长度(和max比较),移动j。

set变为ab,还没有重复,我们记录长度(和max比较),移动j。

set变为abc,还没有重复,我们记录长度(和max比较),移动j。

set变为abcc,在这里重复了,然后把i进行移动(把第i个字符在set里面去掉),

set变成bcc,在这里重复了,然后把i进行移动(把第i个字符在set里面去掉),

set变成cc,在这里重复了,然后把i进行移动(把第i个字符在set里面去掉),

set变成c,还没有重复,我们记录长度(和max比较),移动j。

set变成cd,还没有重复,我们记录长度(和max比较),移动j,发现到String的最尾部了,所以停止算法。

总结就是:

 定义一个hashSet,

当(i和j没有到达尾部时):{

     根据j的位置取出字符,存进char c;

     如果c不存在set里面{

        我们把存进set里面,记录长度,然后移动j的位置

     }

    如果c存在在set的位置{

        我们移动i的位置(去掉hashSet的第i个元素,然后i++);

    }

}

代码

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        int n = s.length();
        Set<Character> set = new HashSet<>();
        int i=0,j=0,num=0;

        while(i<n && j<n){
            char c=s.charAt(j);
            //如果不包含c的话
            if(!set.contains(c)){
                num=Math.max(num,j-i+1);
                set.add(s.charAt(j++));
            }
            else{
                set.remove(s.charAt(i++));
            }

        }
        return num;

    }
}

滑动窗口的解法二:

import java.util.*;
public class Solution {
    public int lengthOfLongestSubstring(String s) {
        int n = s.length();
        //在这里改为map比较好
        Vector v = new Vector(); 
        int i=0,j=0,num=0;

        while(i<n && j<n){
           char c=s.charAt(j);
           //如果不包含c的话
           if(v.indexOf(c)==-1){
                num=Math.max(num,j-i+1);
               v.addElement(s.charAt(j++));
            }
           else{
                if(v.indexOf(c)!=-1){
                	 v.removeElementAt(0);
                	 i++;
                }
                  
                }
               
           }
        return num;
        }
}

 

完成。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值