第一题:
分别维护每行每列添加的总和,最后加起来统计即可。
class Solution {
public int oddCells(int n, int m, int[][] indices) {
int ans=0;
int[] r=new int[n];
int[] c=new int[m];
for(int[] temp:indices){
r[temp[0]]++;
c[temp[1]]++;
}
for(int i=0;i<n;i++) {
for(int j=0;j<m;j++) {
if((r[i]+c[j])%2==1)
ans++;
}
}
return ans;
}
}
第二题:
直接构造。
public class Solution {
public List<List<Integer>> reconstructMatrix(int upper, int lower, int[] sum) {
int n=sum.length;
int s=0;
for(int i=0;i<n;i++)
s+=sum[i];
if(upper+lower!=s) {
return new ArrayList<List<Integer>>();
}
int[][] buf=new int[2][n];
for(int i=0;i<n;i++) {
if(upper>=sum[i]) {
buf[0][i]=sum[i];
upper-=sum[i];
}
else {
buf[0][i]=upper;
sum[i]-=upper;
upper=0;
buf[1][i]=sum[i];
lower-=sum[i];
}
}
ArrayList<Integer>[] temp=new ArrayList[2];
for(int i=0;i<2;i++)
temp[i]=new ArrayList<Integer>();
for(int i=0;i<2;i++) {
for(int j=0;j<n;j++)
temp[i].add(buf[i][j]);
}
List<List<Integer>> ans=new ArrayList<List<Integer>>();
ans.add(temp[0]);
ans.add(temp[1]);
return ans;
}
}
第三题:
并查集维护联通块,显然这些联通块要么处于边界,要么为题中定义的“孤岛”。
public class Solution {
public int[] pre;
public int find(int x) {
int temp=x;
while(temp!=pre[temp])
temp=pre[temp];
int i=x,j;
while(i!=temp) {
j=pre[i];
pre[i]=temp;
i=j;
}
return temp;
}
public void join(int x,int y) {
int a=find(x);
int b=find(y);
if(a!=b)
pre[a]=b;
}
public int getID(int i,int j,int n) {
return i*n+j;
}
public int closedIsland(int[][] g) {
int n=g.length;
int m=g[0].length;
pre=new int[n*m];
for(int i=0;i<n*m;i++)
pre[i]=i;
for(int i=0;i<n;i++) {
for(int j=0;j<m;j++) {
if(g[i][j]==0) {
if(i-1>=0&&g[i-1][j]==0)
join(getID(i,j,m),getID(i-1,j,m));
if(j-1>=0&&g[i][j-1]==0)
join(getID(i,j,m),getID(i,j-1,m));
if(i+1<n&&g[i+1][j]==0)
join(getID(i,j,m),getID(i+1,j,m));
if(j+1<n&&g[i][j+1]==0)
join(getID(i,j,m),getID(i,j+1,m));
}
}
}
HashMap<Integer,ArrayList<Integer>> map=new HashMap<Integer,ArrayList<Integer>>();
HashSet<Integer> set=new HashSet<Integer>();
for(int i=0;i<n*m;i++) {
if(g[i/m][i%m]==0) {
ArrayList<Integer> temp=map.getOrDefault(find(i), new ArrayList<Integer>());
temp.add(i);
map.put(find(i), temp);
}
}
int ans=0;
for(Map.Entry<Integer, ArrayList<Integer>> temp:map.entrySet()) {
boolean flag=true;
for(int v:temp.getValue()) {
if(v/m==0||v%m==0||v/m==n-1||v%m==m-1) {
flag=false;
break;
}
}
if(flag)
ans++;
}
return ans;
}
}
第四题:
起初看起来像是一个01揹包,但发现好像不好列状态,但后来发现数据范围很小,可以二进制枚举暴力通过。
public class Solution {
public int maxScoreWords(String[] words, char[] letters, int[] score) {
int n=words.length;
int ans=0;
int[] cnt=new int[26];
for(char c:letters) {
cnt[c-'a']++;
}
int[] val=new int[n];
int[][] c=new int[n][26];
for(int i=0;i<n;i++) {
for(char v:words[i].toCharArray()) {
val[i]+=score[v-'a'];
c[i][v-'a']++;
}
}
for(int i=0;i<(1<<n);i++) {
int[] buf=cnt.clone();
int temp=0;
for(int j=0;j<n;j++) {
if((i&(1<<j))!=0) {
boolean flag=true;
for(int k=0;k<26;k++) {
if(buf[k]<c[j][k]) {
flag=false;
break;
}
}
if(flag) {
temp+=val[j];
for(int k=0;k<26;k++) {
buf[k]-=c[j][k];
}
}
}
}
ans=Math.max(ans, temp);
}
return ans;
}
}