LeetCode
Variable_ZQ
这个作者很懒,什么都没留下…
展开
-
LC5454.统计全1子矩阵(矩阵统计)
问题解题技巧:矩阵枚举上下边界,用一个sum维护上下边界内每一列的列和,压成一维数组如果上下边界的差值diff等于这一列的列和sum,则这一列可以用来做矩阵由于会存在连续并排的列,因此还需要一个cnt统计连续列的个数,每多一个列加在连续块的后面则cnt需要+1,此时的cnt就是这个列贡献的全1子矩阵的个数,res需要加上这个列贡献的全1矩阵。class Solution { public int numSubmat(int[][] mat) { int n = mat原创 2020-07-05 21:39:04 · 687 阅读 · 0 评论 -
LC480.滑动窗口中位数(双堆+滑动窗口)
问题题解题目同数据流的中位数一样,都是使用双堆维护,详细可以看那一题。不同点在于,给数据流加了一个滑动窗口,数据需要从窗口中移除,因此只需要判断要被移除的元素是在哪个堆中即可,找到后删除,heap删除元素的时间复杂度为O(n)class Solution { public double[] medianSlidingWindow(int[] nums, int k) { PriorityQueue<Integer> maxHeap = new Priorit原创 2020-07-01 20:37:51 · 206 阅读 · 0 评论 -
LC295.数据流的中位数(双堆)
问题题解将窗口的元素分成两堆,使得一堆所有元素都>=中位数,另一堆所有元素都<=中位数。用两个优先队列维护这两个堆,maxHeap和minHeap规定maxHeap.size()-minHeap.size()==1或0,这样当两堆元素总个数为奇数时,maxHeap.peek()就是所需要的中位数,若为偶数,则中位数=maxHeap.peek()/2.0+minHeap.peek()/2.0;关键在于维持maxHeap.size()-minHeap.size()==1或0这个关系,每原创 2020-07-01 20:32:18 · 141 阅读 · 0 评论 -
LC18.四数之和(双指针)
问题解题题目解法同三数之和,双指针,枚举前面两个数,确定前两个数的和sum之后,在后面使用双指针找 -sum即可。步骤:先从小到大排序再使用指针a确定第一个数,注意要跳过后面出现的重复的数再枚举a后面的第二个数b,注意也要跳过后面出现的重复的数双指针枚举c和d,两边向中间枚举,如果大于target则d–,否则c++,注意也要跳过重复的数。需要注意的是a和b在跳过重复数的时候,不能采用nums[i + 1] == nums[i]的判断方式,因为这样会跳过第一个出现的值,而我们应该跳过原创 2020-06-29 19:15:34 · 137 阅读 · 0 评论 -
LC5450.满足条件的子序列数目(双指针)
问题解题看清题干,是最小值和最大值的和小于等于target,因此组合中的最大值和最小值之间的数应该在最大值和最小值之间,因此先对数组排序。排序之后对每一个最小值i,找到最大的且满足条件的值j。那么这个最小值和最大值之间的数的个数(j - i - 1)可以贡献2^(j - i)个组合。预处理2的幂次数组,防止溢出。class Solution { public int numSubseq(int[] nums, int target) { int mod = 10000原创 2020-06-28 21:07:02 · 122 阅读 · 0 评论 -
LC5449.检查数组对是否可以被k整除(map)
问题题解先对arr中的每个元素求余,余数相加为k即可配对被k整除需要特判的是余数为0的情况,余数为0的元素个数必须为偶数。(e % k + k) % k,取余公式class Solution { public boolean canArrange(int[] arr, int k) { int[] cnt = new int[k]; Arrays.fill(cnt, 0);//初始化 for(int e : arr){原创 2020-06-28 20:59:31 · 152 阅读 · 0 评论 -
LC1049.最后一块石头的重量II
问题题解考虑到最后合并的时候两堆越接近石头重量总和的一半,则差值最小由于是随机拿石头,因此转换为用一个背包重量为sum/2的背包去石头堆里找石头,尽量让背包装满以上分析后题目变成0-1背包问题class Solution { public int lastStoneWeightII(int[] stones) { int n = stones.length; int sum = 0; for(int stone : stones){原创 2020-06-28 20:45:52 · 523 阅读 · 0 评论 -
LC448/41.找到所有数组中消失的数字/缺失的第一个正数(替换/哈希)
问题以41为例题解题目的关键在于时间复杂度以及空间复杂度,可以借鉴448题,利用下标对下标对应元素的交换原地降低时间复杂度。整体思路:交换的目的为了让下标上的元素和下标一样,第一个不相等的下标即为第一个缺失的正数示例2来说,为了方便比较,先对每个元素做-1操作:2 3 -2 00 1 2 3第一次交换,由于0上方的元素不是0,因此,让2交换到下标为2的地方-2 3 2 0 0 1 2 3第二次交换,由于0上方的数字不在0~n之间,因此移动枚举原创 2020-06-27 22:59:42 · 195 阅读 · 0 评论 -
LC1293.网格中的最短路径(BFS)
问题解题题干中的求最短距离,先想到BFS,然后用BFS+队列实现又由于题干中需要维护一个花费值K,如果假设K为每个格子还能移除K个障碍物,则每个格子都可能有K个状态,用visited[i][j][k]表示点i,j格子还能消除k个障碍物的状态是否出现过。用step维护最短路径,类似于树的层序遍历,每次扩展一层,该层的step比上一层+1.如果扩展到的点为0,则剩下的消除数rest不变,否则-1,如果rest<0则跳过这个状态注意:这里需要维护三个状态,横纵坐标以及该点的消除数K,因此需原创 2020-06-27 22:45:20 · 379 阅读 · 0 评论 -
LC609.在系统中查找重复文件(map)
问题解题暴力遍历每一个文件,然后先保存根目录,然后找到该文件的文件名,组合成绝对路径保存在以文件内容为key的map中。class Solution { public List<List<String>> findDuplicate(String[] paths) { Map<String, List<String>> map = new HashMap(); for(String path : paths)原创 2020-06-25 14:18:30 · 132 阅读 · 0 评论 -
LC593.有效的正方形(数学)
问题解题思路一:找到最长的两条就是对角线,对角线垂直且相等以及对角线中点重合,确定一条,另两个点确定另外一条对角线。class Solution { //四个点六条边,最长的两条就是对角线,对角线垂直且相等以及对角线中点重合,确定一条,另两个点确定另外一条对角线 public boolean isSame(int[] p1, int[] p2){ return p1[0] == p2[0] && p1[1] == p2[1]; }原创 2020-06-25 14:08:04 · 132 阅读 · 0 评论 -
LC150.逆波兰表达式求值(栈)
问题解题提示已经给的很明显了用栈。。。class Solution { public int evalRPN(String[] tokens) { int n = tokens.length; Stack<Integer> stack = new Stack(); for(int i = 0; i < n; i ++){ //判断是否是数字,即判断该String最后一位是不是数字即可原创 2020-06-25 00:37:50 · 93 阅读 · 0 评论 -
LC139.单词拆分(DP)
问题解题状态表示:dp[i],表示s的第0~i位能否成功地单词拆分状态转移,枚举0~j,如果dp[j]能成功单词拆分且第 j+1 ~ i 位也在字典中,那么dp[i]也可以成功地单词拆分,因此状态转移方程:dp[i] = dp[j](from 0 to i - 1) && set.contains(s.substring(j,i))class Solution { public boolean wordBreak(String s, List<String>原创 2020-06-25 00:11:04 · 139 阅读 · 0 评论 -
LC224.基本计算器(辅助栈)
题目解题为了省去符号的倒序麻烦,使用两个栈来倒腾数字,这样最后的顺序就是顺序的,再用一个栈存储符号。每次遇到右括号执行以上的操作,即完成该括号对内的操作。为了能够存储多位整数和符号,用String来存储栈内元素。class Solution { public int calculate(String s) { s = "("+s+")"; Stack<String> stack = new Stack(); for(int原创 2020-06-24 23:53:53 · 129 阅读 · 0 评论