2.1 lc.1763 最长的美好子字符串
- 滑动窗口
class Solution {
public:
string longestNiceSubstring(string s) {
int maxPos = 0, maxLen = 0;
auto check = [&](int typeNum) {
vector<int> lowerCnt(26);
vector<int> upperCnt(26);
int cnt = 0;
for (int l = 0, r = 0, total = 0; r < s.size(); ++r) {
int idx = tolower(s[r]) - 'a';
if (islower(s[r])) {
++lowerCnt[idx];
if (lowerCnt[idx] == 1 && upperCnt[idx] > 0) {
++cnt;
}
} else {
++upperCnt[idx];
if (upperCnt[idx] == 1 && lowerCnt[idx] > 0) {
++cnt;
}
}
total += (lowerCnt[idx] + upperCnt[idx]) == 1 ? 1 : 0;
while (total > typeNum) {
idx = tolower(s[l]) - 'a';
total -= (lowerCnt[idx] + upperCnt[idx]) == 1 ? 1 : 0;
if (islower(s[l])) {
--lowerCnt[idx];
if (lowerCnt[idx] == 0 && upperCnt[idx] > 0) {
--cnt;
}
} else {
--upperCnt[idx];
if (upperCnt[idx] == 0 && lowerCnt[idx] > 0) {
--cnt;
}
}
++l;
}
if (cnt == typeNum && r - l + 1 > maxLen) {
maxPos = l;
maxLen = r - l + 1;
}
}
};
int mask = 0;
for (char & ch : s) {
mask |= 1 << (tolower(ch) - 'a');
}
int types = __builtin_popcount(mask);
for (int i = 1; i <= types; ++i) {
check(i);
}
return s.substr(maxPos, maxLen);
}
};
2.2 lc.2000 反转单词前缀
- 中间用 if 判断一下
class Solution {
public:
string reversePrefix(string word, char ch) {
int l = 0 , r = 0 ;
while(r < word.size()){
if(word[r] == ch) break;
r ++ ;
}
if(r == word.size()) return word ;
while(l < r){
swap(word[l] , word[r]);
l ++ ; r -- ;
}
return word ;
}
};
2.3 lc.1414 和为k的最少斐波那契数字数目
- 贪心小模拟
class Solution {
public:
int findMinFibonacciNumbers(int k) {
int cnt = 0 ;
while(k > 0){
int a = 1 , b = 1 ;
while(b <= k){
int tmp = b ;
b = b + a ;
a = tmp ;
}
k = k - a ;
cnt ++ ;
}
return cnt ;
}
};
2.4 lc.1725 可以形成最大正方形的矩形
- 贪心小模拟
class Solution {
public:
int countGoodRectangles(vector<vector<int>>& rectangles) {
int cnt , maxlen = 0 ;
for(int i = 0 ; i < rectangles.size() ; i ++){
int premax = 0 ;
if(rectangles[i][0] > rectangles[i][1]) premax = rectangles[i][1] ;
else premax = rectangles[i][0] ;
if(premax > maxlen) {
cnt = 1 ;
maxlen = premax ;
}
else if(premax == maxlen) cnt ++ ;
}
return cnt ;
}
};
初四也是 easy 呢。
2.5 lc.1219 黄金矿工
- DFS
class Solution {
public:
int ans = 0 ;
void dfs(int i, int j, int sum, vector<vector<int>>& grid){
int m = grid.size() , n = grid[0].size() ;
if(i < 0 || i >= m || j < 0 || j >= n || grid[i][j] == 0) return ;
int tmp = grid[i][j] ;
sum += tmp ;
ans = max (ans , sum) ;
grid[i][j] = 0 ;
dfs(i + 1 , j , sum , grid) ;
dfs(i - 1 , j , sum , grid) ;
dfs(i , j + 1 , sum , grid) ;
dfs(i , j - 1 , sum , grid) ;
sum -= tmp ;
grid[i][j] = tmp ;
}
int getMaximumGold(vector<vector<int>>& grid) {
int m = grid.size() , n = grid[0].size() ;
for(int i = 0 ; i < m ; i ++){
for(int j = 0 ; j < n ; j ++){
if(grid[i][j] > 0){
dfs(i, j, 0, grid) ;
}
}
}
return ans ;
}
};
确实这种简单的回溯没必要再搞 DIRECTION 和 BOOL 来做。
2.6 lc.1748 唯一元素的和
class Solution {
public:
int sumOfUnique(vector<int>& nums) {
int ans = 0 , len = nums.size() ;
sort(nums.begin() , nums.end()) ;
if(len == 1) return nums[0] ;
if(nums[1] != nums[0]) ans = nums[0] ;
if(nums[len - 1] != nums[len - 2]) ans += nums[len - 1] ;
for(int i = 1 ; i < len - 1 ; i ++){
if(nums[i] != nums[i - 1] && nums[i] != nums[i + 1]) ans += nums[i] ;
}
return ans ;
}
};
2.8 lc.1001 网格照明
- 模拟 WA
class Solution {
public:
void openvisit(int row , int col , int n , vector<vector<int>>& open){
for(int i = 0 ; i < n ; i ++){
int sum = row + col , dif = col - row;
open[row][i] = 1 ;
open[i][col] = 1 ;
int y1 = sum - i , y2 = i + dif;
if(y1 >= 0 && y1 < n) open[i][y1] = 1 ;
if(y2 >= 0 && y2 < n) open[i][y2] = 1 ;
}
} // 0 close, 1 light, 2 open
void closevisit(int row , int col , int n , vector<vector<int>>& open){
vector<vector<int>> direction = {{0,1},{0,-1},{1,0},{1,-1},{0,0},{1,1},{1,-1},{-1,1},{-1,-1}};
for(int i = 0 ; i < 9 ; i ++){
int pr = row + direction[i][0] , pc = col + direction[i][1] ;
if(pr >= 0 && pr < n && pc >= 0 && pc < n){
if(open[pr][pc] == 2) close(row , col , n , open) ;
}
}
}
void close(int row , int col , int n , vector<vector<int>>& open){
for(int i = 0 ; i < n ; i ++){
int sum = row + col , dif = col - row;
open[row][i] = 0 ;
open[i][col] = 0 ;
int y1 = sum - i , y2 = i + dif;
if(y1 >= 0 && y1 < n) open[i][y1] = 0 ;
if(y2 >= 0 && y2 < n) open[i][y2] = 0 ;
}
}
vector<int> gridIllumination(int n, vector<vector<int>>& lamps, vector<vector<int>>& queries) {
vector<int> ans ;
vector<vector<int>> open (n , vector<int>(n , 0)) ;
for(int i = 0 ; i < lamps.size() ; i ++){
int row = lamps[i][0] , col = lamps[i][1] ;
open[row][col] = 2 ;
openvisit(row , col , n , open);
}
for(int i = 0 ; i < queries.size() ; i ++){
int row = queries[i][0] , col = queries[i][1] ;
if(open[row][col] != 0) ans.emplace_back(1) ;
else ans.emplace_back(0) ;
closevisit(row , col , n , open);
}
return ans ;
}
};
一个位置只要亮了就是1,所以一个光源没了就不亮了,这个方法不成立。
写了不少时间,在写代码前进行算法分析还是有必要的。
- 行列两个对角线共开 4 个哈希表
class Solution {
public:
vector<int> gridIllumination(int n, vector<vector<int>>& lamps, vector<vector<int>>& queries) {
set<pair<int, int> > point;
map<int, int> r, c, d, rd;
for (int i = 0; i < lamps.size(); i++) {
int x = lamps[i][0], y = lamps[i][1];
if (point.find({x, y}) == point.end()) {
point.insert({x, y});
r[x]++;
c[y]++;
d[x - y]++;
rd[x + y]++;
}
}
vector<int> ans (queries.size());
for (int i = 0; i < queries.size(); i++) {
int x = queries[i][0], y = queries[i][1];
if (r[x] || c[y] || d[x - y] || rd[x + y])
ans[i] = 1;
else
ans[i] = 0;
for (int rx = -1; rx <= 1; rx++) {
for (int ry = -1; ry <= 1; ry++) {
int nx = x + rx, ny = y + ry;
if (point.find({ nx, ny}) != point.end()) {
cout << nx << ' ' << ny << endl;
point.erase({nx, ny});
r[nx]--;
c[ny]--;
d[nx - ny]--;
rd[nx + ny]--;
}
}
}
}
return ans;
}
};
2.9 lc.2006 差绝对值为K的数对数目
- sort + 二分查找
class Solution {
public:
int ans = 0 ;
void Findx(vector<int>& nums , int k , int x , int i){
int l = i , r = nums.size() - 1 ;
while(l < r){
int mid = l + r >> 1;
if(x <= nums[mid]) r = mid ;
else l = mid + 1 ;
}
while(l < nums.size()){
if(nums[l] == x) {
ans ++ ;
l ++;
}
else break ;
}
}
int countKDifference(vector<int>& nums, int k) {
int n = nums.size() ;
sort(nums.begin() , nums.end()) ;
for(int i = 0 ; i < n ; i ++){
int x = nums[i] + k ;
if(x > nums[n - 1]) break ;
Findx(nums , k , x , i);
}
return ans ;
}
};
ans 得注意每次迭代时值的迭代。
2.10 lc.1447 最简分数 int -> string: to_string
- 居然没超时
class Solution {
public:
bool huzhi(int j , int i){ // 判断两数是否互质 j 被除数 i 除数
for(int x = 2 ; x < i ; x ++){
if(i % x == 0 && j % x == 0) return false ;
}
return true ;
}
vector<string> simplifiedFractions(int n) {
vector<string> ans ;
for(int i = 2 ; i <= n ; i ++){
for(int j = 1 ; j < i ; j ++){
if(!huzhi(j,i)) continue;
ans.emplace_back(to_string(j) + "/" + to_string(i)) ;
}
}
return ans ;
}
};
int 转 string to_string
2.11 lc.1984 学生分数最小差值
- 滑动窗口
class Solution {
public:
int minimumDifference(vector<int>& nums, int k) {
int ans = 100000;
sort(nums.begin() , nums.end()) ;
int l = 0 , r = k - 1 ;
while(r < nums.size()){
int dis = nums[r] - nums[l] ;
ans = min(ans , dis) ;
r ++ ; l ++ ;
}
return ans ;
}
};
2.12 lc.1020 飞地的数量
飞地 (enclave) 的意思是隶属于某一行政区管辖但不与本区毗连的土地。如果某一行政主体拥有一块飞地,那么它无法取道自己的行政区域到达该地,只能“飞”过其他行政主体的属地,才能到达自己的飞地。(百度百科)
- DFS
class Solution {
public:
void dfs(vector<vector<int>>& grid, int row, int col){
int m = grid.size() , n = grid[0].size() ;
if(row < 0 || row >= m || col < 0 || col >= n ) return ;
if(grid[row][col] == 0 || grid[row][col] == 2) return ;
else if(grid[row][col] == 1) grid[row][col] = 2 ;
dfs(grid,row - 1,col);
dfs(grid,row + 1,col);
dfs(grid,row,col - 1);
dfs(grid,row,col + 1);
}
int numEnclaves(vector<vector<int>>& grid) {
int m = grid.size() , n = grid[0].size() , ans = 0 ;
for(int i = 0 ; i < n ; i ++){
if(grid[0][i] == 1) dfs(grid,0,i) ;
if(grid[m-1][i] == 1) dfs(grid,m-1,i) ;
}
for(int i = 0 ; i < m ; i ++){
if(grid[i][0] == 1) dfs(grid,i,0) ;
if(grid[i][n-1] == 1) dfs(grid,i,n-1) ;
}
for(int i = 0 ; i < m ; i ++){
for(int j = 0 ; j < n ; j ++){
if(grid[i][j] == 1) ans ++ ;
}
}
return ans ;
}
};
2.13 lc.1189 “气球”
class Solution {
public:
int maxNumberOfBalloons(string text) {
int b = 0 , a = 0 , l = 0 , o = 0 , n = 0 , ans = 0 ;
for(int i = 0 ; i < text.size() ; i ++){
if(text[i] == 'b') b ++ ;
if(text[i] == 'a') a ++ ;
if(text[i] == 'l') l ++ ;
if(text[i] == 'o') o ++ ;
if(text[i] == 'n') n ++ ;
}
while( b > 0 && a > 0 && l > 1 && o > 1 && n > 0){
ans ++ ;
b -- ; a -- ; n -- ; l -= 2 ; o -= 2 ;
}
return ans ;
}
};
2.14 lc.540 有序数组中的单一元素
模拟也行,用二分理论上更快
class Solution {
public:
int singleNonDuplicate(vector<int>& nums) {
int low = 0, high = nums.size() - 1;
while (low < high) {
int mid = (high - low) / 2 + low;
mid -= mid & 1;
if (nums[mid] == nums[mid + 1]) {
low = mid + 2;
} else {
high = mid;
}
}
return nums[low];
}
};
2.18 lc.1791 找出星型图中心节点
class Solution {
public:
int findCenter(vector<vector<int>>& edges) {
if(edges[0][0] == edges[1][0]) return edges[0][0] ;
else if(edges[0][0] == edges[1][1]) return edges[0][0] ;
else if(edges[0][1] == edges[1][0]) return edges[0][1] ;
else if(edges[0][1] == edges[1][1]) return edges[0][1] ;
return 0 ;
}
};
反正n大于等于3,edge前两项都判断一下。
2.19 lc.969 煎饼排序
class Solution {
public:
vector<int> pancakeSort(vector<int>& arr) {
vector<int> ret;
for (int n = arr.size(); n > 1; n--) {
int index = max_element(arr.begin(), arr.begin() + n) - arr.begin();
if (index == n - 1) {
continue;
}
reverse(arr.begin(), arr.begin() + index + 1);
reverse(arr.begin(), arr.begin() + n);
ret.push_back(index + 1);
ret.push_back(n);
}
return ret;
}
};
智商题属于是
2.20 lc.717 1bit&2bit
class Solution {
public:
bool isOneBitCharacter(vector<int>& bits) {
int i = 0 ;
while(i < bits.size() - 1){
if(bits[i] == 1) i += 2 ;
else i ++ ;
}
if(i == bits.size() - 1 ) return true ;
else return false ;
}
};
2.26 lc.2016 增量元素之间的最大差值
- 滑动窗口
class Solution {
public:
int maximumDifference(vector<int>& nums) {
int ans = 0 ;
int left = 0 , right = 0 , len = nums.size();
while(left < len && right < len){
if(nums[right] < nums[left]){
left = right ;
}
ans = max (ans , nums[right] - nums[left]) ;
right ++ ;
}
if(ans == 0) return -1 ;
return ans ;
}
};
休息了好几天,开学了,继续奋斗继续刷题。
2.28 lc.1601 最多可达成的换楼请求数
- dfs
class Solution {
private:
vector<int> delta;
int ans = 0, cnt = 0, zero, n;
public:
void dfs(vector<vector<int>> &requests, int pos) {
if (pos == requests.size()) {
if (zero == n) {
ans = max(ans, cnt);
}
return;
}
// 不选 requests[pos]
dfs(requests, pos + 1);
// 选 requests[pos]
int z = zero;
++cnt;
auto &r = requests[pos];
int x = r[0], y = r[1];
zero -= delta[x] == 0;
--delta[x];
zero += delta[x] == 0;
zero -= delta[y] == 0;
++delta[y];
zero += delta[y] == 0;
dfs(requests, pos + 1);
--delta[y];
++delta[x];
--cnt;
zero = z;
}
int maximumRequests(int n, vector<vector<int>> &requests) {
delta.resize(n);
zero = n;
this->n = n;
dfs(requests, 0);
return ans;
}
};