2022.01.25刷题.15844655
Summary:
-
今天玩了好久, 只写了 48 x easy.
-
明天尽量站着写吧, 坐着写一天题, 又不游泳, 脑袋跟浆糊一样啊.
-
还是那样 运动时候在手机上在题解上写出来思路, 然后电脑上码代码吧.
121. 买卖股票的最佳时机 todo
❤️思维导图整理: 股票问题大总结, 彻底搞懂股票问题❤️ - 买卖股票的最佳时机 - 力扣(LeetCode) (leetcode-cn.com)
415. 字符串相加
感觉逻辑很不清晰...
Code
//我的
string addStrings(string num1, string num2) {
reverse(num1.begin(), num1.end());
reverse(num2.begin(), num2.end());
if(num1.size()<num2.size())swap(num1,num2);
int tmp = 0;
int n = num1.size(), m = num2.size();
for(int i = 0; i< m || tmp;i++){ //这直接是字符串模式的大数加法是吧.. 普通的好像挺简单的.
if(i==n) num1+='0'; //不够了补0
num1[i] += tmp; //
if(i<m) num1[i] += num2[i] -'0';
tmp = 0;
if(num1[i]>'9'){
num1[i]-=10;
tmp = 1;
}
}
reverse(num1.begin(), num1.end());
return num1;
}
169. 多数元素
简单题 可是题解有好多, 我只用了um做.
Code
350. 两个数组的交集 II
便捷的交换方向..
Code
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
if (nums1.size() > nums2.size()) {
return intersect(nums2, nums1);
}
}
正解:小的进um, 大的命中直接 --
;
Code
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
if(nums1.size()>nums2.size())return intersect(nums2, nums1);
unordered_map<int,int> um;
for(auto i:nums1) um[i]++;
vector<int> res;
for(auto i:nums2){
if(um.count(i)) {
res.push_back(i),um[i]--;
if(um[i]==0) um.erase(i);
}
}
return res;
}
我的
Code
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
unordered_map<int,int> um1,um2;
for(auto i:nums1) um1[i]++;
for(auto i:nums2) um2[i]++;
vector<int> res;
for(auto i:um1){
int cnt = min(i.second, um2[i.first]);
while(cnt--) res.push_back(i.first);
}
return res;
}
434. 字符串中的单词数
Code
int countSegments(string s) {
int ans = 0;
s += ' '; //方便分解单词.
for (int i = 1; i < s.size(); i++)
if (s[i] == ' ' && s[i - 1] != ' ') ans++; //如果有的话.
return ans;
}
387. 字符串中的第一个唯一字符
简单解法: O(2n)
高效一点: 哈希表直接存索引 O(n+26)
Code
int firstUniqChar(string s) {
vector<int> um(26);
int res = INT_MAX;
for(int i =0;i<s.size();i++){
if(!um[s[i]-'a']) um[s[i]-'a'] = i+1;
else um[s[i]-'a'] = -1;
}
for(auto i:um){
if(i>0) res=min(res,i);
}
return res==INT_MAX?-1:res-1;
}
155. 最小栈
Code
//两个数的栈.
stack<int> s;
stack<int> smin;
MinStack() {
smin.push(INT_MAX); //输入max可以方便底下的min比较.
}
void push(int val) {
s.push(val);
smin.push(min(val,smin.top()));
}
void pop() {
s.pop();smin.pop();
}
int top() {
return s.top();
}
int getMin() {
return smin.top();
}
Code
//原始解法, 相当于三个数的栈.
stack<int> s1;
stack<pair<int,int>> s2;
int minval = 0,mincnt = 0;
MinStack() {}
void push(int val) {
if(!s2.empty()) minval=s2.top().first,mincnt=s2.top().second;
if(s1.size()==0 || minval >val) minval = val,mincnt = 1;
else if(minval == val) mincnt++;
s1.push(val);
s2.push({minval,mincnt});
}
void pop() {
s1.pop();
s2.pop();
}
int top() {
return s1.top();
}
int getMin() {
return s2.top().first;
}
453. 最小操作次数使数组元素相等
其实每次n-1
个元素+1 就是最大的元素-1;
Code
int minMoves(vector<int>& a) {
int min = *min_element(a.begin(),a.end());
int res = 0;
for(auto i:a) res+=i-min;
return res;
}
733. 图像渲染
BFS的框架.
Code
vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {
vector<vector<int>> dir={{1,0},{-1,0},{0,1},{0,-1}};
queue<pair<int,int>> s;
int n = image.size(), m = image[0].size();
s.push({sr,sc});
int origin = image[sr][sc];
if(color==origin) return image; //注意... 非常重要.
while(!s.empty()){
image[s.front().first][s.front().second] = color;
for(auto i:dir){
auto x = s.front().first + i[0],y = s.front().second + i[1];
if(x>=0 && x<n && y>=0 && y<m && image[x][y] == origin){
s.push({x,y});
}
}
s.pop();
}
return image;
}
234. 回文链表
如何O(n) , O(1) 也不简单..
Code
bool isPalindrome(ListNode* head) {
if(!head->next) return true; //单一节点, 对.
ListNode* slow = head, *fast = head;
while(fast->next && fast->next->next){
fast = fast->next->next;
slow = slow->next;
}
ListNode* hh = slow->next;
slow->next = NULL;
ListNode* newhead = NULL;
while(hh){ //反转链表.
auto oldNext = hh->next;
hh->next = newhead;
newhead = hh;
hh = oldNext;
}
while(newhead){ //需要注意 后半段是一定比前半段短...
if(head->val!=newhead->val) return false;
head = head->next, newhead = newhead->next;
}
return true;
}
705. 设计哈希集合
了解下如何使用 bitset
Code
class MyHashSet {
public:
bitset<1000005> hashSet;
MyHashSet() { }
void add(int key) {
hashSet[key] = 1;
}
void remove(int key) {
hashSet[key] = 0;
}
bool contains(int key) {
return hashSet.test(key);
}
};
414. 第三大的数
使用有序集合, 如果大于最小的就抹去最小的.
Code
int thirdMax(vector<int>& nums) {
set<int> s;
for(auto i:nums){
if(s.count(i))continue;
s.insert(i);
if(s.size()>3) s.erase(s.begin());
}
return s.size()==3?*s.begin():*s.rbegin(); //注意是 rbegin()是返回最大的.
}
Code
// 原本 模拟法 容易出错.
int thirdMax(vector<int>& nums) {
long long a=LONG_MIN,b=LONG_MIN,c=LONG_MIN;
for(auto i:nums){
if(i==b||i==a)continue;;
if(i>c) {
c = i;
if(c>b){
swap(c,b);
if(b>a)
swap(a,b);
}
}
}
return c!=LONG_MIN?c:a;
}
326. 3 的幂
其实可以直接判断是否是最大的约数..
Code
bool isPowerOfThree(int n) {
while(n && n%3==0){
n/=3;
}
return n == 1;
}
Code
// O(1)
bool isPowerOfThree(int n) {
return n > 0 && 1162261467 % n == 0;
}
Code
//我的
bool isPowerOfThree(int n) {
if(n<=0) return false;
n = abs(n);
while(n>1){
if(n%3) return false;
n/=3;
}
return true;;
}
506. 相对名次
Code
vector<string> findRelativeRanks(vector<int>& score) {
int n = score.size();
vector<string> gold = {"Gold Medal","Silver Medal","Bronze Medal"};
vector<pair<int,int>> arr;
for(int i = 0;i<n; i++){
arr.emplace_back(make_pair(-score[i],i));
} // 这样子直接放一起排序, 可以保持原有的序号, 知道哪个下标排第几.
// emplace_back 和 make_pair好像可以加快速度?
sort(arr.begin(),arr.end());
vector<string> ans(n);
for(int i = 0;i<n;i++){
ans[arr[i].second] = i>2?to_string(i+1):gold[i];
}
return ans;
}
// 原始.
Code
vector<string> findRelativeRanks(vector<int>& score) {
int n = score.size();
vector<int> origin = score;
sort(score.begin(), score.end());
unordered_map<int, string> um;
vector<string> gold = {"","Gold Medal","Silver Medal","Bronze Medal"};
vector<string> res;
for(int i = 0; i < n;i++){
um[score[i]] = n-i<=3?gold[n-i]:to_string(n-i);
}
for(auto i:origin){
res.push_back(um[i]);
}
return res;
}
剑指 Offer 11. 旋转数组的最小数字 //todo
这题意思是对旋转数组做二分..
Code
剑指 Offer 42. 连续子数组的最大和
脑筋急转弯, 还有分治的做法. 其实就是如果前一个数最大小于0 就不要他了.
Code
int maxSubArray(vector<int>& nums) {
int pre = 0, maxAns = nums[0];
for (const auto &x: nums) {
pre = max(pre + x, x);
maxAns = max(maxAns, pre);
}
return maxAns;
}
剑指 Offer 10- I. 斐波那契数列\todo
矩阵快速幂的方法.
面试题 10.01. 合并排序的数组
双指针题目, 归并排序的模板.
Code
void merge(vector<int>& A, int m, vector<int>& B, int n) {
int a = m - 1, b= n - 1;
for(int i = a+b+1;i>=0 ;i--){
if(a<0||b<0) A[i]=a>=0?A[a--]:B[b--];
else if(A[a] >= B[b]) A[i] = A[a--];
else A[i] = B[b--];
}
}
258. 各位相加\todo
有O(1)的解法.
290. 单词规律
Code
bool wordPattern(string pattern, string s) {
unordered_map<char,string> um;
unordered_map<string,char> um2;
int l = 0, len = 0;
for(int i = 0;i<pattern.size();i++){
while(l+len<s.size()&&s[l+len]!=' ') len++;
if(l>s.size()) return false;
string ss = s.substr(l,len);
char c = pattern[i];
//---------------------
if(um.count(c)^um2.count(ss)) return false;
if(um.count(c)){
if(um[c]!=ss || um2[ss]!=c) return false;
}
else um[c] = ss, um2[ss] = c;
//--------------------------上面的改成下面好一点...
if (str2ch.count(tmp) && str2ch[tmp] != ch) return false;
if (ch2str.count(ch) && ch2str[ch] != tmp) return false;
str2ch[tmp] = ch; ch2str[ch] = tmp;
//------------------------
l = l+len+1, len = 0;
}
return l>=s.size();
}
605. 种花问题
有个跳格子解法, 可是不知道其他地方能用到不.
448. 找到所有数组中消失的数字
有个O(1)的原地操作解法
405. 数字转换为十六进制数
补码是 原码取反再加一.
Code
string toHex(int num) {
if(num == 0) return "0"; // 避免出现先导0
string res = "";
for(int i = 7;i>=0;i--){
int c = (num>>(4*i)) & 0xf; //这里记住是左移 4 * i 位.
if(res.size()>0 || c!=0){
res+= c<=9?'0'+c:'a'+c-10; // 这里是
}
// cout<<c<<' ';
}
return res;
}
598. 范围求和 II
脑筋急转弯... 不是差分.
997. 找到小镇的法官
做错了... 多读题吧, 和这次的周赛是一样的.
只有入度 n-1 出度是0的时候 才能是法官.
因为 n<= 10000, 所以直接一个数组就能存下来.
Code
int findJudge(int n, vector<vector<int>>& trust) {
vector<int> a(n+1);
for(auto i:trust){
a[i[0]]+=n;
a[i[1]]++;
}
for(int i = 1;i<=n;i++){
if(a[i] == n-1) return i;
}
return -1;
}
492. 构造矩形
做错了,, 贪心构造是错的. 应该是个数学问题, 遇到比 sqrt() 更小的那个才返回.
Code
vector<int> constructRectangle(int area) {
for(int i = sqrt(area);;i--){
if(area%i == 0) return {area/i,i};
}
return {};
}
Code
// 错误 贪心.
vector<int> constructRectangle(int area) {
if(area == 1) return {1,1};
int tmp = area;
vector<int> divs;
for(int i = 2;i<=tmp;i++){
while(tmp%i==0) divs.push_back(i), tmp/=i;
}
int l = 1, w = 1;
for(int i = divs.size()-1; i>=0; i--){
if(l<w) l*=divs[i];
else w*=divs[i];
}
if(l<w) swap(l,w) ;
return {l,w};
}
594. 最长和谐子序列
Code
int findLHS(vector<int>& nums) {
unordered_map<int, int> um; //直接记录成um就行.
for(auto i:nums) um[i]++;
int res = 0;
for(auto [key, val]:um) //这里 记住!! 怎么和python一样展开, 不知道pair行不行.
if(um.count(key+1)) res = max(res,val+um[key+1]);
return res;
}
Code
//我的, 有缺陷.
int findLHS(vector<int>& nums) {
map<int, int> um;
for(auto i:nums) um[i]++;
auto it = um.begin();
int res = 0;
int preval = INT_MIN, precnt = 0;
for(auto i:um){
if(preval+1 == i.first) res=max(res,i.second+precnt);
// else res = max(res, i.second);
preval = i.first, precnt = i.second;
}
return res;
}
551. 学生出勤记录 I
注意 s.size()-2 有个大bug..
s.size() 是 unsigend long, 需要转换成 int 才能做..
Code
bool checkRecord(string s) {
int cntA = 0;
for(auto i:s) if(i=='A')cntA++;
if(cntA>1) return false;
for(int i = 0;i<(int)s.size()-2;i++){
string b = s.substr(i,3);
if(b=="LLL") return false;
}
return true;
}
796. 旋转字符串todo
Rabin-Karp 字符串哈希
Code
Code
Code
Code
Code
Code
Code
Code
Code
Code
Code
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)