![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
LeetCode刷题笔记
督促自己学习
爱一袭铁路
这个作者很懒,什么都没留下…
展开
-
704.二分查找
根据题意class Solution { public int search(int[] nums, int target) { if(target<nums[0]||target>nums[nums.length-1])return-1; int n=nums.length; int left=0,right=n-1; while(left<=right) { int mid原创 2021-09-08 22:03:52 · 81 阅读 · 0 评论 -
474. 一和零
https://leetcode-cn.com/problems/ones-and-zeroes/本题中的字符串可以看作是一个物品,每个物品只能拿取一次,所以这道题可以用01背包做出来,只不过需要二维的背包来存储dp数组那么按照dp五步来1.dp[i] /[j]表示,最多有i个0和j个1的strs的最大子集的大小为dp[i] /[j]2.确定递推公式dp[i] /[j]可以由前一个strs的前一个字符串推导出来,strs的字符串里有num1个1,num个0,因此,dp可以是dp[i - num0]原创 2021-05-20 22:07:34 · 65 阅读 · 0 评论 -
416. 分割等和子集
https://leetcode-cn.com/problems/partition-equal-subset-sum/这道题要我们判断这个数组能否分割为2个子集,使得两个子集的元素和相等因此,只要找到元素和为总和的一半的子集,就找到了两个子集因为元素和我们只能用一次,所以在这道题中我们需要使用01背包的思想我们可以确定的条件:1.背包的大小为所有元素之和的一半2.背包需要放入的商品的价值为元素的数值,重量也是3.背包正好装满的时候,说明找到了总和为元素之和一半的子集4.背包中每一个元素不可原创 2021-05-18 15:41:20 · 40 阅读 · 0 评论 -
1049. 最后一块石头的重量 II
https://leetcode-cn.com/problems/last-stone-weight-ii/其实这道题的意思就是把数组分成尽量相等的两份,然后输出剩下的值我们可以直接根据动归五步来做1.确定dp数组及其下标的含义dp[j]表示,容量为j的背包最大可以容纳价值为dp[j]的物品2.确定递推公式dp[j] = max(dp[j], dp[j - stones[i]] + stones[i])3.dp数组的初始化根据题目中的意思,把数组大小规定为20000左右就可以了,初值按0来赋原创 2021-05-18 15:40:34 · 52 阅读 · 0 评论 -
96. 不同的二叉搜索树
https://leetcode-cn.com/problems/unique-binary-search-trees/如果n=1,那么一共有1棵搜索树如果n=2,那么一共有2棵搜索树如果n=3,那么一共有5棵搜索树如果n=4,那么一共有14棵搜索树我们大致推出,n每增加一,答案都需要再原来的基础上增加如果以双层循环作为标准,那么我们大致可以推出状态转移方程为dp[i] += dp[j - 1] * dp[i - j]我们可以判断推理的顺序是从1到n,循环两层class Solution {原创 2021-05-12 22:14:18 · 61 阅读 · 0 评论 -
343. 整数拆分
https://leetcode-cn.com/problems/integer-break/从2开始,拆分的数字从两个增加,所以,我们采用动态规划对该问题进行求解class Solution {public: int integerBreak(int n) { vector<int>dp(n+1); dp[2]=1; for(int i=3;i<=n;i++) { for(int j=1原创 2021-05-12 13:54:31 · 47 阅读 · 0 评论 -
63. 不同路径 II
https://leetcode-cn.com/problems/unique-paths-ii/利用动态规划,从1开始存储每个节点的道路数状态转移方程是dp[i][j]=do[i][j-1]+dp[i-1][j]但是,题目中有一个重要的点,障碍物该怎么跨越假设路径只要一条,那么障碍物后面的都是不可以到达的,我们标记为0class Solution {public: int uniquePathsWithObstacles(vector<vector<int>>&原创 2021-05-11 21:04:42 · 34 阅读 · 0 评论 -
746. 使用最小花费爬楼梯
https://leetcode-cn.com/problems/min-cost-climbing-stairs/这是一道动态规划的题目既然是动态规划,那么就应该写出状态转移方程根据题目 的意思,我们可以判断dp[i]=dp[i-1]+dp[i-2]+cost[i]然后,我们只需要从前到后遍历数组就可以了class Solution {public: int minCostClimbingStairs(vector<int>& cost) { int原创 2021-05-11 18:03:27 · 38 阅读 · 0 评论 -
102.二叉树的层序遍历
https://leetcode-cn.com/problems/binary-tree-level-order-traversal/class Solution {public: vector<vector<int>> levelOrder(TreeNode* root) { queue<TreeNode*>que; if(root!=NULL)que.push(root); vector<vector&原创 2021-04-26 23:37:58 · 51 阅读 · 0 评论 -
二叉树的前序中序后序遍历(递归法)
void recursion(Treenode* cur, vector<int>& vec){//前序遍历 if (cur == NULL)return; vec.push_back(cur->val); recursion(cur->left, vec); recursion(cur->right, vec);}void recursion(Treenode* cur, vector<int>& vec){//中序遍历 if原创 2021-04-25 21:49:34 · 43 阅读 · 0 评论 -
145.二叉树的后序遍历(迭代法)
https://leetcode-cn.com/problems/binary-tree-postorder-traversal/在前序遍历的基础上改进class Solution {public: vector<int> postorderTraversal(TreeNode* root) { stack<TreeNode*>st; vector<int>result; st.push(root);原创 2021-04-25 16:19:09 · 44 阅读 · 0 评论 -
94.二叉树的中序遍历(迭代法)
https://leetcode-cn.com/problems/binary-tree-inorder-traversal/根前序遍历的题类似,就是输出顺序但是,这次我们需要一个指针用来遍历节点同样是一个栈来处理节点上的元素class Solution {public: vector<int> inorderTraversal(TreeNode* root) { stack<TreeNode*>st; vector<int&g原创 2021-04-25 15:55:34 · 45 阅读 · 0 评论 -
144.二叉树的前序遍历(迭代法)
https://leetcode-cn.com/problems/binary-tree-preorder-traversal/这道题的目的是让我们输出二叉树的前序遍历前序遍历,即根据 中 左 右 的顺序输出二叉树的结点class Solution {public: vector<int> preorderTraversal(TreeNode* root) { stack<TreeNode*>st;//创建一个栈来做中转站 vector原创 2021-04-25 15:18:02 · 41 阅读 · 0 评论 -
347.前k个高频元素
https://leetcode-cn.com/problems/top-k-frequent-elements/给定一个整数集和一个数返回频率第k高的数如果用暴力的方法去做也可以完成,统计每个数的频率然后逐个输出但是,题目中的进阶要求我们必须使用时间复杂度为O(nlogn)级别的算法因此,我们可以采用优先级队列不过,还有一个问题,是用大顶堆还是小顶堆呢?如果使用大顶堆的话,在每次更新的时候,都会弹出最大的元素,因此,我们使用小顶堆因为我们需要统计前k频率的数,小顶堆每次弹出最小元素,最后小原创 2021-04-24 20:39:09 · 38 阅读 · 0 评论 -
239.滑动窗口最大值
https://leetcode-cn.com/problems/sliding-window-maximum/又是一道滑动窗口题这道题的暴力解法是在每次移动时比较产生最大值,但因为数据是整体移动的,用max来标记最大值不容易实现因此,我们定义一个双向队列来实现这一目的...原创 2021-04-24 15:12:13 · 49 阅读 · 0 评论 -
150.逆波兰表达式
https://leetcode-cn.com/problems/evaluate-reverse-polish-notation/根据题目的意思,我们需要把原先的中缀表达式改写为后缀表达式也就是原本a+b改写为ab+我们也是运用stack来进行解答stack<int>st; for(int i=0;i<tokens.size();i++) { if(tokens[i]=="+"||tokens[i]=="-"||tokens原创 2021-04-23 12:35:09 · 44 阅读 · 0 评论 -
向左旋转字符串
https://leetcode-cn.com/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/在只学习了C语言的时候,向左旋转字符串是非常麻烦的,需要注意各种条件而在stl库中,reverse函数可以方便地旋转字符串 reverse(s.begin(),s.begin()+n); reverse(s.begin()+n,s.end()); reverse(s.begin(),s.end()); return s;原创 2021-04-19 23:53:35 · 73 阅读 · 0 评论 -
翻转字符串中的单词
https://leetcode-cn.com/problems/reverse-words-in-a-string/该题需要我们翻转字符串中的单词因为题目中建议我们采用n(1)复杂度的方法,所以我们就不能使用stl库中的一些函数了首先,我们反转整个字符串我们设计让指针只读入非空格字符,除了第一个单词,之后每遇到一个单词都在前面加上空格,这样就达到了去空格的目的然后,我们只需要对每个单词进行翻转就完成了字符串中单词的翻转 reverse(s.begin(),s.end()); i原创 2021-04-19 19:30:13 · 101 阅读 · 0 评论 -
字符串替换空格
https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/在之前,如果需要替换空格并且替换的长度不等于空格大小,可以采用边判断边输出的方法,但这道题我们需要返回一个string类型,所以需要采取新方法首先,我们遍历一次字符串,获得空格的数目然后我们把原数组的大小扩充空格的两倍((3-1)/1=2)之后我们定义两个指针,一个指向原字符串末尾,一个指向新字符串末尾,让它们同时向头部移动,如果遇到非空格那么就从前指针输入字符到后指针,否则,就把空格转化为%原创 2021-04-19 18:50:59 · 143 阅读 · 0 评论 -
从第k个字符开始反转字符串
https://leetcode-cn.com/problems/reverse-string-ii/submissions/因为如果用双指针法进行反转字符串代码量会比较大,所以,我们采用stl库中的reserve函数它的功能是反转字符串,具体是reserve(开始位置,结束位置)int n=s.size(); for(int i=0;i<n;i+=2*k) { //如果剩余字符数大于K if(i+k<=n) reve原创 2021-04-19 18:32:28 · 220 阅读 · 0 评论 -
四数相加
https://leetcode-cn.com/problems/4sum-ii/该题大意是说给我们四个数组,判断从每个数组中各取一个数相加能否等于零,因为是四数相加,所以采用暴力解法的复杂度会非常大因此,我们采用哈希表法因为数组不需要有序,为了读入数据更加快捷,我们采用unordered_map来存储哈希表首先,遍历前两个数组,获得每两个元素相加的和存储到哈希表中然后,遍历后两个数组,前两个数组与后两个数组的和即a+b+c+d,即前两个数组的和在等于-c-d 时四数之和为零,当满足条件时,将结果原创 2021-04-19 16:17:53 · 127 阅读 · 0 评论 -
用set定义的哈希表
https://leetcode-cn.com/problems/intersection-of-two-arrays/题目给了两个数组,储存在vector中,我们也可以用数组进行存储哈希表,但是,在数组大小未知的情况下,这样做很容易出错或浪费空间所以,我们可根据集合的性质,来对哈希表进行存储 unordered_set<int>result_set; unordered_set<int>nums_set(nums1.begin(),nums1.end());原创 2021-04-18 23:35:05 · 161 阅读 · 0 评论 -
滑动窗口
https://leetcode-cn.com/problems/minimum-size-subarray-sum/滑动窗口确实是两指针法的一种首先定义两个指针,先让右指针向右移动,直到达到题目所需的值然后移动左指针,记录最小时的元素数目重复上述过程,记录最小值 int n=nums.size(); int ans=INT_MAX; int left=0,right=0; int sum=0; while(right<原创 2021-04-18 13:03:51 · 44 阅读 · 0 评论 -
环形链表
判断环形链表并不难,这道题的难点在于如何找到环形链表的入口我们采用快慢指针法首先,定义两个指针fast和slow,让它们都等于头部节点之后,fast一次前进两格,slow一次前进一格,那么如果存在环形链表,它们一定会相遇至此,判断就结束了那么,如何找到入口呢?根据模拟的情况,这个时候让fast或slow等于head,然后再让两个指针都以每次前进一个单位的速度进行遍历,当它们相等的时候,该位置即链表的入口ListNode*fast=head; ListNode*slow=head原创 2021-04-18 10:18:53 · 29 阅读 · 0 评论 -
删除链表中的第n个节点
ListNode* dummyNode = new ListNode(0,head); ListNode* left = dummyNode;//左指针指向虚拟节点 ListNode* right = head;//右指针指向头部节点 for (int i = 0; i < n; i++)right = right->next;//右指针先移动n个位置 while (right)//当右指针不为空时 { .原创 2021-04-17 22:14:02 · 735 阅读 · 0 评论 -
链表反转(递归法)
class Solution {public: ListNode* reverseList(ListNode* head) { if (head == NULL || head->next == NULL)return head; ListNode* ret = reverseList(head->next);//递归 head->next->next = head; head->next = NULL原创 2021-04-17 21:18:51 · 646 阅读 · 0 评论 -
链表反转(双指针法)
首先,定义两个指针ListNode* left = NULL, * right = head;ListNode是自己定义的链表结构体先让左指针指向空,右指针指向第一个表每次让right的next指向left,完成一次局部反转,然后再让它们整体向前移动一位,重复这个过程,直到righ到达链表的末尾当然,实际过程中左指针一开始可以指向某一段开头,右指针也不一定指向空 ListNode*left=NULL,right=head; while(right!=NULL)原创 2021-04-17 16:29:03 · 409 阅读 · 0 评论 -
设计链表
https://leetcode-cn.com/problems/design-linked-list/题目的意思是需要写出一些函数来使链表可以实现一些目的,比如最基本的查找,添加,删除struct LinkedNode { int val; LinkedNode* next; LinkedNode(int val) :val(val), next(nullptr) {} };首先把链表主体写出来MyLinkedList() {原创 2021-04-17 14:53:23 · 173 阅读 · 0 评论 -
双指针法
https://leetcode-cn.com/problems/4sum/以上为题目链接如果采用暴力算法,那么时间复杂度会达到O(n4)的级别,不用想都知道会超时,所以,双指针法就成了一个可以采取的方法。双指针法的核心是移动指针,在本题中,我们先将数组进行排序,然后将双指针放置于左右两端,如果结果比target小,那么左指针右移;如果比target大,那么右指针左移。需要注意的是,为了确保没有重复输出,在每次输出前应该检查是否有重复,即做去重处理class Solution {public:原创 2021-04-13 22:42:57 · 97 阅读 · 0 评论