算法
I_ren
这个作者很懒,什么都没留下…
展开
-
面试常见算法之堆排序
#include <vector>#include <iostream>#include <algorithm>using namespace std;int heap_size;void heapify(vector<int> &nums, int i){ // 检查节点i的子孩子是否大于节点i int left = 2 * i + 1; int right = 2 * i + 2; int largest = i; if.原创 2020-08-24 10:49:14 · 332 阅读 · 0 评论 -
面试常见算法之二叉树中序遍历
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public: vector<int> inorderTrave.原创 2020-08-22 15:32:56 · 211 阅读 · 0 评论 -
面试常见算法之二叉树后续遍历(反向输出前序遍历的镜像版本)
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public: vector<int> postorderTra.原创 2020-08-22 15:21:57 · 489 阅读 · 0 评论 -
面试常见算法之快排
#include <vector>#include <iostream>using namespace std;// partition实现int partition(vector<int>& nums, int left, int right){ // 当数组只有一个元素时直接返回该元素index if (left == right) return left; // 简单地取第一个数作为pivot int pivot = nums[.原创 2020-08-21 15:01:31 · 240 阅读 · 0 评论 -
Leetcode 416. Partition Equal Subset Sum
令dp[i][j]表示是否能从前i个数字中选出和为j的数, dp[i][j] = dp[i-1][j] || dp[i-1][j-nums[i]]class Solution {public: bool canPartition(vector<int>& nums) { int n = nums.size(); int total = accumulate(nums.begin(), nums.end(), 0); if..原创 2020-06-01 12:46:57 · 151 阅读 · 0 评论 -
Leetcode 410. Split Array Largest Sum
dp[i][j] 表示将数组中前j个数字分成i组所能得到的最小的各个子数组中最大值i的范围是[1, j]计算dp[i][j]时,对于所有1<=k<=j-1:最后一个分组为nums[k+1]…nums[j]时,此时各个子数组中最大值为max(sum(nums[k+1:j+1]), dp[i-1][k])遍历k得到最小的dp[i][j]最终返回 dp[m][n] 即可class Solution {public: int spli...原创 2020-05-28 18:26:15 · 202 阅读 · 0 评论 -
Leetcode 403. Frog Jump
dp[i] = […]表示在第i块stone上允许跳出的步伐大小dp[i]计算:遍历stone[1]…stone[i-1]如果能从stone[k]跳到stone[i],则向dp[i]加入新的gap-1,gap,gap+1,注意<=0的数不添加。最后检查dp[-1]的长度是否不为0class Solution {public: bool canCross(vector<int>& stones) { if (stones...原创 2020-05-25 10:58:26 · 156 阅读 · 0 评论 -
Leetcode 391. Perfect Rectangle
正确的答案应当满足:1.最大的长方形面积等于所有长方形的面积之和2.除了四个顶点出现的次数为1,其他点出现次数必须为2/4次class Solution {public: bool isRectangleCover(vector<vector<int>>& rectangles) { //记录四边形顶点出现次数 unordered_map<string, int> vertex_count; //记录总面积 int ...原创 2020-05-24 14:31:13 · 188 阅读 · 0 评论 -
Leetcode 390. Elimination Game
第一次删除时,所有数字都是偶数,除以2之后,得到了1~n/2的连续数组。对于1~n/2的序列,从右向左删除,原来的结果为该lastRemaining(n/2)镜像结果的两倍。class Solution {public: int lastRemaining(int n) { if (n == 1) return 1; // 1 2 3 4 5 ... n // TO // 2*1 2*2 ...原创 2020-05-21 16:40:12 · 260 阅读 · 0 评论 -
Leetcode 377. Combination Sum Ⅳ
dp[i]表示target为i时的组合数。对于每一个数i,遍历 nums 数组,dp[i] += dp[i-nums[j]] + nums[j] (满足nums[j] <= i)。class Solution(object): def combinationSum4(self, nums, target): """ :type nums: List[int] :type target: int :rtype: ...原创 2020-05-20 12:00:42 · 173 阅读 · 0 评论 -
Leetcode 375. Guess Number Higher or Lower Ⅱ
dp[i][j]表示从i~j中选择一个数字,至少需要多少钱才能猜出这个数字。首先,如果只有1个数字,dp[i][i]=0 如果有两个数字,则猜第1个数字,dp[i][i+1] = i 如果有3个数字,则猜中间的数字,dp[i][i+2] = i+1对于dp[i][j]而言,可以先猜k(i<=k<=j),然后根据大小情况猜dp[i][k-1]或者dp[k+1][j]则dp[i][j] = min( k + max(dp[i][k-1],...原创 2020-05-18 14:26:50 · 126 阅读 · 0 评论 -
Leetcode 373. Find K Pairs with Smallest Sums
将nums1与nums2组成的所有组合用矩阵M的形式表示,M[i][j]表示nums[i]+nums[j]用priority queue数据结构进行维护,首先将nums[0] + nums[1]加入pq中,每次pop出一个元素时,将该元素右边和下边未访问过的元素加入pq中。from Queue import PriorityQueue as PQclass Solution(object): def kSmallestPairs(self, nums1, nums2, k): ..原创 2020-05-17 21:38:24 · 202 阅读 · 0 评论 -
Leetcode 372. Super Pow
两个先验知识:1. ab%k = (a%k)(b%k)%k2. a^(mn)%k = (a^m%k)^n%k令f(a, b)=a^b % k,则 f(a,1234567) = f(a, 1234560) * f(a, 7) % k = f(f(a, 123456),10) * f(a,7)%k;class Solution(object): def subPow(self, a, b): #0<= b <= 10 if b == 0: ..原创 2020-05-14 17:22:29 · 147 阅读 · 0 评论 -
Leetcode 368. Largest Divisible Subset
先对数组进行排序,用动态规划的思想,dp[i]表示以nums[i]结尾的最长的divisible subset。首先dp[0] = [nums[0]]更新dp[i]时,如果num[i]为之前某个数num[j](j<i)的倍数,则存在以nums[i]结尾,长度为dp[j] + 1的divisible subset。遍历nums[0]...nums[i-1],找出以nums[i]结尾的最长divisible subset。class Solution(object): def l..原创 2020-05-13 12:59:54 · 172 阅读 · 0 评论 -
Leetcode 365. Water and Jug Problem
当z为GCD(x,y)的倍数时,返回True裴蜀定理:如果d为a,b的最大公约数,则存在整数x,y使得:ax+by=d且d为最小的可以被写成ax+by的正数其他可以被写成ax+by的整数都是d的倍数当a或b为负数时,说明正在从一个杯子中倒出x杯子或y杯子的水同理,如果a或b为正数时,说明正在向杯子中导入x杯子或y杯子的水。例如:x=5, y=6, z=3其中,z = 3GCD(x,y),因此可以成功z = 3 * y - 3 * x说明需要倒入3次6容量的杯子,倒..原创 2020-05-11 15:42:50 · 171 阅读 · 0 评论 -
Leetcode 363. Max Sum of Rectangle No Larger Than K
对于一维数组,求每个数从数组第一个元素开始的累计和sum[i],对于每一个数num[i]而言,要找到sum[i] - sum[j]<=k,且sum[j]最小的数,用java Treemap进行二分查找即可。而二维数组,可以进行遍历,将相同列的数累加,转换成一维数组的形式。解决row>column的方式:按照列的方式进行累加和的计算以及二分查找。class Solution { public int maxSumSubmatrix(int[][] matrix, i...原创 2020-05-09 13:44:32 · 161 阅读 · 0 评论 -
Leetcode 354. Russian Doll Envelopes
首先对envelopes数组按照h升序,w降序进行排序,然后直接对w数组求解longest increasing subsequence即可。longest increasing subsequence问题:假设dp[i]表示长度为i的increasing subsequence结尾元素最小值,显然dp[i] >= dp[i-1]遍历数组nums[i]时: 如果num...原创 2020-05-07 12:15:56 · 188 阅读 · 0 评论 -
Leetcode 352. Data Stream as Disjoint Intervals
显然,Disjoint Intervals需要通过二分搜索的方式进行维护。插入一个数n时,假设k1([k1,v1]为<=n的最大的作为intervals开始的数,k2([k2,v2])为>=n的最小的作为intervals开始的数,可能会发生四种情况:1. v1 + 1 == n == k2 - 1,此时,需要将[k1,v1], [k2, v2]区间merge为[k1, v...原创 2020-05-06 12:08:50 · 184 阅读 · 0 评论 -
Leetcode 338. Counting Bits
递归方法:f[n] = f[n/2] + f[n%2]class Solution(object): def countBits(self, num): """ :type num: int :rtype: List[int] """ dp = [0,1,1] if num <=...原创 2020-05-05 11:32:37 · 116 阅读 · 0 评论 -
Leetcode 336. Palindrome Pairs
有4种情况能够组成回文对:Case1:如果s1为空字符串,且s2为回文字符串,则s1+s2, s2+s1均为回文Case2:如果s1为s2的逆字符串,则s1+s2, s2+s1均为回文Case3:如果s1[0:cut]为回文,且存在s2为s1[cut+1:]的逆字符串,则s2+s1为回文Case4:同理,如果s1[cut+1:]为回文,且存在s2为s1[0:cut]的逆字符串,...原创 2020-05-04 12:58:50 · 137 阅读 · 0 评论 -
Leetcode 330. Patching Array
假设current为[0,n]中最小的不能组成的数,[0,current)能够组成,如果存在num <= current,则可以将num加入到[0,current)中组成[0, current + num),否则,必须加入current这个数到数组中,此时能够组成的数变为[0,current + current)。class Solution(object): ...原创 2020-05-03 12:28:51 · 167 阅读 · 0 评论 -
Leetcode 329. Longest Increasing Path in a Matrix
维护dp数组,dp[i][j]表示以(i,j)为起点的最长递增路径的长度,初始时所有值都为0。当采用dfs递归调用时,遇到某个位置(x,y)!=0,则可以直接返回dp[i][j]。class Solution: def dfs(self, i, j): nebr = [[i+1, j], [i-1,j], [i, j+1], [i, j-1]] m...原创 2020-05-02 11:47:57 · 126 阅读 · 0 评论 -
Leetcode 321. Create Maximum Number
这道题的步骤如下:1.将k拆分成两个数i,k-i,分别表示从nums1,nums2中取出的数个数2.从nums1, nums2中取出相应个数的最大的数3.将这两个最大的数merge成一个数4.遍历所有的k拆分情况,得到最终Maximum Number对于步骤2,如何从一个数组中取出给定个数(记作M)的最大数,需要用递减栈的思想:初始化stack, 遍历数组中的数nums...原创 2020-04-28 12:38:58 · 152 阅读 · 0 评论 -
Leetcode 319. Bulb Switcher
对于bulb[1],只有第一轮会被按,最后为on对于bulb[2],第(1,2)轮会被按,最后为off对于bulb[3],第(1,3)轮会被按,最后为off对于bulb[4],第(1,2,4)轮会被按,最后为off......显然,对于bulb[i]而言,如果i不是完全平方数,则会按的轮数一定为偶数,最后状态为off。因此,要找最后为on的bulbs,只需要知道<=n...原创 2020-04-27 11:56:14 · 247 阅读 · 0 评论 -
Leetcode 318. Maximum Product of Word Lengths
由于words只包含了26个小写字母,而int型有32位,可以用26位表示一个单词中是否出现某个小写字母。比如,"a"可以表示为1,"ab"表示为11。这样在检查两个单词是否有相同字母时,只需要将它们对应的数值作按位与操作,查看结果是否为0即可。class Solution(object): def maxProduct(self, words): """ ...原创 2020-04-25 11:52:33 · 184 阅读 · 0 评论 -
Leetcode 315. Count of Smaller Numbers After Self
这道题采用的是merge sort的思想。假设已知数组左半部分和右半部分Count of Smaller Numbers After Self结果以及排序结果,还需要知道merge过程中左半部分与右半部分inversions pairs。在merge过程中,假设i为左半部分数组a的指针,j为右半部分数组b的指针。1.在任意一步中,如果b[j] <= a[i],则将b[j]放入...原创 2020-04-24 12:36:49 · 193 阅读 · 0 评论 -
Leetcode 310. Minimum Height Trees
这道题的思路是每次都从图中将叶子节点去掉,直到最后只剩下1个或者2个节点时,这样的节点为根节点。需要用set(字典)数据结构存储每个节点的邻居。查找叶子节点时,即查找len(set) = 1的节点。去掉叶子节点时,需要将它们相邻节点中set存储的叶节点邻居也去掉。# 代码来自leetcode https://leetcode.com/problems/minimum-hei...原创 2020-04-23 11:26:20 · 148 阅读 · 0 评论 -
Leetcode 309. Best Time to Buy and Sell Stock with Cooldown
这道题用的是dp的思想,用buy, sell, cooldown记录当前这些状态下最多的profit。对于day i 而言: sell[i] = buy[i-1] + prices[i] buy[i] = max(muy[i-1], cooldown[i-1] - prices[i]) cooldown[i] = max(cooldown[i-1]...原创 2020-04-20 11:51:44 · 256 阅读 · 0 评论 -
Leetcode 300. Longest Increasing Subsequence
这道题最优解法是利用dp + 二分,可以达到O(nlogn)的时间复杂度。dp[i]存放长度为i+1的递增子序列最小的末尾数字。比如,nums = [4, 5, 6, 3],则所有的递增系列为:len = 1 :[4], [5], [6], [3] => dp[0] = 3len = 2 : [4, 5], [5, 6] => dp[1] = 5...原创 2020-04-18 11:48:04 · 130 阅读 · 0 评论 -
Leetcode 295. Find Median from Data Stream
这道题需要用一个最大堆和最小堆维护数组,满足最大堆的值<=最小堆的值,且最大堆数量 = 最小堆数量/最小堆数量+1。这样就能直接利用最大堆和最小堆顶部的数字得到中位数。添加时:1. 如果最大堆数量 = 最小堆数量,则应该增加最大堆数量 case 1. 添加的元素<=最大堆顶部元素,可以直接添加入最大堆 case 2. 添加的元素>最大堆顶部...原创 2020-04-16 12:23:08 · 128 阅读 · 0 评论 -
Leetcode 287. Find the Duplicate Number
这道题最简单的方式是用二分搜索。首先设置head, tail指针分别指向1和n,head <= duplicate number <= tail。计算mid = (tail + head)/2,遍历数组查找<=mid的数的个数。如果大于mid个,说明重复元素在[head, mid]之间,更新tail = mid;否则说明重复元素在[mid + 1, tail]之间,更新hea...原创 2020-04-15 11:30:56 · 178 阅读 · 1 评论 -
Leetcode 264. Ugly NumberⅡ
这道题需要将前n个ugly number计算出来,计算的过程中,维护三个指针,分别对应2、3、5乘上第几个最大的ugly number时,没有超过当前ugly number最大值。比如当前计算出了10个ugly number [1,2,3,4,5,6,8,9,10,12]对应的第一个指针,2 * 6 <= 12,6 = array[5],因此第一个指针point1 = 5对应...原创 2020-04-12 12:12:27 · 125 阅读 · 0 评论 -
Leetcode 260. Single Number Ⅲ
首先有这样一个问题:如果有一个数组,除了一个数字出现了一次,其余数字都出现了两次,求这个出现了一次的数字。这个问题的解法只需要将数组中所有的数字都进行异或,最后的结果就是只出现了一次的数字。原因是任何两个相同的数字异或结果都为0,并且异或满足交换律。而对于数组中出现了2个只出现一次的数字,将所有数字都异或之后的结果为这两个数字的异或。这个异或结果一定不为0,因此可以从中任意选择某一个不...原创 2020-04-11 12:05:49 · 125 阅读 · 0 评论 -
Leetcode 235. Lowest Common Ancestor of a Binary Search Tree
这道题采用递归的方法,如果根节点在min(p,q)和max(p,q)之间,说明根节点已经是lowest common ancestor。否则,如果根节点<min(p,q),说明lowest common ancestor在根节点的右子树中;反之在根节点的左子树中。# Definition for a binary tree node.# class TreeNode(obje...原创 2020-04-10 11:43:40 · 87 阅读 · 0 评论 -
Leetcode 222. Count Complete Tree Nodes
这道题用递归的思想,如果一棵全满的树,只要知道它的高度就能够计算出它节点的个数(1<<0 + 1<<1 + 1<<2... + 1<<height)。因此,对于给定的不完全二叉树,检查根节点的左子树是否全满(这里通过两个指针,一个指针沿着左孩子一路向下,一个指针沿着右孩子一路向下,当沿着右孩子的指针为空时,查看沿着左孩子的指针是否为空)...原创 2020-04-09 11:28:08 · 99 阅读 · 0 评论 -
Leetcode 215. Kth Largest Element in an Array
这道题的两种做法:1.heap构建一个最大为k的最小堆hep,记录nums中k大元素遍历nums数组时,如果heap大小<k,则将nums[i]加入heap;否则当nums[i] > heap顶端元素时,将nums[i]加入heapfrom Queue import PriorityQueue as PQclass Solution(object): ...原创 2020-04-08 12:09:28 · 103 阅读 · 0 评论 -
Leetcode 214. Shortest Palindrome
这道题求的实际上是字符串s从头部开始的最长回文子字符串,然后将剩余部分reverse一下拼接在头部即可。首先需要了解一下KMP算法(https://www.cnblogs.com/zhangtianq/p/5839909.html)然后只需要构造ss = s + '#' + reverse(s),对ss求KMP得next table(这里注意next table长度需要为len(ss...原创 2020-04-06 11:29:19 · 118 阅读 · 0 评论 -
Leetcode 204. Count Primes
这道题建立一个nums[n+1]的数组,num[i]表示i是否为prime number,初始化为True。遍历range(2, n),每次将nums[i*2], nums[i*3]...nums[i*k] (i*k <= n)设置为False。最后返回nums数组中≥2且值为True的数字。这里有个优化的地方:如果遍历到i时,发现nums[i]已经为0了,说明之前已经遇到了...原创 2020-04-03 11:50:37 · 91 阅读 · 0 评论 -
Leetcode 172. Factorial Trailing Zeorses
要使乘积末尾有0,则乘积得是10的倍数,即必须存在因数2和5。显然阶乘中因数2的数量永远比5多,因此只需要计算质因数中5的个数即可。利用递归式 trailingZeroes(n) =trailingZeroes(n/5) + n/5class Solution(object): def trailingZeroes(self, n): """ ...原创 2020-04-02 11:29:40 · 102 阅读 · 0 评论 -
Leetcode 229. Majority Element Ⅱ
这道题用拓展的Moore投票算法,需要记录2个candidate,步骤如下:遍历nums数组: 如果遇到等于candidate1/candidate2的数,则相应的count加1 否则:1.如果candidate1/candidate2为空,则将其设置为当前nums[i],并将count设置为1 2.否则count1/coun...原创 2020-04-02 11:23:44 · 120 阅读 · 0 评论