刷题记录 3

7.14

42. 接雨水 - 力扣(LeetCode)

REVIEW

双指针dp 说真的想不到能这样dp 左dp一遍最高右遍历一遍最高

1
2
3
4
5
6
7
8
9
10
class Solution {
public int trap(int[] height) {
int []dpL=new int[height.length],dpR = new int[height.length];
int ans = 0;dpL[0] = height[0];dpR[height.length-1] = height[height.length-1];
for(int i=1;i<height.length;i++) dpL[i]=Math.max(dpL[i-1],height[i]);
for(int i=height.length-2;i>=0;i--) dpR[i]=Math.max(dpR[i+1],height[i]);
for(int i=0;i<height.length;i++) ans+=Math.min(dpL[i],dpR[i])-height[i];
return ans;
}
}

还有更优的双指针加dp解法 因为两个dp都只用维护一个最大值 证明公式后可以用双指针dp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public int trap(int[] height) {
int ans = 0, leftMax = height[0], rightMax=height[height.length-1], left = 0 ,right = height.length-1;
while(left<=right){
leftMax = Math.max(leftMax,height[left]);
rightMax = Math.max(rightMax,height[right]);
if(leftMax<rightMax){
ans+=leftMax-height[left];
left++;
}else{
ans+=rightMax-height[right];
right--;
}
}
return ans;
}
}

135. 分发糖果 - 力扣(LeetCode)

和上题差不多的左右两次dp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public int candy(int[] ratings) {
int []dpL=new int[ratings.length],dpR = new int[ratings.length];
int ans =0 ; dpL[0] = 1;dpR[ratings.length-1]=1;
for(int i=1;i<ratings.length;i++){
if(ratings[i]>ratings[i-1])
dpL[i] = dpL[i-1]+1;
else
dpL[i]=1;
}
for(int i=ratings.length-2;i>=0;i--){
if(ratings[i]>ratings[i+1])
dpR[i] = dpR[i+1]+1;
else
dpR[i]=1;
}
for(int i=0;i<ratings.length;i++){
ans += Math.max(dpR[i],dpL[i]);
}
return ans;
}
}

739. 每日温度 - 力扣(LeetCode)

第一次做单调栈 执行时间有点惨哦 227ms

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
Stack<Integer> index = new Stack<>(),value = new Stack<>();
int []ans = new int[temperatures.length];
for(int i=0;i<temperatures.length;i++){
while(!value.empty()&&temperatures[i]>value.peek()){
int t_index = index.pop();
ans[t_index] = i-t_index;
value.pop();
}
value.push(temperatures[i]);
index.push(i);
}
return ans;
}
}

稍微改了一下 用了一个数组栈 168ms

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
Stack<int[]> index = new Stack<>();
int []ans = new int[temperatures.length];
for(int i=0;i<temperatures.length;i++){
while(!index.empty()&&temperatures[i]>index.peek()[0]){
int[] t_index = index.pop();
ans[t_index[1]] = i-t_index[1];
}
index.push(new int[]{temperatures[i],i});
}
return ans;
}
}

哦牛皮 原来别人比我快了将近7倍只是因为他们用了Deque是吧 那是真的牛皮 23ms

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
Deque<int[]> index = new ArrayDeque<>();
int []ans = new int[temperatures.length];
for(int i=0;i<temperatures.length;i++){
while(!index.isEmpty()&&temperatures[i]>index.peek()[0]){
int[] t_index = index.pop();
ans[t_index[1]] = i-t_index[1];
}
index.push(new int[]{temperatures[i],i});
}
return ans;
}
}

7.15

1768. 交替合并字符串 - 力扣(LeetCode)

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public String mergeAlternately(String word1, String word2) {
StringBuilder ans = new StringBuilder();
int len1 = word1.length(),len2 = word2.length();
for(int i=0;i<Math.min(len1,len2);i++){
ans.append(word1.charAt(i));
ans.append(word2.charAt(i));
}
if(len1<len2) ans.append(word2.substring(len1));
else if(len2<len1) ans.append(word1.substring(len2));
return ans.toString();
}
}

1071. 字符串的最大公因子 - 力扣(LeetCode)

REVIEW

这是简单题?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public String gcdOfStrings(String str1, String str2) {
int len1 = str1.length(),len2 = str2.length();
for(int i=Math.min(len1,len2);i>=1;i--){
if(len1%i==0&&len2%i==0){
String s = str1.substring(0,i);
if(check(str1,s)&&check(str2,s)) return s;
}
}
return "";
}
public boolean check(String s1,String s2){
int len = s1.length()/s2.length();
return s2.repeat(len).equals(s1);
}
}

辗转相除法(gcd)优化 数学证明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public String gcdOfStrings(String str1, String str2) {
if (!str1.concat(str2).equals(str2.concat(str1))) {
return "";
}
return str1.substring(0, gcd(str1.length(), str2.length()));
}

public int gcd(int a, int b) {
int remainder = a % b;
while (remainder != 0) {
a = b;
b = remainder;
remainder = a % b;
}
return b;
}
}

1431. 拥有最多糖果的孩子 - 力扣(LeetCode)

三目运算符好像比Math.max快?

1
2
3
4
5
6
7
8
9
class Solution {
public List<Boolean> kidsWithCandies(int[] candies, int extraCandies) {
List<Boolean> ans = new ArrayList<>();
int max = -1;
for(int candy:candies) max = max>candy?max:candy;
for(int candy:candies) ans.add(candy+extraCandies>=max);
return ans;
}
}

605. 种花问题 - 力扣(LeetCode)

要注意边界条件的处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public boolean canPlaceFlowers(int[] flowerbed, int n) {
if(n==0) return true;
if(flowerbed.length==1) return flowerbed[0]!=1;
int ans = 0;
if(flowerbed[0]==0&&flowerbed[1]==0) flowerbed[0]=-1;
for(int i=1;i<flowerbed.length;i++){
if(flowerbed[i]==0){
if(flowerbed[i-1]==-1) {
ans++;
if(ans>=n) return true;
}
else if (flowerbed[i-1]==0) flowerbed[i]=-1;
}
}
if(flowerbed[flowerbed.length-1]==-1) ans++;
return ans>=n;
}
}

345. 反转字符串中的元音字母 - 力扣(LeetCode)

又一次提醒我用set和hashmap会有多慢

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public String reverseVowels(String s) {
//Set<Character> set = new HashSet<>(List.of(new Character[]{'a', 'e', 'i', 'o', 'u','A', 'E', 'I', 'O', 'U'}));
int [] indexes = new int[s.length()];
int index = 0;
StringBuilder chars = new StringBuilder(s);
for(int i=0;i<s.length();i++)
//if(set.contains(chars.charAt(i)))
if(isVowel(chars.charAt(i))){
indexes[index] = i;
index++;
}
char ch;
for(int i=0;i<index/2;i++){
ch = chars.charAt(indexes[i]);
chars.setCharAt(indexes[i],chars.charAt(indexes[index-i-1]));
chars.setCharAt(indexes[index-i-1],ch);
}
return chars.toString();
}
private boolean isVowel(char ch) {
return ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u' || ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U';
}
}

哎 我想了一下用双指针应该更快点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public String reverseVowels(String s) {
char [] chars = s.toCharArray();
int l=0,r = s.length()-1;
while(l<r){
boolean flag1 = isVowel(chars[l]),flag2 = isVowel(chars[r]);
if(flag1&&flag2){
swap(chars,l,r);l++;r--;
}else if(flag1) r--;
else if (flag2) l++;
else {r--;l++;}
}
return String.valueOf(chars);
}
private boolean isVowel(char ch) {
return ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u' || ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U';
}
private void swap(char[] cs, int l, int r) {
char c = cs[l];
cs[l] = cs[r];
cs[r] = c;
}
}

3ms -> 2ms

334. 递增的三元子序列 - 力扣(LeetCode)

我想的是记录最大最小值, 结果普通地记录最小次小值就好了…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//最大最小
class Solution {
public boolean increasingTriplet(int[] nums) {
int []dpL=new int[nums.length],dpR= new int[nums.length];
int min = Integer.MAX_VALUE,max = Integer.MIN_VALUE;
for(int i=0;i<nums.length;i++) {
min = Math.min(nums[i], min);
dpL[i] = min;
}
for(int i=nums.length-1;i>=0;i--) {
max = Math.max(nums[i], max);
dpR[i] = max;
if(nums[i]>dpL[i]&&nums[i]<dpR[i]) return true;
}
return false;
}
}

//最小次小
class Solution {
public boolean increasingTriplet(int[] nums) {
int min = nums[0],bigMin = Integer.MAX_VALUE;
for(int num:nums){
if(num>min&&num<bigMin) bigMin=num;
else if(min>num) min = num; //这里bigMin不用重新赋值 因为大于bigMin肯定大于之前的min
else if(num>bigMin) return true;
}
return false;
}
}

443. 压缩字符串 - 力扣(LeetCode)

这种题除了各种条件判断写着烦没别的了 一点乐趣也没有

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Solution {
public int compress(char[] chars) {
int fast = 0,slow = fast,ansLen=0;
while(fast<chars.length){
int len = 1;
char ch = chars[fast++];
while(fast<chars.length&&ch==chars[fast]){
fast++;len++;
}
if(len==1){
chars[slow++]=ch;ansLen++;
}else if(len<10){
chars[slow++]=ch;chars[slow++]= (char) (len+'0');ansLen+=2;
}else{
chars[slow++]=ch;ansLen++;
String str = String.valueOf(len);
char [] cLen = str.toCharArray();
for(char c:cLen){
chars[slow++]=c;ansLen++;
}
}
}
return ansLen;
}
}

7.17

1679. K 和数对的最大数目 - 力扣(LeetCode)

快排加双指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public int maxOperations(int[] nums, int k) {
Arrays.sort(nums);
int ans = 0, l = 0, r = nums.length-1;
while(l<r){
if(nums[l]+nums[r]==k) {
ans++;++l;--r;
}else if(nums[l]+nums[r]<k){
++l;
}else{
--r;
}
}
return ans;
}
}

改了一下快了2ms 据我分析应该是因为不等于k的情况比等于k的情况多很多 所以每次循环少了不少判断 还有用num记录nums[l]+nums[r] 这样就只用计算一次相加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public int maxOperations(int[] nums, int k) {
Arrays.sort(nums);
int ans = 0, l = 0, r = nums.length-1;
while(l<r){
int num = nums[l]+nums[r];
if(num<k) {
++l;
}else if(num>k){
--r;
}else{
ans++;++l;--r;
}
}
return ans;
}
}

1456. 定长子串中元音的最大数目 - 力扣(LeetCode)

第一次提交的时候看错题了( ̄_ ̄|||)

先计算前k个字符串然后dp ans等于k时就返回结果减少计算量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public int maxVowels(String s, int k) {
int []dp = new int[s.length()];
char [] chars = s.toCharArray();
int ans = 0, len = s.length();
dp[0] = isTarget(chars[0])?1:0;
for(int i=1;i<k;i++){
dp[i]= isTarget(chars[i])?dp[i-1]+1:dp[i-1];
}ans = Math.max(ans,dp[k-1]);
if(ans==k)return k;
for(int i=k;i<len;i++){
int num = dp[i-1]- (isTarget(chars[i-k])?1:0);
dp[i]= isTarget(chars[i])?num +1:num;
ans = Math.max(ans,dp[i]);
if(ans==k)return k;
}
return ans;
}

private boolean isTarget(char ch){
return ch=='a'||ch=='e'||ch=='i'||ch=='o'||ch=='u';
}
}

看别人的代码又学到一招 真是为了优化无所不用其极啊 用数组存储元音字母 判断速度更快 11ms -> 5ms

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Solution {
public static final int[] cnt = new int[128];
static{
Arrays.fill(cnt,0);
cnt['a'] = 1;
cnt['e'] = 1;
cnt['i'] = 1;
cnt['o'] = 1;
cnt['u'] = 1;
}
public int maxVowels(String s, int k) {
int []dp = new int[s.length()];
char [] chars = s.toCharArray();
int ans = 0, len = s.length();
dp[0] = cnt[chars[0]];
for(int i=1;i<k;i++){
dp[i]= dp[i-1]+cnt[chars[i]];
}ans = Math.max(ans,dp[k-1]);
if(ans==k)return k;
for(int i=k;i<len;i++){
int num = dp[i-1]- cnt[chars[i-k]];
dp[i]= num + cnt[chars[i]];
ans = Math.max(ans,dp[i]);
if(ans==k)return k;
}
return ans;
}
}

再进一步! 因为这个dp只用记录最大值 所以可以用一个滑动窗口的最大值代替dp数组 dp 不需要了 5ms -> 4ms

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public int maxVowels(String s, int k) {
int []cnt = new int[128];
cnt['a'] = 1;
cnt['e'] = 1;
cnt['i'] = 1;
cnt['o'] = 1;
cnt['u'] = 1;
char [] chars = s.toCharArray();
int ans = 0, len = s.length();
ans += cnt[chars[0]];
for(int i=1;i<k;i++){
ans += cnt[chars[i]];
}
if(ans==k)return k;
int sum = ans;
for(int i=k;i<len;i++){
sum += - cnt[chars[i-k]] + cnt[chars[i]];
ans = Math.max(ans,sum);
if(ans==k)return k;
}
return ans;
}
}

643. 子数组最大平均数 I - 力扣(LeetCode)

和上题差不多的滑动窗口 简单但是优化空间似乎很大?

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public double findMaxAverage(int[] nums, int k) {
double ans , sum = 0;
for(int i=0;i<k;i++)
sum += nums[i];
ans = sum/k;
for(int i=k;i<nums.length;i++){
sum += -nums[i-k] + nums[i];
ans = Math.max(ans,sum/k);
}
return ans;
}
}

哦 阿西吧 没必要更新最大值的时候算平均数的 最后把最大和除一下就行 5ms->2ms

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public double findMaxAverage(int[] nums, int k) {
int ans,sum = 0,len = nums.length;
for(int i=0;i<k;i++)
sum += nums[i];
ans = sum/k;
for(int i=k;i<len;i++){
sum += -nums[i-k] + nums[i];
ans = Math.max(ans,sum);
}
return (double) ans /k;
}
}

7.18

1004. 最大连续1的个数 III - 力扣(LeetCode)

REVIEW

之前没写过这种滑动窗口长度可变的题 一开始写的时候用定长滑动窗口一直写不出来 看了题解发现其实很简单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public int longestOnes(int[] nums, int k) {
int len=nums.length,zero = 0,sum=0,ans=0,l=0;
for(int r=0;r<len;r++){
zero+=nums[r]==0?1:0;
sum+=nums[r];
while(zero>k){
l++;zero-=nums[l]==0?1:0;sum-=nums[l];
}
ans=Math.max(ans,zero+sum);
}
return ans;
}
}

1493. 删掉一个元素以后全为 1 的最长子数组 - 力扣(LeetCode)

跟上题思路差不多的可变滑动窗口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public int longestSubarray(int[] nums) {
int len=nums.length,zero = 0,sum=0,ans=0,l=0;
for(int r=0;r<len;r++){
zero+=nums[r]==0?1:0;
sum+=nums[r];
while(zero>1){
zero-=nums[l]==0?1:0;sum-=nums[l];l++;
}
ans=Math.max(ans,sum+zero-1);
}
return ans;
}
}

优化: 不需要维护sum 三元运算符换成if判断更快

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public int longestSubarray(int[] nums) {
int len=nums.length,zero = 0,ans=0,l=0;
for(int r=0;r<len;r++){
if(nums[r]==0) ++zero;
while(zero>1){
if(nums[l++]==0) --zero;
}
ans=Math.max(ans,r-l);
}
return ans;
}
}

1732. 找到最高海拔 - 力扣(LeetCode)

1
2
3
4
5
6
7
8
9
10
11
class Solution {
public int largestAltitude(int[] gain) {
int len = gain.length,ans=0,h=0;
for(int i=1;i<=len;i++){
h+=gain[i-1];
ans=Math.max(ans,h);
}
return ans;
}
}

7.19

724. 寻找数组的中心下标 - 力扣(LeetCode)

维护一个前缀和一个后缀和 三次遍历 应该还有挺大优化空间的

1
2
3
4
5
6
7
8
9
10
class Solution {
public int pivotIndex(int[] nums) {
int len = nums.length;
int []left = new int[len],right = new int[len];
for(int i=1;i<len;i++) left[i]=left[i-1]+nums[i-1];
for(int i=len-2;i>=0;i--) right[i]=right[i+1]+nums[i+1];
for(int i=0;i<len;i++) if(left[i]==right[i])return i;
return -1;
}
}

原来如此 计算数组总和就行了 维护前后缀和是在计算复杂的时候(比如乘除之类的)才用

1
2
3
4
5
6
7
8
9
10
11
class Solution {
public int pivotIndex(int[] nums) {
int sum = 0,curSum=0;
for(int num:nums) sum+=num;
for(int i=0;i<nums.length;i++){
curSum+=nums[i];
if(sum-curSum==curSum-nums[i]) return i;
}
return -1;
}
}

1207. 独一无二的出现次数 - 力扣(LeetCode)

用了两个set 本来以为时间会很烂…结果击败了79.5% 其实还好…?

1
2
3
4
5
6
7
8
9
10
11
12
class Solution {
public boolean uniqueOccurrences(int[] arr) {
int [] nums = new int[2001];
Set<Integer> set1 = new HashSet<>(),set2=new HashSet<>();
for(int num:arr){++nums[num+1000];set1.add(num);}
for(Integer num:set1){
if(set2.contains(nums[num+1000])) return false;
set2.add(nums[num+1000]);
}
return true;
}
}

2215. 找出两数组的不同 - 力扣(LeetCode)

本来用了三个数组三次遍历以为时间会被暴打了 结果击败100%…?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public List<List<Integer>> findDifference(int[] nums1, int[] nums2) {
List<List<Integer>> ans = new ArrayList<>();
List<Integer> n1 = new ArrayList<>(),n2 = new ArrayList<>();
ans.add(n1);ans.add(n2);
boolean []set1 = new boolean[2001], set2 = new boolean[2001], set3 = new boolean[2001];
for(int num:nums1) set1[num+1000] = true;
for(int num:nums2){
int n = num+1000;
if(!set1[n]&&!set2[n]) n2.add(num);
set2[n] = true;
}
for(int num:nums1){
int n = num+1000;
if(!set2[n]&&!set3[n]) n1.add(num);
set3[n]=true;
}
return ans;
}
}

7.20

2390. 从字符串中移除星号 - 力扣(LeetCode)

REVIEW

还以为中等题会这么简单呢…一千多ms

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
public String removeStars(String s) {
StringBuilder stringBuilder = new StringBuilder(s);
int index=0;
while(index<stringBuilder.length()){
if(stringBuilder.charAt(index)=='*'){
stringBuilder.delete(index-1,index+1);
--index;
}else{
index++;
}
}
return stringBuilder.toString();
}
}

还是有点麻烦的 从后往前遍历会简单很多 碰到星号就维护一个星号数量 星号数量大于0时就遍历下去直到星号数量等于0 (12ms defeat 94%)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Solution {
public String removeStars(String s) {
char[] chars = s.toCharArray();
int len=s.length(),ansLen=len,ansIndex=0;
for(int i=len-1;i>=0;){
if(chars[i]=='*'){
int index=1,star=1;--i;
while(star>0){
if(chars[i]!='*'){
--star;chars[i]='*';
}else{
++star;
}i--;++index;
}ansLen-=index;
}else i--;
}
char [] ans = new char[ansLen];
for(int i=0;i<len;i++){
if(chars[i]!='*'){
ans[ansIndex++]=chars[i];
}
}
return String.valueOf(ans);
}
}

我去 居然还有这种简单的写法 虽然时间不如上面的写法但是真的简单啊 效率的选择

因为是设置长度所以不用删除 耗时减少了很多 22ms

1
2
3
4
5
6
7
8
9
10
class Solution {
public String removeStars(String s) {
StringBuilder sb=new StringBuilder();
for(char c: s.toCharArray()){
if(c=='*') sb.setLength(sb.length() - 1);
else sb.append(c);
}
return sb.toString();
}
}

原来这题的标签是栈… 没想到栈的解法 是我的问题

2352. 相等行列对 - 力扣(LeetCode)

写出来就知道会慢了 34.47%其实还行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public int equalPairs(int[][] grid) {
Map<String, Integer> mapR = new HashMap<>();
int n=grid.length,ans=0;
for (int[] R : grid) {
String str = Arrays.toString(R);
mapR.put(str,mapR.getOrDefault(str, 0)+1);
}
for(int i=0;i<n;i++){
int [] L = new int[n];
for (int k=0;k<n;k++) L[k]=grid[k][i];
String str = Arrays.toString(L);
ans+= mapR.getOrDefault(str, 0);
}
return ans;
}
}

也不知道是为什么 用了List之后快了将近一倍 18ms

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public int equalPairs(int[][] grid) {
Map<List<Integer>, Integer> mapR = new HashMap<>();
int n=grid.length,ans=0;
for (int[] R : grid) {
List<Integer> list = new ArrayList<>();
for(int num:R) list.add(num);
mapR.put(list,mapR.getOrDefault(list, 0)+1);
}
for(int i=0;i<n;i++){
List<Integer> list = new ArrayList<>();
for (int k=0;k<n;k++) list.add(grid[k][i]);
ans+= mapR.getOrDefault(list, 0);
}
return ans;
}
}

看到一个妙解 转置矩阵之后对比每行 10ms

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {

//转置矩阵
public int equalPairs(int[][] grid) {
int n = grid.length;
int[][] arr = new int[n][n];
int count = 0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
arr[i][j] = grid[j][i];
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(Arrays.equals(grid[i],arr[j])){
count++;
}
}
}
return count;

}
}

1657. 确定两个字符串是否接近 - 力扣(LeetCode)

80.44% 还行 就是代码有点臃肿了

记录字符出现次数的次数 还要注意两个word的字符种类是相同的 只要每种字符出现的次数能跟另一个word一一对应就行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public boolean closeStrings(String word1, String word2) {
if(word1.length()!=word2.length()) return false;
Map<Integer,Integer> map1 = new HashMap<>(),map2 = new HashMap<>();
int []nums1 = new int[26],nums2=new int[26];
char [] chars1 = word1.toCharArray(),chars2 = word2.toCharArray();
for(int i=0;i<word1.length();i++){
++nums1[chars1[i]-'a'];++nums2[chars2[i]-'a'];
}for(int i=0;i<26;i++){
if((nums1[i]==0&&nums2[i]!=0)||(nums2[i]==0&&nums1[i]!=0)) return false;
if(nums1[i]!=0){
map1.put(nums1[i],map1.getOrDefault(nums1[i],0)+1);
map2.put(nums2[i],map2.getOrDefault(nums2[i],0)+1);
}
}
for(Integer num:map1.keySet()){
if(!map2.containsKey(num)|| !Objects.equals(map1.get(num), map2.get(num))) return false;
}
return true;
}
}