LeetCode3-4(无重复字符的最长子串、寻找两个正序数组的中位数)

1.无重复字符的最长子串

①暴力解法

根据题目,将字符串转换为char类型,一次循环,然后使用一个临时StringBuffer类型的temp变量进行判断。若当前字节在temp字符串中不存在则追,否则进行截取,然后继续往下运行判断。

代码如下:

public int lengthOfLongestSubstring(String s) {
	int max = 0;
	StringBuffer temp = new StringBuffer();
	
	char[] array = s.toCharArray();
	for(char arr:array){
		String str = temp.toString();
		String a = String.valueOf(arr);
		
		if(!str.contains(a)){
			temp.append(a);
		}else{
			//最大值判断
			max = str.length()>max?str.length():max;
			//进行截取,再加上当前值
			temp = new StringBuffer(temp.substring(str.indexOf(a)+1)+a);
		}
	}
	max = temp.length()>max?temp.length():max;
	return max;
}

②窗口移动方式

参考官方解析。使用移动方式,定义左右两个指针,左右两个指针一起移动,右侧指针停下的那一刻,进行字符串的长度的比较。存储方式使用HashSet的不重复的特性。

代码如下:

public int lengthOfLongestSubstring(String s) {
	Set<Character> sets = new HashSet<Character>();
	int right = -1;
	int temp = 0;
	
	int len = s.length();
	
	for(int i=0;i<len;i++){
		//左侧移动,去除数据
		if(i!=0){
			sets.remove(s.charAt(i-1));
		}
		//右侧移动,加入数据
		while(right+1<len&&!sets.contains(s.charAt(right+1))){
			sets.add(s.charAt(right+1));
			right++;
		}
		//比较大小
		temp = Math.max(temp, right-i+1);
	}
	return temp;
}

总结:相比于自己想出的方法,此方法使用两个指针同时移动,而自己方法相当于只使用了一个指针。自己方式等于说使用的StringBuffer做存储和比较,窗口方式使用HashSet做存储和比较,判断比较哈希效率更高,StringBuffer还需要做截取等操作。

2.寻找两个中序数组的中位数

此算法方法较多,暴力解法是合并两个数组,然后使用Arrays.sort即可,但是此方式效率较低,官方的解法较多,不一一列举,下面给出自己写的一种方式,通俗易懂。

灵感来源于“无重复字符的最长子串”,可理解为定义两个指针,一个用于数组1的移动,另一个用于数组2的移动,比较两者的大小,取较小者,然后让较小者后移。

此题目的存在奇偶两种情况,例如奇数0,1,2,则取1,即总长/2;偶数0,1,2,3则取1,2,即总长/2-1+总长/2。我们只需要循环一次,并且循环到总长/2-1处,然后再往下走一次,并且循环长度只需要小于总长/2即可。

代码如下:

public double findMedianSortedArrays(int[] nums1, int[] nums2) {
		
	int l1 = nums1.length;
	int l2 = nums2.length;
	int sum = l1+l2;
	
	int n = sum/2;
	
	int a = 0,b = 0;
	int a_n = 0,b_n = 0;//第一个数组第几位、第二个数组第几位
	
	for(int i=0;i<n;i++){
		//取得第一数组的值、第二数组的值
		if(a_n<l1){
			a = nums1[a_n];
		}else{
			a = nums2[b_n];
		}
		if(b_n<l2){
			b = nums2[b_n];
		}else{
			b = nums1[a_n];
		}
		//比较两个数组的值大小
		if(a_n<l1&&a<=b){
			a_n++;
		}else{
			b_n++;
		}
	}
	
	int count = sum%2==0?2:1;//中位数数量
	int temp = 0;
	if(count==2){
		temp = a<=b?a:b;
	}
	
	//再往下比一次
	if(a_n<l1){
		a = nums1[a_n];
	}else{
		a = nums2[b_n];
	}
	if(b_n<l2){
		b = nums2[b_n];
	}else{
		b = nums1[a_n];
	}
	temp += (a<=b?a:b);
	
	return ((double)temp)/count;
}

记录自己解题的过程和方法,加上自己的见解,官方解析更规范也更清晰。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值