134day( Longest Substring Without Repeating Characters的方法)

本文探讨了三种求解最长无重复字符子串长度的方法:使用Set容器验证子串唯一性的暴力枚举法、改进效率的滑动窗口法以及利用HashMap优化窗口移动的高效解法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

《2018年2月22日》【连续134天】

标题: Longest Substring Without Repeating Characters的方法;

内容:

1.昨天的题目:

阅读了它的解题思路:
方法一:
利用set容器的唯一性,来判断字符串是否有重复元素,然后枚举所有的子字符串,缺点的耗时,程序超时:

 

class Solution {
   public static boolean allunique(String s,int start, int end) {
		 Set<Character> set =new HashSet<>();
		 boolean truth=true;
		 for(int i=start;i<end;i++)
		 {
			 Character chars =s.charAt(i);
			 if(set.contains(chars)) truth=false;  //通过set容器的唯一性判断子字符串是否有重复元素;
			 set.add(chars);
		 }
		 return truth;
		 
	 }
	 
	 public static int lengthOfLongestSubstring(String s) {  //本体
	       int length =s.length();
	       int result =0;
	       String longest="";
	       for(int i=0;i<length;i++)
	    	   for(int j=i+1;j<=length;j++)
	    	   {
	    		   if(allunique(s,i,j)) longest=s.substring(i, j);
	    		   result =Math.max(result, longest.length());
	    	   }
	       return result;
	 }	 
	
}

方法二:滑动窗口(sliding window)
简单来[i,j)向右滑动一个就变成了[i+1,j+1);

 

因为在方法一中我们重复的检查了许多子字符串,如果是s[i,j)是无重复子字符串,那么只需检查第j个元素是否在前面重复,

所以我们用滑动窗口来判断,每次见j向右移一个,直至重复,就让i向右移一格:

 public static int lengthOfLongestSubstring(String s) {  //本体
	       int length =s.length();
	       int result =0; 
	       int i=0;
	       int j=0;
	       Set<Character> set =new HashSet<>();
	       while (i<length && j<length)
	       {
	    	   if(!set.contains(s.charAt(j)))
	    	   {
	    		   set.add(s.charAt(j++));
	    		   result=Math.max(result, j-i);
	    	   }
	    	   else
	    		   set.remove(s.charAt(i++));
	       }
	       return result;
	 }	 


方法三:
如果用滑动窗口的话,如果j出现了重复,i可以直接移到与第j位重复元素s的右边,

 

即[i,j)->[s+1,j),而通过HashMap可以直接确定s的位置;

 

 public class Solution {
     public static int lengthOfLongestSubstring(String s) { 
	       int length =s.length();
	       int result =0; 
	       int i=0;
	       int j=0;
	       HashMap<Character, Integer> map = new HashMap<>();
	       for(;j<length;j++)
	       {	      
	    	   if(map.containsKey(s.charAt(j)))
	    		   i =Math.max(map.get(s.charAt(j)), i);
	    	   result =Math.max(result, j-i+1);
	    	   map.put(s.charAt(j), j+1);
	       }
	       return result;
	 }	 
}
	

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值