- 博客(367)
- 收藏
- 关注
原创 poj3522——Slim Span
题目大意:给出n个点m条边,选出n-1条边,使得图连通且最大边与最小边的权值差最小。分析:最小生成树。原题=>边从小到大排序后,枚举前m-n+1条边作为Krustal求最小生成树的最小边。因为krustal算法需要找出n-1条边,所以只有前m-(n-1)条可以作为每次krustal的最小边。代码:#include <iostream>#include <algorithm>using namespace std;struct Edge{ int
2020-08-10 21:16:40 234
原创 leetcode1047——Remove All Adjacent Duplicates In String
题目大意:一次遍历,删除字符串中所有的相邻重复字符,比如abbaca->ca分析:用字符串实现栈。遍历字符串,如果当前字符和栈顶相同就弹栈,否则入栈。代码:class Solution {public: string removeDuplicates(string S) { string ans; for (int i = 0;i < S.size();i++) { if (ans.size() &&
2020-08-02 09:57:21 196
原创 leetcode402——Remove K Digits
题目大意:字符串num代表一个非负整数,删除其中k位使得数字变得最小,输出不能出现前导零和空串。分析:单调栈+贪心。贪心策略:从左往右删,如果左邻居>当前位,就应该删掉左邻居,这样才能使数字变最小。栈:遍历字符串,当前位小于栈顶元素时弹栈,否则入栈。可以直接用字符串来实现这个单调栈。注意:1.可能遍历结束时还没删够k位,需要直接删掉末尾几位,也就是直接截取字符串的前size-k位。2.可能删除导致出现了前导零,比如10200,因此要删掉前导零再返回。3.当k>=size,会删除所有数字,此时
2020-07-31 20:37:08 214
原创 leetcode384——Shuffle an Array
题目大意:打乱无重复元素的数组分析:Fisher-Yates洗牌算法。遍历数组的每个元素,将当前元素和随机选出的下标所指的元素互相交换。代码:class Solution { vector<int> data;public: Solution(vector<int>& nums) { data = nums; } /** Resets the array to its original configur
2020-07-31 19:45:04 139
原创 leetcode662——Maximum Width of Binary Tree
题目大意:二叉树中有空节点,求它的最大宽度,每层的宽度定义为两端非空节点之间的长度,空节点也计入长度分析:BFS。队列中记录节点和节点位置的pair信息。每层计算两端点的位置差即可。代码:class Solution {public: int widthOfBinaryTree(TreeNode* root) { if (!root) return 0; queue<pair<TreeNode*, unsigned long long>
2020-07-30 21:53:41 130
原创 leetcode342——Power of Three
题目大意:判断整数是否是3的幂次方分析:整数限制。3的幂次方在int范围内最大的是1162261467,因为log3(INT_MAX)=19.56,3^19=1162261467。由于3是质数,所以1162261467的除数都是3的幂次方,也就是1162261467除以3余数应为0。所以3的幂次方满足:1162261467 % num = 0。代码:class Solution {public: bool isPowerOfThree(int n) { return
2020-07-29 15:11:32 115
原创 leetcode342——Power of Four
题目大意:判断整数是否是4的幂次方分析:位运算。在leetcode231的基础上,num是2的幂次方需要满足二进制最高位为1其余都是0,也就是(num & (num - 1)) == 0,而4的幂次方是就是2的偶数幂次方,也就是最高位的1在偶数位上(0、2、4...位),所以num&(101010...10)应该为0,二进制(101010...10)对应十六进制0xaaaaaaaa。代码:class Solution {public: bool isPowerOfFo
2020-07-29 15:04:21 143
原创 leetcode231——Power of Two
题目大意:判断整数是否是2的幂次方分析:二进制位运算方法一:n不断除以2再模2判断余数是否为0,时间复杂度O(logn)。方法二:位运算,2的幂次方数是由2^0不断×2得到的,也就是1不断左移的过程,所以2的幂次方数的二进制都是最高位为1,其余位都是0的。而这个数-1之后变成最高位为0,其余位都是1。所以有n&(n-1)=0。注意n≤0时一定返回false,所以先排除,不然测试数据有INT_MIN,INT_MIN-1就会造成溢出问题。代码:class Solution {pu
2020-07-29 14:37:58 127
原创 笔试——交替01子序列
题目大意:给出长度为n的01组成的字符串,可以选择任意的连续片段做翻转(0变1/1变0),问修改后最大01交替子序列的长度(子序列意味着可以不连续)分析:找规律。如果原串中只有1个00(或11)出现=>翻转后可以得到最长n位的交替序列;如果有多个00(或11)出现,统计相邻位不同的数cnt,可以得到最长cnt+2位的交替序列。也就是需要遍历字符串记录相邻两位不相同的位数,例如10100010,其中有6位和它的相邻位(前一位)不同,意味着有多个连续的00(或11),那么答案为6+2;例如101010
2020-07-08 17:41:02 3070 1
原创 笔试——石头半径升序的最小操作次数
题目大意:给出石头们的半径,每次可以选一块石头放在剩下n-1个石头的最左或最右侧,求使得半径升序的最小操作次数分析:例如:输入:6 3 2 1 4 6 5;输出:3(2左1左6右)代码:...
2020-07-08 16:49:26 3034 1
原创 leetcode162——Find Peak Element
题目大意:在给出的数组中找出峰值的索引,假设nums[-1]=nums[n]=-∞,如果有多个返回任意一个即可,要求时间复杂度O(logn),。分析:二分查找。时间复杂度O(logn)自然联想二分查找。利用好题里的-∞条件来不断缩小搜索空间:拿到mid,判断nums[mid]和右侧数据的大小关系,如果降序,说明峰值在[left,mid];如果升序,说明峰值在[mid+1,right]。代码:方法一:线性查找。class Solution {public: int findPeak
2020-07-07 16:04:28 136
原创 leetcode150——Evaluate Reverse Polish Notation
题目大意:根据逆波兰表达式法,求表达式的值分析:栈。token为数字时入栈,token为运算符时弹出两个栈顶元素,运算后入栈。注意题目给的string,string转int用stoi(str)。代码:class Solution {public: int evalRPN(vector<string>& tokens) { stack<int> s; for (string token : tokens) {
2020-07-05 22:04:02 153
原创 leetcode140——WordBreakⅡ
题目大意:给出字符串s和字典,用空格拆分字符串s,使得成为一个或多个在字典中出现的单词,找出所有可拆分的解。分析:动态规划。先用leetcode139判断是否有解。有解的基础上:状态:二维数组dp[i]——s[0~i-1]的所有可拆分情况(一堆字符串)初始化:vector<string>均为空结果:dp[s.size()]转移方程:如果s[0~i-i]有解——if(!dp[i].empty()) ,就遍历字典,依次拿出word匹配,如果有匹配当前s[i]的word:
2020-07-05 15:08:13 161
原创 leetcode128——Longest Consecutive Sequence
题目大意:求未排序数组中的最长连续序列的长度,要求时间复杂度为O(n)。例如[100,4,200,1,3,2],len=4。分析:哈希表unordered_set。原题=>遍历数组时需要判断某个数(大一或小一)是否存在=>用哈希表(查询O(1))。num依次插入set,遍历set,对每个num都尝试匹配num+1,num+2...是否存在。最坏还是O(n²)。所以加上“跳过逻辑”:存在num-1时跳过,也就是只有num为连续序列的第一个数的时候,才开始内层循环匹配。达到了O(n)
2020-07-03 15:21:59 140
原创 leetcode687——Longest Univalue Path
题目大意:求二叉树中每个节点值都相同的最长路径长度,长度=节点间边数。分析:dfs。维护全局maxLen,对每个节点求最长路径。经过该节点的最长路径=leftLen+rightLen。LeftGain、RightGain分别为左右子节点的最大贡献值。节点最大贡献值=节点值+max(leftGain,rightGain),因为贡献值代表该节点左侧路径or右侧路径二选一,选择一条贡献值最大的继续往该节点的父节点贡献。代码:/** * Definition for a binary tree no
2020-07-02 11:28:35 154
原创 leetcode124——Binary Tree Maximum Path Sum
题目大意:求二叉树中最大路径和,路径可以从任意任意节点出发,到任意节点结束。分析:dfs。维护全局maxSum,对每个节点求最大路径。经过该节点的最大路径=节点值+leftGain+rightGain。LeftGain、RightGain分别为左右子节点的最大贡献值。节点最大贡献值=节点值+max(leftGain,rightGain),因为贡献值代表该节点左侧路径or右侧路径二选一,选择一条贡献值最大的继续往该节点的父节点贡献。代码:/** * Definition for a binar
2020-07-01 16:57:10 154
原创 leetcode13——Roman to Integer
题目大意:将罗马数字字符串转换成整数分析:方法一:最简单的思路。switch case从左到右依次判断字符,将当前tmp加入ans。方法二:转换问题本质。原题=>当左边字母<右边字母,就做减法,否则就做加法。代码:方法一:class Solution {public: int romanToInt(string s) { int ans = 0; int index = 0; while(index < s
2020-06-30 15:27:02 146
原创 leetcode739——Daily Temperatures
题目大意:给出每日气温数组,求出每天之后等待几天,气温会升高分析:栈。用栈记录遍历的索引,遍历时只要当前元素大于栈顶索引所指气温值,说明栈顶元素的答案找到了,记录答案并弹栈,循环直到栈顶索引所指气温值不小于当前遍历气温,然后压入当前索引即可。代码:class Solution {public: vector<int> dailyTemperatures(vect...
2020-04-06 10:01:06 142
原创 leetcode记录
1 2 3 4 5 7 8 9 10(没做:6)11 14 15 16 17 18 19 20(没做:12 13)21 22 23 24 25 26 27 28 29 3031 32 33 34 35 36 37 38 39 4041 42 43 44 45 46 47 48 49 5051 52 53 54 55 56 57 58 59 6061 62 63 64 65 ...
2020-04-06 09:46:16 519
原创 leetcode621——Task Scheduler
题目大意:给出字符数组表示任务列表,26个大写字母代表26种任务。给出整数n,执行相同任务之间必须有长度为n的冷冻时间。CPU在每个单位时间可以选择执行任务或者待命,求完成这些任务所需要的最短时间。分析:方法一:贪心法。贪心策略:尽早安排出现次数较多的任务。因为如果把他们留在后面,就会造成大量的冷冻时间。做法:每一轮选择剩余出现次数最多的不超过n+1个任务来执行,这样保证了冷冻时间。在每一轮中...
2020-04-05 09:58:32 109
原创 leetcode617——Merge Two Binary Trees
题目大意:合并两棵二叉树变成一棵树,合并时重叠的两节点值相加作为新节点,否则不为NULL的节点作为新节点分析:dfs。先合并当前节点:有一方为空就直接返回另一方(这个分支无需再合并了),两节点都存在就值相加。然后递归合并左右子树即可。代码:/** * Definition for a binary tree node. * struct TreeNode { * int...
2020-04-04 09:59:05 132
原创 leetcode581——Shortest Unsorted Continuous Subarray
题目大意:找出最短的子数组,子数组排序后能让整个数组升序(非降序)分析:方法一:排序后比较,第一个和最后一个值不相等的位置就是子数组的左右界限。时间O(nlogn),空间O(n)。方法二:题意=>找到乱序子数组的左右界限=>遍历一次找到逆序子数组的最小值(它的正确位置代表子数组的左界限)和最大值(它的正确位置代表子数组的右界限)=>找到两个最值之后,从左往右找最小值本该放...
2020-04-03 15:39:50 155
原创 leetcode538/1038——Convert Bst to Greater Tree/Binary Search Tree to Greater Sum Tree
题目大意:把二叉搜索树转化成累加树,使得每个节点的值是原来的节点值加上所有大于它的节点值之和分析:题意转化成=>从右往左中序遍历,并且在遍历过程中记录前一个访问节点的值代码:/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; ...
2020-04-01 11:35:43 139
原创 leetcode494——Target Sum
题目大意:在数组中每个数前面添‘+’或‘-’,使得数组所有元素加和等于目标和,求添加符号的方法数(数组所有元素加和不超过1000)分析:方法一:dfs。每个位置的数有正负两种情况,递归数组中的每个数,遍历到数组末尾时判断加和是否等于目标和即可。时间复杂度为O(2^n)。方法二:动态规划。背包问题。状态:dp[i][j + 1000]——用nums[0~i]组合成j的方法个数。由于j可能...
2020-03-31 10:33:46 106
原创 leetcode461——Hamming Distance
题目大意:计算两个整数的汉明距离(两个数的二进制位中不同的位置个数)分析:位运算。计算汉明距离:只要统计两个数的异或中有几个1即可。比如1(0001)和4(0100),异或后(0101)就能显示出有几位不同。异或操作——0^1=1,0^0=0。方法一:库函数。C++:return bitset<32>(x^y).count();JAVA:return Integer.bitco...
2020-03-29 10:07:31 148
原创 leetcode442——Find All Duplicates in an Array
题目大意:大小为n的数组中,每个数满足1≤a[i]≤n,有些元素出现了两次,有些元素出现了一次,找到重复数字。要求时间复杂度O(n),空间复杂度O(1)。分析:和leetcode448类似。遍历数组的过程中标记相反数,当要标记位置的数值已经为负时,就说明该位置代表的数字已经出现过代码:class Solution {public: vector<int> fin...
2020-03-28 10:29:26 104
原创 leetcode448——Find All Numbers Disappeared in an Array
题目大意:大小为n的数组中,每个数满足1≤a[i]≤n,有些元素出现了两次,这意味着1~n中有些数字没有出现在数组中,找到这些数字。要求时间复杂度O(n),空间复杂度O(1)。分析:由于要求不使用额外空间,所以需要利用好数组内元素取值范围这个特点。由于数组内元素值在1~n之间,所以可以利用元素值对应的下标做标记,来记录哪些值是出现过的。第一步:遍历数组,遍历时将nums[abs(nums[...
2020-03-28 10:21:34 124
原创 leetcode438——Find All Anagrams in a String
题目大意:在字符串s中找出字符串p的所有字母异位词的首字母下标(字母相同,排列不同的字符串)分析:滑动窗口双指针+哈希表。类似leetcode76。遇到子串匹配的问题基本就用滑动窗口解决。leetcode76:s中找到最短子串,使得包含p中所有字母。本题:s中找到与p长度相同的子串,使得包含p中所有字母。所以只需要再76的基础上改动,不需要维护最小长度了。当找到满足76的子串时,只需要...
2020-03-27 10:22:07 108
原创 leetcode437——Path SumⅢ
题目大意:找出二叉树中路径和等于目标和的路径个数,节点为整数(可能为负),路径起点不一定为根节点,但是方向向下分析:二叉树dfs。相比leetcode112、113要注意两点:节点数值可能为负,路径起点可以任选。因为路径起点任选,所以要以树中每一个节点为起点dfs,也就是用countHelper统计以该点为起点的路径条数,然后递归统计左右节点为起点的路径条数。countHelper统计...
2020-03-26 10:48:26 120
原创 leetcode416——Partition Equal Subset Sum
题目大意:判断能否将数组分割成两个等和的子集,元素均为正整数。分析:动态规划背包问题。原问题转化为是否能在数组中取出一些数,使得和为数组元素总和的一半。状态:dp[i][j]——nums[0~i]可选,是否能使得选出元素的总和为j。初始化:dp[0][0]=true,如果nums[0]≤数组元素总和的一半,那么dp[0][nums[0]] = true,因为第一个元素可选时,它只能让容...
2020-03-25 10:14:42 110
原创 leetcode406——Queue Reconstruction By Height
题目大意:给出二维数组代表打乱顺序的一队人,每个人由(身高h,排在他前面身高大于等于他的人的个数k)表示,重排队列。分析:贪心算法。由于矮子对高个子来说是“看不见”的(矮子插入在高个子前面不会影响高个子的k值),所以采取每次先放高个子的贪心策略,如果身高相同,按k值递增排序。这样的贪心策略能确保每一步插入都使得当前队列是符合要求的。做法:第一步:对people排序,先按h降序,再按k升序。...
2020-03-24 09:59:13 91
原创 leetcode394——Decode String
题目大意:将字符串按规则解码,k[str]的编码规则为k个str相连,例如3[ab2[c]2[a]],解码后为abccaaabccaaabccaa分析:栈。这道题重点在于需要识别嵌套的[],所以需要用栈。遍历字符串,维护当前的k和str:当前字符为数字时,更新k=k*10 + 当前字符值;当前字符为字母时,更新str=str + 当前字符;当前字符为'['时,将<k,str&...
2020-03-23 10:43:35 123
原创 leetcode347——Top K Frequent Elements
题目大意:找出数组中出现频率前k高的元素们分析:TOPK问题。类似leetcode215,使用堆来维护topk,这道题还需要使用哈希表统计元素频率。时间复杂度O(nlogk),空间复杂度O(k)。代码:class Solution { struct cmp{ bool operator()(pair<int,int> p1,pair<int,...
2020-03-20 09:50:07 124
原创 leetcode309——Best Time to Buy and Sell Stock with Cooldown
题目大意:给出股票价格数组,可以进行多次买卖,但是卖出的第二天要休息,求最大收益分析:动态规划。状态:dp[i][0]——第i天不持有股票时获得的最大收益;dp[i][1]——第i天持有股票时获得的最大收益初始化:dp[0][0]=0,dp[0][1]=-0x3f3f3f3f结果:dp[n - 1][0]状态转移方程:dp[i][0] = max(dp[i-1][0], ...
2020-03-19 12:47:38 136
原创 leetcode121——Best Time to Buy and Sell Stock
题目大意:给出股票价格数组,只允许买卖一次,求最大收益分析:股票问题采用动态规划。但是这道入门题只允许买卖一次,有更简单的方法——一次遍历:遍历数组时维护当前的最低点,每一天都计算当天与当前最低点的差值,这就是收益,取收益最大值即可。代码:class Solution {public: int maxProfit(vector<int>& prices)...
2020-03-19 11:40:12 146
原创 leetcode287——Find the Duplicate Number
题目大意:数组大小n+1,数组内元素范围[1,n],求出重复的元素分析:面试中一般采用前几种做法。快慢指针的做法虽然很好,但是一般想不出来,除非你之前做过这道题。方法一:排序后找相邻元素重复的即可。时间复杂度O(nlogn)+空间复杂度O(1)。方法二:哈希表判重。时间复杂度O(n)+空间复杂度O(n)。方法三:二分查找。时间复杂度O(nlogn)+空间复杂度O(1)。二分查找O(...
2020-03-18 11:03:36 148
原创 leetcode120——Triangle
题目大意:求数字三角形自顶向下的最小路径和分析:和poj3176类似。两道题都可以空间优化,用一维dp数组即可。代码:class Solution {public: int minimumTotal(vector<vector<int>>& triangle) { int n = triangle.size(); ...
2020-03-17 11:14:08 119
原创 leetcode283——Move Zeroes
题目大意:原地将数组变化成所有零在数组末尾,其余元素保持原顺序分析:双指针。方法一(自己的):zero指针指向0,non_zero指针指向zero后的第一个非零,交换两个指针并且双指针后移。循环这个过程。方法二:题目相当于要把所有非零元素移到数组前面。所以遍历数组,遇到非零元素就赋值给最后一个找到的非零元素的后一位。这样剩余的空位填0即可。代码:方法一:class ...
2020-03-17 10:47:04 98
原创 leetcode253——Meeting Rooms II
题目大意:给出一些会议的开始和结束时间,求出需要的最少会议室个数分析:map。和leetcode732其实是一道题。都是区间重叠问题,732是求最大重叠数,而这道题中需要的最少会议室个数其实就是区间最大重叠数。用一个map(自动排序)记录端点的出入度,遍历map的过程中得到的端点度的加和最大值就是最大重叠数。代码:class Solution {public: int ...
2020-03-16 10:28:11 411
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人