第 186 场力扣周赛题解

今天脑袋被门挤了,疯狂wa,排名也是掉成sb。

5392. 分割字符串的最大得分

思路:记一波前缀和,然后倒着更新答案即可。

class Solution {
    public int maxScore(String s) {
    	
    	int[] sum=new int[s.length()];
    	
    	if(s.charAt(0)=='0') sum[0]=1;
    	for(int i=1;i<s.length();i++) {
    		sum[i]=sum[i-1];
    		if(s.charAt(i)=='0')
    			sum[i]++;
    	}
    	int num=0,ans=0;
    	for(int i=s.length()-1;i>0;i--) {
    		num=num+(s.charAt(i)=='1'?1:0);
    		ans=Math.max(ans, num+sum[i-1]);
    	}
    	
    	return ans;
    }
}

5393. 可获得的最大点数

思路:和第一题有异曲同工之妙,我们可以利用前缀和暴力前半部分和后半部分分别取多少个,保证总数为k。

class Solution {
    public int maxScore(int[] cardPoints, int k) {
    	
    	int n=cardPoints.length;
    	int[] sum=new int[n];
    	sum[0]=cardPoints[0];
    	for(int i=1;i<n;i++)
    		sum[i]=sum[i-1]+cardPoints[i];
    	
    	int ans=sum[k-1],num=0;
    	for(int i=n-1;i>=n-k;i--) {
    		num+=cardPoints[i];
    		int p=k-(n-i);
    		if(p>0) ans=Math.max(ans, sum[p-1]+num);
    		else ans=Math.max(ans, num);
    	}
    	
    	return ans;
    }
}

5394. 对角线遍历 II

思路:采用BFS按层搜索,下一层是紧邻当前位置的下边节点和右边节点,按顺序添加即可(记得节点不要加重复)。

class Solution {
	
	class node{
		int val,x,y;
		public node(int val,int x,int y) {
			this.val=val;
			this.x=x;
			this.y=y;
		}
	}
	
    public int[] findDiagonalOrder(List<List<Integer>> nums) {
    	
    	int n=nums.size();
    	List<Integer> ans=new ArrayList<>();
    	Queue<node> q=new LinkedList<>();
    	Map<Long,Boolean> map=new HashMap<>();
    	
    	int mx=0;
    	for(int i=0;i<nums.size();i++)
    		mx=Math.max(mx, nums.get(i).size());
    	
    	q.add(new node(nums.get(0).get(0),0,0));
    	
    	while(!q.isEmpty()) {
    		node now=q.poll();
    		ans.add(now.val);
    		int x=now.x+1,y=now.y;
    		if(x<n && y<nums.get(x).size() && !map.containsKey((long)x*mx+y)) {
    			map.put((long)x*mx+y, true);
    			q.add(new node(nums.get(x).get(y),x,y));
    		}
    		x=now.x;y=now.y+1;
    		if(x<n && y<nums.get(x).size() && !map.containsKey((long)x*mx+y)) {
    			map.put((long)x*mx+y, true);
    			q.add(new node(nums.get(x).get(y),x,y));
    		}
    	}
    	
    	int[] res=new int[ans.size()];
    	for(int i=0;i<ans.size();i++)
    		res[i]=ans.get(i);
    	
    	return res;
    }
}

5180. 带限制的子序列和

思路:动态规划,定义dp[i]表示前i个元素中取第i个元素的的子序列最大和。当前点取或不取之和前k个数有关,我们可以同优先队列维护前边的最优解,并且要保证队头的索引与当前位置的距离不超过k。

class Solution {
	
	class node implements Comparable<node>{
		int id,val;
		public node(int id,int val) {
			this.id=id;
			this.val=val;
		}
		@Override
		public int compareTo(node o) {
			// TODO 自动生成的方法存根
			return o.val-val;
		}
		
	}
    public int constrainedSubsetSum(int[] nums, int k) {
        
    	int n=nums.length;
    	int[] dp=new int[n];
    	int ans=Integer.MIN_VALUE;
    	PriorityQueue<node> q=new PriorityQueue<>();
    	
    	for(int i=0;i<n;i++) {
    		ans=Math.max(ans, nums[i]);
    		dp[i]=-10000;
    	}
   
    	for(int i=0;i<nums.length;i++) {
    		while(!q.isEmpty() && i-q.peek().id>k) q.poll();
    		if(!q.isEmpty()) dp[i]=q.peek().val+nums[i];
    		dp[i]=Math.max(dp[i], nums[i]);
    		q.add(new node(i,dp[i]));
    	}
    	
    	for(int i=0;i<n;i++)
    		ans=Math.max(ans, dp[i]);
    	
    	return ans;
    }
}
原创文章 1111 获赞 194 访问量 25万+

猜你喜欢

转载自blog.csdn.net/haut_ykc/article/details/105766202