题目链接: Leetcode Weekly Contest 228
写在前面:
今天是正月初三,情人节单身狗只能打打周赛这样子,这次第一题相邻好久没做出来,第二题一开始数据溢出也WA,差点爆零的一次周赛。
1、1758. Minimum Changes To Make Alternating Binary String
难度:Easy
题目大意:
判断至少经过几次操作能将二进制字符串转化成交替二进制字符串。
思路:
参考高赞回答,最后只有两种可能的结果,010101……或101010……,求将字符串转化成这两种结果所需的操作次数,取最小值即可。
代码
class Solution {
public int minOperations(String s) {
//最后只有两种可能的结果,010101……或101010……
int res=0,n=0;
for(int i=0;i<s.length();i++){
if(s.charAt(i)-'0'!=i%2){//转化成成010101……
n++;
}
}
res=Math.min(n,s.length()-n);//s.length-n表示转化成101010……需要的操作数
return res;
}
}
2、1759. Count Number of Homogenous Substrings
难度:Medium
题目大意:
求一个字符串里有多少个同质的字串(字符串的所有字符都相等)。
思路:
遍历字符串,统计连续相同字符的个数。注意数据类型用long,用int会溢出。
代码
class Solution {
public int countHomogenous(String s) {
int M=1000000007;
char[] arr=s.toCharArray();
long ans=0;//用int会溢出
for(int i=0;i<arr.length;){
long n=1;//统计连续相同字符的个数,用int会溢出
while(i+1<arr.length&&arr[i+1]==arr[i]){
n++;
i++;
}
//ans=(ans%M+(((n%M)*((n+1)%M)%M)/2)%M)%M;
ans=(ans%M+(n*(n+1)/2)%M)%M;
i++;
}
return (int)ans;
}
}
3、1760. Minimum Limit of Balls in a Bag
难度:Medium
题目大意:
给出若干个背包中的小球数,每次操作可以将一个背包中的小球分到两个新的背包中(如7=3+4),最多可以操作maxOperations次,求操作后各个背包中小球数最大值的最小值。
思路:
参考高赞回答,若背包中有a个小球,要使得各个背包中小球数不超过m个所需要的操作次数为(a-1)/m。对m进行二分搜索,求特定m所需的操作数,与题目给定的最多操作数进行比较,如何对m进行调整,知道找到合适的m为止。
代码
class Solution {
public int minimumSize(int[] nums, int maxOperations) {
int left=1,right=1000000000;
while(left<right){
int mid=(left+right)/2;
int count=0;
for(int n:nums){
count+=(n-1)/mid;
}
if(count>maxOperations){
left=mid+1;
}
else{
right=mid;
}
}
return left;
}
}
4、1761. Minimum Degree of a Connected Trio in a Graph
难度:Hard
题目大意:
求一个图中联通三元组的最小度数。
思路
参考高赞回答,因为图的节点数比较少,直接暴力求解,用HashMap来记录每个节点有几条边,用二维数组来记录两个节点是否联通。
代码
class Solution {
public int minTrioDegree(int n, int[][] edges) {
int res=Integer.MAX_VALUE;
Map<Integer,Integer> map=new HashMap<>();//统计几个节点有几条边
boolean isEdge[][]=new boolean[n+1][n+1];//isEdge[i][j]表示i和j是否为联通节点
for(int[] edge:edges){
map.put(edge[0],map.getOrDefault(edge[0],0)+1);
map.put(edge[1],map.getOrDefault(edge[1],0)+1);
isEdge[edge[0]][edge[1]]=true;
isEdge[edge[1]][edge[0]]=true;
}
for(int[] edge:edges){
for(int i=1;i<=n;i++){
if(isEdge[i][edge[0]]&&isEdge[i][edge[1]]){//如果i,edge[0],edge[1]构成联通三元组
int degree=map.get(i)+map.get(edge[0])+map.get(edge[1])-6;
res=Math.min(res,degree);
}
}
}
if(res==Integer.MAX_VALUE){
res=-1;
}
return res;
}
}