LeetCode Weekly Contest 22

1. 532. K-diff Pairs in an Array

分析:由于要唯一,所以要去重,考虑k=0,时候,相同的数字需要个数大于1,所以,先用map统计个数,对于k=0,特判,对于其他的,遍历每一个数,只需要判断a + k是否存在即可。

这个题目,是absolute difference,我没注意这点,没有判断k<0,直接return 0,导致出错。

 1 class Solution {
 2 public:
 3 int findPairs(vector<int>& nums, int k) {
 4     if(k < 0) return 0;
 5     int n = nums.size();
 6     int res = 0;
 7     map<int, int> ma;
 8     for (int x : nums) {
 9         ma[x]++;
10     }
11     if(k == 0) {
12         for (auto it : ma) {
13             if(it.second > 1) res++;
14         }
15         return res;
16     }
17     for (auto it : ma) {
18         int x = it.first;
19         if(ma.count(x + k)) res++;
20     }
21     return res;
22 }
23 };
View Code

2. 531. Lonely Pixel I

预处理出行列元素个数,然后扫描每一个元素进行处理,比较简单。

 1 class Solution {
 2 public:
 3 int findLonelyPixel(vector<vector<char>>& p) {
 4     int n = p.size();
 5     if(n == 0) return 0;
 6     int m = p[0].size();
 7     if(m == 0) return 0;
 8     vector<int> row(n, 0), col(m, 0);
 9     for (int i = 0; i < n; i++) {
10         for (int j = 0; j < m; j++) {
11             if(p[i][j] == 'B') {
12                 row[i]++;
13                 col[j]++;
14             }
15         }
16     }
17     int res = 0;
18     for (int i = 0; i < n; i++) {
19         for (int j = 0; j < m; j++) {
20             if(p[i][j] == 'B') {
21                 if(row[i] == 1 && col[j] == 1) res++;
22             }
23         }
24     }
25     return res;
26 }
27 };
View Code

3. 533. Lonely Pixel II

也是要先预处理出每行,每列的b的个数,然后进行处理。

分析这个题目,是要按列进行考虑的,因为满足要求的b的列的位置上为b的这些行要相同,所以如果只要有一个不满足要求,这一列的b都是不满足要求的。

同时注意到,每2行可能需要比较多次,每次都是相同重复的,可以记录下来,进行加速处理。也算比较简单。

 1 class Solution {
 2 public:
 3  int findBlackPixel(vector<vector<char>>& p, int k) {
 4     int n = p.size();
 5     if(n == 0) return 0;
 6     int m = p[0].size();
 7     if(m == 0) return 0;
 8     vector<int> row(n, 0), col(m, 0);
 9     for (int i = 0; i < n; i++) {
10         for (int j = 0; j < m; j++) {
11             if(p[i][j] == 'B') {
12                 row[i]++;
13                 col[j]++;
14             }
15         }
16     }
17     int res = 0;
18     map<pair<int, int>, bool> ma;
19     for (int j = 0; j < m; j++) {
20         if(col[j] != k) continue;
21         int id = -1;
22         bool f = 1;
23         for (int i = 0; i < n; i++) {
24             if(p[i][j] == 'B') {
25                 if(row[i] != k) {
26                     f = 0;break;
27                 }
28                 if(id == -1) id = i;
29                 else {
30                     if(ma.count({id, i})) {
31                         if(!ma[{id, i}]) {
32                             f = 0;
33                             break;
34                         }
35                     }
36                     for (int x = 0; x < m; x++) {
37                         if(p[id][x] != p[i][x]) {
38                             ma[{id, i}] = 0;
39                             f = 0;
40                             break;
41                         }
42                     }
43                     if(f) {
44                         ma[{id, i}] = 1;
45                     } else
46                     break;
47                 }
48             }
49         }
50         if(f) res += k;
51     }
52     return res;
53 }
54 };
View Code

4. 514. Freedom Trail

分析:读懂题意,这么多英文描述,我一看,脑袋都花了!

然后,我想着是不是贪心,每次都转移到最近的一个字母,但是提交以后,wa。然后观察例子,分析出是dp。

因为这一次的转移会影响下一次的转移,局部是最优的,但是不能保证全局最优,所以需要记录所有的状态,然后进行处理。

考虑合法的转移状态,注意非法的情况。还有,这题的数据范围很小,100,100的,如果是贪心,那也太小了,所以,一般是dp的可能性很大,最后dp的复杂度是100*100*100,可以在1s的实现内运行完毕。

 1 class Solution {
 2 public:
 3 int findRotateSteps(string ring, string key) {
 4     int n = ring.size();
 5     int m = key.size();
 6     if(n == 1) {
 7         return m;
 8     }
 9     vector<vector<int>> dp(m + 1, vector<int>(n + 1, -1));
10     dp[0][0] = 0;
11     for (int i = 1; i <= m; i++) {
12         char cur = key[i - 1];
13         for (int j = 0; j < n; j++) {
14             if(dp[i - 1][j] == -1) continue;
15             for (int x = 0; x < n; x++) {
16                 if(ring[x] == cur) {
17                     int y = abs(x - j);
18                     if(n - y < y) y = n - y;
19                     if(dp[i][x] == -1)
20                         dp[i][x] = dp[i - 1][j] + y;
21                     else
22                         dp[i][x] = min(dp[i][x], dp[i - 1][j] + y);
23                 }
24                 //cout << j << " " << x << " " << i << " "<< dp[i][x] << endl;
25             }
26         }
27     }
28     int res = INT_MAX;
29     for (int i = 0; i < n; i++)
30         if(dp[m][i] != -1)
31         res = min(res, dp[m][i]);
32     return res + m;
33 }
34 };
View Code

要求最小值,dp非法值处理的-1的情况,代码写的比较复杂,应该处理成INT_MAX,这样非法情况可以像正常情况一样处理,但是要注意溢出哦,可以取一个很大的数,而不是INT_MAX就行了。

这次题目不是很难,但是我写的还是比较慢!还需要多练!

原文地址:https://www.cnblogs.com/y119777/p/6519873.html