leetcode :
第一题https://leetcode.cn/problems/check-distances-between-same-letters/利用哈希表记录相同元素出现位置的下标
class Solution {
public:
bool checkDistances(string s, vector<int>& distance) {
vector<int> ans(26);
unordered_map<char, vector<int>> res;
for(int i = 0; i < s.size(); i ++){
res[s[i]].push_back(i);
}
for(auto &[x, y] : res){
ans[x - 97] = y[1] - y[0] - 1;
}
for(int i = 0; i < 26; i ++) cout << ans[i] << " ";
for(int i = 0; i < 26; i ++){
if(ans[i] != distance[i] && res.count(char(i + 97)) != 0) return false;
}
return true;
}
};
第三题https://leetcode.cn/problems/longest-nice-subarray/
从左往右枚举,枚举时h滑动窗口维护一个当前所有数的或的结果(填充所有的1)。遇到一个数:
如果与当前记录的结果now相与为0,那么now或运算上这个数,右指针往前继续走
如果与当前记录的结果now相与不为0,那么加入的这个数不满足条件,需要将滑动窗口左边往右移,对于每一个离开窗口的数,用记录的窗口结果now与其做异或运算。
滑窗中间满足条件的情况记录更新
class Solution {
public:
int longestNiceSubarray(vector<int>& nums) {
int n = nums.size();
int i = 0, j = 1, ans = 1;
if (n == 1) return 1;
long long now = nums[0];
while (i < n && j < n) {
while ((i < j) && ((now & nums[j]) != 0)) {
now ^= nums[i];
i ++;
}
now |= nums[j];
ans = max(ans, j - i + 1);
j ++;
}
return ans;
}
};
第一题https://leetcode.cn/problems/find-subarrays-with-equal-sum/从前往后遍历一遍, 用哈希表记录
class Solution {
public:
bool findSubarrays(vector<int>& nums) {
unordered_map<int, int> ans;
for(int i = 0; i < nums.size() - 1; i ++){
int x = nums[i] + nums[i + 1];
ans[x] ++;
if(ans[x] == 2) return true;
}
return false;
}
};
第二题https://leetcode.cn/problems/strictly-palindromic-number/常规方法将数字转换为指定的n进制数, 利用字符串reverse判断是否符合
class Solution {
public:
string trans(int n,int k){
string res = "";
while(n){
int tmp = n % k;
n /= 2;
res += tmp + '0';
}
return res;
}
bool check(string s)
{
string test = s;
reverse(test.begin(), test.end());
if(test==s) return true;
return false;
}
bool isStrictlyPalindromic(int n) {
for(int i = 2; i <= n - 2; i ++){
string tmp = trans(n, i);
if(!check(tmp)) return false;
}
return true;
}
};
脑筋急转弯, 数字 4 在二进制下不是回文的。对于 n ≥ 5,它们的 (n−2) 进制表示都是 12,因此也都不是回文的。直接返回 false 即可
class Solution {
public:
bool isStrictlyPalindromic(int n) {
return false;
}
};
第一题https://www.acwing.com/problem/content/4612/样例给的提示很明显了,尽量让数字更长用 1 和 7 两个数字
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
cin >> n;
vector<int> ans(n);
for(int i = 0; i < n; i ++) cin >> ans[i];
for(int i = 0; i < n; i ++){
string x;
if(ans[i] % 2 != 0){
x += '7';
for(int j = 0; j < (ans[i] - 3) / 2; j ++){
x += '1';
}
}
else{
for(int j = 0; j < ans[i] / 2; j ++){
x += '1';
}
}
cout << x << endl;
}
return 0;
}
第二题https://www.acwing.com/problem/content/4613/
列交换是对两列元素全部交换,所以我们逆向思维一下,从结果可以得到只交换一次或者不交换的排列。(即 m 个元素的全排列中与原顺序排列相比不同元素的数量小于等于2个的排列)
#include<iostream>
using namespace std;
const int N = 25;
int a[N][N];
int s[N];
int n, m;
bool check()
{
int cnt = 0;
for(int i = 1; i <= n; i++)
{
int f = 0;
for(int j = 1; j <= m; j++)
{
if(s[j] != a[i][j]) f++;
}
if(f > 2) return 0;
}
return 1;
}
bool solve()
{
cin >> n >> m;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
cin >> a[i][j];
for(int i = 1; i <= m; i++) s[i] = i;
if(check()) return 1;
for(int x = 1; x <= m; x++)
{
for(int y = x + 1; y <= m; y++)
{
swap(s[x], s[y]);
if(check()) return 1;
swap(s[x], s[y]);
}
}
return 0;
}
int main()
{
if(solve()) puts("YES");
else puts("NO");
return 0;
}