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

posted @   benenzhu  阅读(34)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示
主题色彩