leetcode刷题周记-2021.11.14~2021.11.20

简介: leetcode刷题周记-2021.11.14~2021.11.20

2021.11.14-键值映射

题面

实现一个 MapSum 类,支持两个方法,insert 和 sum:

MapSum() 初始化 MapSum 对象

void insert(String key, int val) 插入 key-val 键值对,字符串表示键 key ,整数表示值 val 。如果键 key 已经存在,那么原来的键值对将被替代成新的键值对。

int sum(string prefix) 返回所有以该前缀 prefix 开头的键 key 的值的总和。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/map-sum-pairs

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

文字分析

使用trie树(字典树),物理上用静态链表进行存储。插入时,每到单词结尾处,利用ValWord数组表示当前结点是否为单词结束。如果单词结束,则ValWord表示当前结点的单词的权值。查询时,利用dfs算法,可以得到当前前缀的权值之和。

代码

class MapSum {
public:
    int ne[10005][26];
    int idx;
    int valWord[10005];
    MapSum() {
        idx=0;
        memset(ne,0,sizeof ne);
        memset(valWord,0,sizeof valWord);
    }
    void insert(string key, int val) {
        int p=0;
        for(int i=0;i<key.length();i++){
            int u=key[i]-'a';
            if (!ne[p][u])
                ne[p][u]=++idx;
            p=ne[p][u];
        }
        valWord[p]=val;
    }
    int sum(string prefix) {
        int p=0;
        for(int i=0;i<prefix.length();i++){
            int u=prefix[i]-'a';
            if(!ne[p][u])
                return 0;
            p=ne[p][u];    
        }
        return dfs(p);
    }
    int dfs(int p){
        int ans=valWord[p];
        for(int u=0;u<26;u++){
            if(ne[p][u])
                ans+=dfs(ne[p][u]);
        }
        return ans;
    }
};
/**
 * 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-灯泡开关

题面

初始时有n nn个灯泡处于关闭状态。第一轮,你将会打开所有灯泡。接下来的第二轮,你将会每两个灯泡关闭一个。

第三轮,你每三个灯泡就切换一个灯泡的开关(即,打开变关闭,关闭变打开)。第 i ii 轮,你每 i ii 个灯泡就切换一个灯泡的开关。直到第 n nn 轮,你只需要切换最后一个灯泡的开关。

找出并返回 n nn 轮后有多少个亮着的灯泡。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/bulb-switcher

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

文字分析

看了题解才能明白一个数论知识:除了平方数,其余灯泡都会被开关偶数次数。只有平方数位置的灯泡会被开关奇数次数。1 11n nn个灯泡中有n \sqrt{n}n个平方数。

代码

class Solution {
public:
    int bulbSwitch(int n) {
    return (int) sqrt(n);
    }

2021.11.16-完美矩形

题面

image.png

如果所有矩形一起精确覆盖了某个矩形区域,则返回 true ;否则,返回 false 。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/perfect-rectangle

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

文字分析

看到了题解才想到,可以通过x i x_{i}xi, y i y_{i}yi, a i a_{i}ai, b i b_{i}bi计算出每个矩形的四个边界点。在完美矩形中,除了大矩形最外侧的四个边界点,其余小矩形边界点都会出现偶数次数,因为每个边界点是两个小矩形的交界处。可以用哈希表记录小矩形每个点出现的次数。同时也不要忘了小矩形面积和等于大矩形。如果小矩形面积和不等于大矩形,则大矩形不是完美矩形。

代码

typedef pair<int,int> PII;
class Solution {
public:
    bool isRectangleCover(vector<vector<int>>& rectangles) {
        long long areasum=0;
        int minX=0x3f3f3f3f;
        int minY=0x3f3f3f3f;
        int maxX=-0x3f3f3f3f;
        int maxY=-0x3f3f3f3f;
        map<PII,int> cnt;
        int n=rectangles.size();
        for(int i=0;i<n;i++){
            int x=rectangles[i][0];
            int y=rectangles[i][1];
            int z=rectangles[i][2];
            int w=rectangles[i][3];
            areasum+=(z-x)*(w-y);
            minX=min(x,minX);
            minY=min(y,minY);
            maxX=max(z,maxX);
            maxY=max(w,maxY);
            PII point0({x,y});
            PII point1({x,w});
            PII point2({z,y});
            PII point3({z,w});
            cnt[point0]++;
            cnt[point1]++;
            cnt[point2]++;
            cnt[point3]++;
        }
        PII minmin({minX,minY});
        PII minmax({minX,maxY});
        PII maxmin({maxX,minY});
        PII maxmax({maxX,maxY});
        long long area=(maxX-minX)*(maxY-minY);
        if(area!=areasum)
            return false;
        if(!cnt.count(minmin) || !cnt.count(minmax) || !cnt.count(maxmin) || !cnt.count(maxmax))
            return false;
        cnt.erase(minmin);
        cnt.erase(minmax);
        cnt.erase(maxmin);
        cnt.erase(maxmax);
        for(auto &node:cnt)
            if(node.second%2==1)
                return false;
        return true;
    }
};

2021.11.17-最大单词长度乘积

题面

给定一个字符串数组 words,找到 length(word[i]) * length(word[j]) 的最大值,并且这两个单词不含有公共字母。你可以认为每个单词只包含小写字母。如果不存在这样的两个单词,返回 0。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/maximum-product-of-word-lengths

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

文字分析

看到了题解才明白,可以将一个单词按位运算压缩成一个只有32bit的int。因为英文字母共26个,26<32.所以,int每一位记录某个字母是否出现在某个单词中。存储单词时对每一位进行或运算,判断单词是否有相同字母时进行与运算。

代码

class Solution {
public:
    int maxProduct(vector<string>& words) {
        int hashword[1005];
        for(int i=0;i<words.size();i++)
            for(int j=0;j<words[i].size();j++)
                hashword[i]|=(1<<(words[i][j]-'a'));
        int ans=0;
        for(int i=0;i<words.size();i++)
            for(int j=i+1;j<words.size();j++){
                if ((hashword[i]&hashword[j])==0)
                    ans=max(ans,words[i].size()*words[j].size());
            }
        return ans;
    }
};

2021.11.18-二叉树的坡度

题面

给定一个二叉树,计算 整个树 的坡度 。

一个树的 节点的坡度 定义即为,该节点左子树的节点之和和右子树节点之和的 差的绝对值 。如果没有左子树的话,左子树的节点之和为 0 ;没有右子树的话也是一样。空结点的坡度是 0 。

整个树 的坡度就是其所有节点的坡度之和。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/binary-tree-tilt

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

文字分析

树的坡度和=左子树坡度和+右子树坡度和+当前结点坡度。可以使用dfs。

代码

class Solution {
public:
    int findsum(TreeNode *root){
        if (root==NULL)
            return 0;
        else return root->val+findsum(root->left)+findsum(root->right);
    }
    int findTilt(TreeNode* root) {
        if(root==NULL)
            return 0;
        int lsum=findsum(root->left);
        int rsum=findsum(root->right);
        return abs(lsum-rsum)+findTilt(root->left)+findTilt(root->right);
    }
};

2021.11.19-整数替换

题面

给定一个正整数 n ,你可以做如下操作:

如果n 是偶数,则用 n/2替换n

如果n 是奇数,则可以用n+1n1替换n

n 变为1 所需的最小替换次数是多少?

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/integer-replacement

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

文字分析

image.png

代码

class Solution {
public:
    int integerReplacement(int n) {
        int ans=0;
        while (n>1){
            if (n%2==0){
                n=n/2;
                ans++;
            }
            else if(n%4==1){
                n=n/2;
                ans+=2;
            }
            else if(n%4==3){
                if (n==3){
                    ans+=2;
                    n=1;
                }
                else{
                    n=n/2+1;
                    ans+=2;
                }
            }
        }
        return ans;
    }
};

2021.11.20-最长和谐子序列

题面

和谐数组是指一个数组里元素的最大值和最小值之间的差别 正好是 1 11

现在,给你一个整数数组 nums ,请你在所有可能的子序列中找到最长的和谐子序列的长度。

数组的子序列是一个由数组派生出来的序列,它可以通过删除一些元素或不删除元素、且不改变其余元素的顺序而得到。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/longest-harmonious-subsequence

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

文字分析

这道题的题面非常具有迷惑性,看似是动态规划,实则没有这么复杂。直接用哈希表存储每个数字出现的次数就行。

代码

class Solution {
public:
    int findLHS(vector<int>& nums) {
        map<int,int> st;
        int len=nums.size();
        for(int i=0;i<len;i++)
            st[nums[i]]++;
        int res=0;
        for(auto num:st){
            if(st.find(num.first-1)!=st.end()){
                res=max(res,st[num.first-1]+num.second);
            }
        }
        return res;
    }
};

自我总结

本周题目为数论2题,数据结构与图论2题,哈希表3题。其中有2题为完全独立思考,有2题为思考出了解法但并非最优解,有2题需要借助题解进行理解。


目录
相关文章
|
5月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
6月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
76 6
|
6月前
|
Python
【Leetcode刷题Python】剑指 Offer 26. 树的子结构
这篇文章提供了解决LeetCode上"剑指Offer 26. 树的子结构"问题的Python代码实现和解析,判断一棵树B是否是另一棵树A的子结构。
73 4
|
6月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
145 2
|
3月前
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
99 1
|
5月前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
6月前
|
索引 Python
【Leetcode刷题Python】从列表list中创建一颗二叉树
本文介绍了如何使用Python递归函数从列表中创建二叉树,其中每个节点的左右子节点索引分别是当前节点索引的2倍加1和2倍加2。
90 7
|
6月前
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
68 5
|
6月前
|
Python
【Leetcode刷题Python】剑指 Offer 30. 包含min函数的栈
本文提供了实现一个包含min函数的栈的Python代码,确保min、push和pop操作的时间复杂度为O(1)。
45 4
|
6月前
|
Python
【Leetcode刷题Python】剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
Leetcode题目"剑指 Offer 21. 调整数组顺序使奇数位于偶数前面"的两种Python解决方案,一种是使用双端队列调整数组顺序,另一种是使用双指针法将奇数移到数组前半部分,偶数移到后半部分。
37 4