题目链接: Leetcode Weekly Contest 244
写在前面:
本次周赛做出了前两题。
1、1886. Determine Whether Matrix Can Be Obtained By Rotation
难度:Easy
题目大意:
判断能否将一个二维方阵经过若干次顺时针旋转90度后变成另外一个矩阵。
思路:
找到方阵顺时针旋转90度后与原来方阵的关系即可。
代码
class Solution {
public boolean findRotation(int[][] mat, int[][] target) {
for(int i=0;i<4;i++){
if(equal(mat,target)){
return true;
}
rotate(mat);
}
return false;
}
public void rotate(int[][] mat){
int n=mat.length;
int[][] arr=new int[n][n];
for(int i=0;i<n;i++){//复制矩阵
for(int j=0;j<n;j++){
arr[i][j]=mat[i][j];
}
}
for(int i=0;i<n;i++){//顺时针旋转90度
for(int j=0;j<n;j++){
mat[i][j]=arr[n-1-j][i];
}
}
}
public boolean equal(int[][] mat,int[][] target){
int n=mat.length;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(mat[i][j]!=target[i][j]){
return false;
}
}
}
return true;
}
}
2、1887. Reduction Operations to Make the Array Elements Equal
难度:Medium
题目大意:
每次操作可以将数组中的一个最大值变成次大值,求经过几次操作可以将数组中的所有元素变成一样。
思路:
统计数组中每个元素的出现次数,如何模拟即可。
代码
class Solution {
public int reductionOperations(int[] nums) {
Map<Integer,Integer> map=new HashMap<>();
Queue<Integer> pq=new PriorityQueue<>((a,b)->b-a);
for(int n:nums){
map.put(n,map.getOrDefault(n,0)+1);
}
for(Integer key:map.keySet()){
pq.offer(key);
}
int res=0;
while(!pq.isEmpty()){
int largest=pq.poll();
if(pq.isEmpty()){
return res;
}
int nextLargest=pq.peek();
int option=map.get(largest);
res+=option;
map.put(largest,0);//所有的最大值变成次大值
map.put(nextLargest,map.get(nextLargest)+option);
}
return res;
}
}
3、1888. Minimum Number of Flips to Make the Binary String Alternating
难度:Medium
题目大意:
详见题目。
思路:
参考高赞回答。将两个字符串拼接,然后使用滑动窗口来统计不同字符的个数。
代码
class Solution {
public int minFlips(String s) {
s=s+s;
char[] arr=s.toCharArray();
int n=s.length();
char[] s1=new char[n];
char[] s2=new char[n];
for(int i=0;i<n;i++){
if(i%2==0){
s1[i]='1';
s2[i]='0';
}
else{
s1[i]='0';
s2[i]='1';
}
}
int res=Integer.MAX_VALUE,diff1=0,diff2=0;
for(int i=0;i<n;i++){
if(arr[i]!=s1[i]){
diff1++;
}
if(arr[i]!=s2[i]){
diff2++;
}
if(i>=n/2){//滑动窗口,左边的值出去,右边的值进来
if(arr[i-n/2]!=s1[i-n/2]){
diff1--;
}
if(arr[i-n/2]!=s2[i-n/2]){
diff2--;
}
}
if(i>=n/2-1){
res=Math.min(res,Math.min(diff1,diff2));
}
}
return res;
}
}
4、1889. Minimum Space Wasted From Packaging
难度:Hard
题目大意:
详见题目。
思路
参考高赞回答,将背包和每个供应商的箱子都按容量升序排列, 遍历每个供应商中的每一个箱子,将体积小于等于箱子的背包都装入这个箱子中,这个过程可以用二分查找。
代码
class Solution {
public int minWastedSpace(int[] packages, int[][] boxes) {
int n=packages.length,m=boxes.length;
Arrays.sort(packages);
int largest=packages[n-1];//最大背包大小
long res=10000000000L;
boolean flag=false;//是否有解
long pSpace=0;
for(int a:packages){
pSpace+=a;
}
for(int i=0;i<m;i++){
int len=boxes[i].length;
Arrays.sort(boxes[i]);
if(boxes[i][len-1]<largest){
continue;
}
flag=true;
long boxesSpace=0;
int l=0;
for(int b:boxes[i]){
int r=binarySearch(packages,b);//packages[l,r-1]都能被容量为b的box装下
if(r==-1){//packages[]中找不到比b大的元素,说明所有的背包都能被容量为b的box装下
r=n;
}
boxesSpace+=(r-l)*(long)b;//注意把b转化成long类型,不然会溢出
l=r;
}
res=Math.min(res,boxesSpace);
}
if(flag){
return (int)((res-pSpace)%1000000007);
}
return -1;
}
public int binarySearch(int[] nums,int target){
//寻找数组中>target的最小下标元素,数组升序排列
int l=0,r=nums.length-1;
while(l<r){
int m=(l+r)/2;
//如果r=m-1,m向上取整,如果l=m+1,r向下取整。
if(nums[m]>target){
r=m;
}
else{
l=m+1;
}
}
if(nums[l]<=target){
return -1;
}
return l;
}
}