第 187 场力扣周赛题解

5400. 旅行终点站

思路:哪个城市没作为起点呢它就是终点。

class Solution {
    public String destCity(List<List<String>> paths) {
    	
    	Map<String,String> count=new HashMap<>();
    	
    	for(int i=0;i<paths.size();i++)
    		count.put(paths.get(i).get(0), paths.get(i).get(1));
    	
    	for(int i=0;i<paths.size();i++)
    		if(!count.containsKey(paths.get(i).get(1)))
    			return paths.get(i).get(1);
    	
    	return "";
    }
}

1437. 是否所有 1 都至少相隔 k 个元素

思路:标记下上一个1出现的位置即可。

class Solution {
    public boolean kLengthApart(int[] nums, int k) {
    	
    	int last=-k-100;
    	for(int i=0;i<nums.length;i++) {
    		if(nums[i]==1) {
    			if(i-last<=k) return false;
    			else last=i;
    		}
    	}
    	
    	return true;
    }
}

5402. 绝对差不超过限制的最长连续子数组

思路:首先二分答案,之后根据当前答案定义两个堆,一个大顶堆和一个小顶堆,用大小顶堆的队头比较判断答案是否成立。

PS:说实话这题题意有锅啊,题目说了任意两个元素之间的绝对差必须小于或者等于 limit,但是样例里数组只有一个元素的时候你竟然返回1?白wa了两次。

class Solution {
	
	class node {
		int val,id;
		public node(int val,int id) {
			this.val=val;
			this.id=id;
		}
	}
	
    public int longestSubarray(int[] nums, int limit) {
    	
    	if(nums.length<=1) return nums.length;
    	
    	int ans=0;
    	int l=1,r=nums.length;
    	while(l<=r) {
    		int mid=(l+r)/2;
    		if(check(nums,limit,mid)) {
    			ans=mid;
    			l=mid+1;
    		}
    		else
    			r=mid-1;
    	}
    	
    	return ans;
    }
    
    private boolean check(int[] a,int x,int len) {
    	
    	PriorityQueue<node> q=new PriorityQueue<>((aa,bb)->aa.val-bb.val);
    	PriorityQueue<node> q2=new PriorityQueue<>((aa,bb)->bb.val-aa.val);
    	for(int i=0;i<len;i++) {
    		q.add(new node(a[i],i));
    		q2.add(new node(a[i],i));
    	}
    	
    	if(q2.peek().val-q.peek().val<=x) return true;
    	
    	for(int i=len;i<a.length;i++) {
    		while(!q.isEmpty() && q.peek().id<=i-len)
    			q.poll();
    		while(!q2.isEmpty() && q2.peek().id<=i-len)
    			q2.poll();
    		q.add(new node(a[i],i));
    		q2.add(new node(a[i],i));
    		if(q2.peek().val-q.peek().val<=x) return true;
    	}
    	
    	return false;
    }
    
}

5403. 有序矩阵中的第 k 个最小数组和

思路:二分答案,判断时只用看有多少种数组和小于当前答案即可,若数量不为k,则更改答案继续判断。

class Solution {
	
	private int num;
	
    public int kthSmallest(int[][] mat, int k) {
    	
    	int ans=0;
    	int m=mat.length;
    	int n=mat[0].length;
    	
    	int l=0,r=0;
    	for(int i=0;i<m;i++) {
    		l+=mat[i][0];
    		r+=mat[i][n-1];
    	}
    	
    	int start=l;
    	
    	while(l<=r) {
    		int mid=(l+r)/2;
    		if(check(mat,start,mid,k)) {
    			ans=mid;
    			r=mid-1;
    		}
    		else
    			l=mid+1;
    	}
    	
    	return ans;
    }
    
    private boolean check(int[][] a,int start,int mx,int k) {
    	
    	num=0;
    	
    	dfs(a,0,start,mx,k);
    	
    	return num>=k;
    	
    }
    
    private void dfs(int[][] a,int index,int start,int mx,int k) {
    
    	if(start>mx || num>k)
    		return;
    	
    	if(index==a.length) {
    		num++;
    		return;
    	}
    	
    	for(int i=0;i<a[0].length;i++) 
    		dfs(a,index+1,start-a[index][0]+a[index][i],mx,k);
    	
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值