每日一题
2021.10.30
260. 只出现一次的数字 III
这题还是比较简单,用个map统计一下各数字出现的次数,最后遍历map的键值,找出值为1的两个数字。
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
map<int,int>mp;
for(int i=0;i<nums.size();i++){
mp[nums[i]]+=1;
}
vector<int>res;
for(auto i:mp){
if(i.second==1)
res.push_back(i.first);
}
return res;
}
};
2021.10.31
500. 键盘行
又是暴力模拟的一天,按照题干描述,根据每个单词的第一个字母,判断是键盘上的那一行,然后遍历完这个单词,判断此单词上的字母是否全在这一行,最后将所以满足条件的返回即可。
class Solution {
public:
string a="qwertyuiop";
string b="asdfghjkl";
string c="zxcvbnm";
vector<string> findWords(vector<string>& words) {
vector<string>res;
for(int i=0;i<words.size();i++){
int flag=0;
if(a.find(words[i][0])!=-1||a.find(words[i][0]+32)!=-1){
for(int j=1;j<words[i].size();j++){
if((words[i][j]>='a'&&words[i][j]<='z'&&a.find(words[i][j])==-1)||(words[i][j]>='A'&&words[i][j]<='Z'&&a.find(words[i][j]+32)==-1)){
flag=1;
break;
}
}
}
else if(b.find(words[i][0])!=-1||b.find(words[i][0]+32)!=-1){
for(int j=1;j<words[i].size();j++){
if((words[i][j]>='a'&&words[i][j]<='z'&&b.find(words[i][j])==-1)||(words[i][j]>='A'&&words[i][j]<='Z'&&b.find(words[i][j]+32)==-1)){
flag=1;
break;
}
}
}
else{
for(int j=1;j<words[i].size();j++){
if((words[i][j]>='a'&&words[i][j]<='z'&&c.find(words[i][j])==-1)||(words[i][j]>='A'&&words[i][j]<='Z'&&c.find(words[i][j]+32)==-1)){
flag=1;
break;
}
}
}
if(!flag)res.push_back(words[i]);
}
return res;
}
};
我这写的可能是最直接的暴力了。
2021.11.01
575. 分糖果
贪心,设糖果数量为n,糖果种类数为m,由于妹妹只能分到一半,所以答案最多为
n
/
2
n/2
n/2,当m大于
n
/
2
n/2
n/2时,显然答案是
n
/
2
n/2
n/2;当m小于
n
/
2
n/2
n/2时,那么妹妹得到的最大糖果种类数就为m。
class Solution {
public:
int distributeCandies(vector<int>& candyType) {
unordered_set<int>s;
for(int i=0;i<candyType.size();i++)
s.insert(candyType[i]);
return min(s.size(),candyType.size()/2);
}
};
2021.11.02
这题较水就不解释了
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
void deleteNode(ListNode* node) {
node->val=node->next->val;
node->next=node->next->next;
}
};
2021.11.03
407. 接雨水 II
小根堆+BFS
类似与短板效应,我们从最外层围成一个环,每次取出环中最小高度的点,将它周围的四个点中比它高度小的加上它们之间的差值,再将高度修改成同该节点一样的高度,遍历过的点都打上一个标记,然后将该点从环中去除,将它周围比它小的点压入环中,如此往复,直至环为空。
class Solution {
public:
pair<int, pair<int,int> >q;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
int trapRainWater(vector<vector<int>>& heightMap) {
priority_queue<pair<int, pair<int,int> > , vector<pair<int, pair<int,int>>> , greater<pair<int, pair<int,int> > > >p;
int res=0,n=heightMap.size(),m=heightMap[0].size();
vector<vector<bool>>v(n,vector<bool>(m,false));
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(i==0||i==n-1||j==0||j==m-1){
p.push({heightMap[i][j],{i,j}});
v[i][j]=true;
}
}
}
while(p.size()){
q=p.top();
p.pop();
for(int i=0;i<4;i++){
int x=q.second.first+dx[i];
int y=q.second.second+dy[i];
if(x>=0&&x<n&&y>=0&&y<m&&(!v[x][y])){
if(heightMap[x][y]<q.first){
res+=q.first-heightMap[x][y];
}
v[x][y]=true;
p.push({max(heightMap[x][y],q.first),{x,y}});
}
}
}
return res;
}
};
2021.11.04
class Solution {
public:
bool isPerfectSquare(int num) {
for(long long i=1;i*i<=num;i++)
if(i*i==(long long)num)return true;
return false;
}
};
2021.11.05
1218. 最长定差子序列
动态规划
我们从左往右遍历arr,并计算出以arr[i] 为结尾的最长的等差子序列的长度,即dp[arr[i]]=dp[arr[i]-difference]+1,取所有长度的最大值,即为答案。
class Solution {
public:
unordered_map<int,int>mp;
int longestSubsequence(vector<int>& arr, int difference) {
mp.clear();
int res=1;
for(int i=0;i<arr.size();i++){
mp[arr[i]]=mp[arr[i]-difference]+1;
res=max(res,mp[arr[i]]);
}
return res;
}
};
2021.11.06
268. 丢失的数字
水题
class Solution {
public:
int missingNumber(vector<int>& nums) {
int num=0,sum=nums.size()*(nums.size()+1)/2;
for(int i=0;i<nums.size();i++)
num+=nums[i];
return sum-num;
}
};
2021.11.07
598. 范围求和 II
水题
class Solution {
public:
int maxCount(int m, int n, vector<vector<int>>& ops) {
int x=m,y=n;
for(int i=0;i<ops.size();i++){
x=min(ops[i][0],x);
y=min(ops[i][1],y);
}
return x*y;
}
};
2021.11.08
299. 猜数字游戏
题意大致就是对于两个等长字符串A和B,找出有多少对下标与字符相同的个数和下标不同但字符相同的个数。
解法:直接遍历一遍字符串,用两个变量num和sum分别记录两个答案,若A[i]=B[i],这num++,否则用两个数组记下各自这个位置上字符出现的次数,最后遍历一遍记录的数组,取两数组的最小值累加即为sum,最后转化成题目所需字符串返回。
class Solution {
public:
string getHint(string secret, string guess) {
int num=0;
int a[10]={0},b[10]={0};
for(int i=0;i<secret.size();i++){
if(secret[i]==guess[i])num++;
else{
a[secret[i]-'0']+=1;
b[guess[i]-'0']+=1;
}
}
int sum=0;
for(int i=0;i<10;i++){
sum+=min(a[i],b[i]);
}
string res;
res+=to_string(num);
res+='A';
res+=to_string(sum);
res+='B';
return res;
}
};
2021.11.10
495. 提莫攻击
遍历一遍数组,用一个标记记录从当前时间中毒持续到什么时候,即minn=min(a[i+1],a[i]+d);再用个变量记录答案即可。
class Solution {
public:
int findPoisonedDuration(vector<int>& timeSeries, int duration) {
int minn,res=duration;
for(int i=0;i<timeSeries.size()-1;i++){
minn=min(timeSeries[i+1],timeSeries[i]+duration);
res+=minn-timeSeries[i];
}
return res;
}
};
2021.11.12
375. 猜数字大小 II
区间dp
我们用dp[i][j]表示从i到j中所需要的最小费用,则可得出状态方程为dp[i][j]=min(dp[i][j],max(dp[i][k-1],dp[k+1][j])+k)。
class Solution {
public:
int a[205][205];
int getMoneyAmount(int n) {
for(int i=n;i>=1;i--){
for(int j=i+1;j<=n;j++){
a[i][j]=100000000;
for(int k=i;k<=j;k++){
a[i][j]=min(a[i][j],max(a[i][k-1],a[k+1][j])+k);
}
}
}
return a[1][n];
}
};
2021.11.13
520. 检测大写字母
简单模拟,直接按着题目的意思来,统计一下大写字母和小写字母的个数,再跟据它们的个数和第一个字母是否大写判断答案。
class Solution {
public:
bool detectCapitalUse(string word) {
int num1=0,num2=0;
for(int i=0;i<word.size();i++){
if(word[i]>='a')num1++;
else num2++;
}
if(num1==word.size()||num2==word.size()||(word[0]<'a'&&num2==1))
return true;
else
return false;
}
};
2021.11.14
写于2021.11.15,昨天由于参与icpc济南站的缘故没有更新,顺便想吐槽一下那题目的真的难呀,第一次参加区域赛,没有悬念的打铁,以至于有了退役的想法。
677. 键值映射
此题只需用map加个set,用set去重,最后只需要遍历set里面中的元素前缀的是与否判断加不加此键所对应的值。
class MapSum {
public:
unordered_set<string>s;
map<string,int>mp;
MapSum() {
s.clear();
mp.clear();
}
void insert(string key, int val) {
s.insert(key);
mp[key]=val;
}
int sum(string prefix) {
int res=0;
for(auto i:s)
if(i.find(prefix)==0)
res+=mp[i];
return res;
}
};
/**
* Your MapSum object will be instantiated and called as such:
* MapSum* obj = new MapSum();
* obj->insert(key,val);
* int param_2 = obj->sum(prefix);
*/
2021.11.15
319. 灯泡开关
第i个灯泡的反转次数等于它所有因子(包括1和i)的个数,一开始的状态的灭的,只有反转奇数次才会变成亮的,所以只有因子个数为奇数的灯泡序号才会亮,只有平方数的因子数为奇数(比如
6
=
1
∗
6
,
2
∗
3
6=1*6,2*3
6=1∗6,2∗3,它们的因子总是成对出现的,而
4
=
1
∗
4
,
2
∗
2
4=1*4,2*2
4=1∗4,2∗2,只有平方数的平方根因子会只出现1次),所以最终答案等于n以内(包括n和1)的平方数数量,只要计算sqrt(n)即可
class Solution {
public:
int bulbSwitch(int n) {
return floor(sqrt(double(n)));
}
};
2021.11.16
391. 完美矩形
题意很简单,就是给你多个矩形让你判断是否都精准合成一个大矩形。
如果能精准合成一个大矩形,那么一定满足两个条件,一个是大矩形除了四个节点都只出现一次,且其他节点都出现偶数次;另一个是所有小矩形的面积和等于大矩形的面积即可。
class Solution {
public:
bool isRectangleCover(vector<vector<int>>& rectangles) {
map<pair<int,int>,int>mp;
long long sum=0;
for(int i=0;i<rectangles.size();i++){
pair<int,int>x;
x={rectangles[i][0],rectangles[i][1]};
mp[x]+=1;
x={rectangles[i][2],rectangles[i][3]};
mp[x]+=1;
x={rectangles[i][0],rectangles[i][3]};
mp[x]+=1;
x={rectangles[i][2],rectangles[i][1]};
mp[x]+=1;
sum+=(long long)(rectangles[i][2]-rectangles[i][0])*(long long)(rectangles[i][3]-rectangles[i][1]);
}
vector<int>a;
int num=0;
for(auto i:mp){
if(i.second==1){
num+=1;
a.push_back(i.first.first);
a.push_back(i.first.second);
}
else if(i.second&1)
return false;
}
if(num==4){
int b=(abs(a[2]-a[0])+abs(a[4]-a[0])+abs(a[6]-a[0]))/2;
int c=(abs(a[3]-a[1])+abs(a[5]-a[1])+abs(a[7]-a[1]))/2;
if((long long)b*(long long)c==sum)return true;
else return false;
}
else return false;
}
};
2021.11.17
318. 最大单词长度乘积
题意为给你一个字符串数组,让你找到两个没有相同字符的字符串,求这两个字符串的长度乘积的最大值。
首先我们可以统计每个字符串的各个字符出现的次数,最后枚举两个不同的字符串,通过判断有没有相同的字符,若没有相同的字符,则
r
e
s
=
m
a
x
(
r
e
s
,
l
e
n
g
t
h
(
w
o
r
d
[
i
]
)
∗
l
e
n
g
t
h
(
w
o
r
d
[
j
]
)
)
res=max(res,length(word[i]) * length(word[j]))
res=max(res,length(word[i])∗length(word[j]))。
class Solution {
public:
int a[1005][30];
int maxProduct(vector<string>& words) {
memset(a,0,sizeof(a));
for(int i=0;i<words.size();i++)
for(int j=0;j<words[i].size();j++)
a[i][words[i][j]-'a']+=1;
int res=0;
for(int i=0;i<words.size();i++){
for(int j=i+1;j<words.size();j++){
int flag=0;
for(int k=0;k<30;k++){
if(a[i][k]&&a[j][k]){
flag=1;
break;
}
}
int num=words[i].size()*words[j].size();
if((flag==0)&&(num>res))
res=num;
}
}
return res;
}
};
2021.11.18
563. 二叉树的坡度
递归即可
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int sum(TreeNode* root){
if(root == NULL)return 0;
return root->val+sum(root->left)+sum(root->right);
}
int findTilt(TreeNode* root) {
if(root == NULL)return 0;
return abs(sum(root->left)-sum(root->right))+findTilt(root->left)+findTilt(root->right);
}
};
2021.11.19
397. 整数替换
同昨日一样,递归
class Solution {
public:
long f(long x){
if(x==1)return 0;
if(x&1)return 1+min(f(x+1),f(x-1));
return 1+f(x/2);
}
long integerReplacement(long n) {
return f(n);
}
};
2021.11.20
594. 最长和谐子序列
直接用map把每个数和每个数出现的次数 对应记录下来。最后遍历map的key,对每个数判断比他大1的数是否存在,存在的话用O(1)时间来拿到他们的次数,更新结果。
class Solution {
public:
int findLHS(vector<int>& nums) {
unordered_map<int,int>mp;
for(int i=0;i<nums.size();i++)
mp[nums[i]]+=1;
int res=0;
for(auto i:mp){
if(mp.count(i.first+1))
res=max(res,i.second+mp[i.first+1]);
}
return res;
}
};
2021.11.21
559. N 叉树的最大深度
直接递归就完事
/*
// Definition for a Node.
class Node {
public:
int val;
vector<Node*> children;
Node() {}
Node(int _val) {
val = _val;
}
Node(int _val, vector<Node*> _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
public:
int sum(Node *x){
if(x==NULL)return 0;
int res=0;
for(auto i:x->children){
res=max(res,1+sum(i));
}
return res;
}
int maxDepth(Node* root) {
if(root==NULL)return 0;
return 1+sum(root);
}
};
2021.11.22
384. 打乱数组
题目比较简单,一个是返回原数组,一个返回原数组的随机打乱数组。
class Solution {
public:
vector<int>a,b;
Solution(vector<int>& nums) {
for(auto i:nums){
a.emplace_back(i);
b.emplace_back(i);
}
}
vector<int> reset() {
return a;
}
vector<int> shuffle() {
random_shuffle(b.begin(),b.end());
return b;
}
};
/**
* Your Solution object will be instantiated and called as such:
* Solution* obj = new Solution(nums);
* vector<int> param_1 = obj->reset();
* vector<int> param_2 = obj->shuffle();
*/
2021.11.23
859. 亲密字符串
这题返回true的情况无非两种,且都是保证在长度相等的情况下。
一种是两字符串完全相同且有字符重复;
另一种是两字符串只有两个位置不同且错位相等。
class Solution {
public:
bool buddyStrings(string s, string goal) {
if(s.size()!=goal.size())return false;
int a[26];
memset(a,0,sizeof(a));
vector<int>b;
int flag=0;
for(int i=0;i<s.size();i++){
a[s[i]-'a']+=1;
if(a[s[i]-'a']>1)flag=1;
if(s[i]!=goal[i])b.emplace_back(i);
}
if(b.size()==0&&flag)return true;
if(b.size()==2&&s[b[0]]==goal[b[1]]&&s[b[1]]==goal[b[0]])return true;
return false;
}
};
2021.11.25
458. 可怜的小猪
把猪看成维度就行,然后水就是维度中的点
class Solution {
public:
int poorPigs(int buckets, int minutesToDie, int minutesToTest) {
int num=minutesToTest/minutesToDie;
int res;
for(int i=0;i<=100;i++)
if(pow(num+1,i)>=buckets){
res=i;
break;
}
return res;
}
};
2021.11.26
700. 二叉搜索树中的搜索
二叉树父节点的左子节点的值小于父节点的值,右子节点的值大于父节点的值。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
if(root==NULL||root->val==val)return root;
return root->val>val?searchBST(root->left,val):searchBST(root->right,val);;
}
};
2021.11.28
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int>res;
if(s.size()<p.size())return res;
int a[30],b[30];
for(int i=0;i<26;i++)a[i]=0,b[i]=0;
for(int i=0;i<p.size();i++)
a[s[i]-'a']+=1,b[p[i]-'a']+=1;
int flag=1;
for(int i=0;i<26&&flag;i++)
if(a[i]!=b[i])flag=0;
if(flag)res.emplace_back(0);
int l=0,r=p.size();
while(r<s.size()){
a[s[r]-'a']+=1;
a[s[l]-'a']-=1;
flag=1;
l++;r++;
for(int i=0;i<26&&flag;i++)
if(a[i]!=b[i])flag=0;
if(flag)res.emplace_back(l);
}
return res;
}
};
2021.12.1
class Solution {
public:
int maxPower(string s) {
int res=1;
int num=1;
for(int i=1;i<s.size();i++){
if(s[i]==s[i-1])num+=1;
else{
res=max(res,num);
num=1;
}
}
res=max(res,num);
return res;
}
};
class Solution:
import math
def maxPower(self, s: str) -> int:
res,num=1,1
for i in range(1,len(s)):
if s[i]==s[i-1]:
num+=1
else:
res=max(num,res)
num=1
res=max(res,num)
return res