leetcode刷题记录
文章平均质量分 77
zcc今天好好学习了吗
研究生在读
展开
-
剑指 Offer 41. 数据流中的中位数(优先队列)【H】
剑指 Offer 41. 数据流中的中位数在看优先队列源码的时候,看到了PriorityQueue的常用地方,其中讲到了topK问题,和求中值问题。之前topK已经整理过了,而求中值也是考点。题目要求:在数据流中(就是数据长度不确定,随时都可能要在此长度上求其中值),由于数据长度未定,所以不能用数组,然后排序求中值;也不能维护一个有序的集合,然后每次插入都是查找合适的位置——时间复杂度O(logN)的时间查找,O(N)的时间插入。我们需要随时维护中值,即随时能够求出中值。利用两个堆,一个最大堆、一个原创 2021-03-20 16:34:26 · 224 阅读 · 0 评论 -
1160. 拼写单词(哈希)【S】
1160. 拼写单词本题不难,只是通过该题,可以知道,有时候不一定要去调用哈希表,当输入限定在一个确定的范围内时,可以用数组自行实现一个哈希表。题目的要求:根据后面给的字符串,来看前面的字符串数组中的哪些单词已经掌握了。可以统计字符串每个字母的出现次数,然后对前面每个字符串的每个字母进行统计,然后将他们做对比即可。由于限定了所有字符串仅包含26个小写字母,所以可以构建出一个长度为26的数组,然后记录每个字母出现的次数;然后对前面的每个字符串也构建出一个26长度的数组,对这两个数组进行比较即可:c原创 2021-03-17 20:36:28 · 199 阅读 · 0 评论 -
15. 三数之和 & 18. 四数之和 & 16. 最接近的三数之和(双指针)& 454. 四数相加 II(哈希表)【M】
15. 三数之和经典的多数之和题这个题之前做过一遍,花了挺久的时间才搞懂,这次重新做能够快速想到思路,但是还是存在细节问题。这题的主要难点是如何去重基本思路:首先,想暴力解,暴力解就是将所有可能的组合均遍历一遍,那么时间复杂度为:O(n∗(n−1)∗(n−2))=O(N3)O(n *(n - 1)*(n-2))=O(N^3)O(n∗(n−1)∗(n−2))=O(N3)这样解,肯定不行,所以需要转变思路,将暴力解优化一下,由于最大的复杂度是O(N3)O(N^3)O(N3),那么排序一下也不会影响,所原创 2021-03-17 11:01:37 · 188 阅读 · 0 评论 -
剑指 Offer 21. 调整数组顺序使奇数位于偶数前面(快排partition)【S】
剑指 Offer 21. 调整数组顺序使奇数位于偶数前面做到这个题的时候,觉得很像是快排的partition的解法:其实本质上也是,就是通过一次遍历,将奇偶数组做一个划分。class Solution { public int[] exchange(int[] nums) { int left = 0, right = nums.length - 1; while(left <= right){ while(left <=原创 2021-03-16 23:44:56 · 96 阅读 · 0 评论 -
151. 翻转字符串里的单词(字符串)【M】
151. 翻转字符串里的单词这题主要就是考查字符串的解法,总体来说比较简单。它规定了是不能利用额外空间,返回的字符串不算是额外空间,主要就是来限制使用库函数。1. 双指针由于不能用额外空间,所以我们需要在字符串上直接进行遍历,且是翻转字符串,所以显然我们需要从后向前遍历。核心是:我们需要能够取出一个完整的单词,那么我们需要标记字母的起始和字母的结束——因此,自然的想到双指针,i来指示单词的开头,j来指示单词的结尾。而本题麻烦的点在于可能两个单词之间可能存在多个空格,那么我们需要找到第一个非空原创 2021-03-16 20:04:16 · 91 阅读 · 0 评论 -
215. 数组中的第K个最大元素 & 剑指 Offer 40. 最小的k个数 & 347. 前 K 个高频元素(快排、优先队列)【M】
215. 数组中的第K个最大元素 & 剑指 Offer 40. 最小的k个数这两个题本质上是一个题,典型的topK问题,一定要掌握这个题的考点:多种解法(快排、优先队列),快排的实现可以想到:暴力解,即将数组sort一下,然后获取index=k-1的数字,就是topk——时间复杂度为O(NlogN)1. 快排首先,我们知道Java内部的sort就是用了改进版的快排。那么快排的主要思想就是:分而治之,核心方法,就是partition,每一次调用partition之后,都能确定一个结点的位置原创 2021-03-16 09:36:36 · 175 阅读 · 0 评论 -
二叉树遍历总结 & 剑指 Offer 07. 重建二叉树【M】
二叉树的遍历整理契机:145. 二叉树的后序遍历题,用递归解决很简单,并且有统一的模板,但是用迭代方法就没有统一的模板,因此想总结一下4类遍历的解法。方便复习前序遍历:1-2-4-5-8-3-6-9-7-10中序遍历:4-2-8-5-1-6-9-3-10-7后序遍历:4-8-5-2-9-6-10-7-3-11. 前序遍历前序遍历:根 – 左 – 右递归解法:/** * Definition for a binary tree node. * public class TreeNode原创 2021-03-15 21:11:34 · 270 阅读 · 0 评论 -
54. 螺旋矩阵(同剑指 Offer 29. 顺时针打印矩阵)(矩阵)【S】
54. 螺旋矩阵同剑指 Offer 29. 顺时针打印矩阵这题是模拟题,就是模拟整个遍历过程。(这两个题间隔一段时间做,做出了两个版本,估计下一次做,又能再给一个版本)这个题没有什么技巧,只需要耐心的分析整个过程就能写出来,只是时间问题。分析:可以发现一次顺时针,需要从左向右走 --> 从上向下走 --> 从右向左走 --> 从下向上走,并且:从左向右走完,该行已经全部遍历完了,之后不用再遍历,需要top++;同理从右向左也一样,需要bottom–从上向下走完,该列已经原创 2021-03-14 20:13:23 · 93 阅读 · 0 评论 -
199. 二叉树的右视图(二叉树)【M】
199. 二叉树的右视图这个题目还是比较简单的。二叉树一般有2种解法:DFS、BFS,分别对应着递归求解、迭代求解这题的迭代解法很简单:对于每层结点进行遍历的时候,记录最右边(即列表的最后的值)——本质上还是二叉树的层序遍历:/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; *原创 2021-03-14 13:00:50 · 296 阅读 · 0 评论 -
146. LRU 缓存机制(设计)【M】
146. LRU 缓存机制这个是面试高频题LRU。题目本身并不难,是一个设计题,如果第一次遇到,且在限定时间内确定数据结构并且完全编写出来,还是有一定难度的;而如果已经写过一次,那么再次写难度会降低很多。我觉得最关键是:明确数据结构LRU:最近最少使用,即当内存容量不够时,我们需要将部分页面置换出去,那么如何选择呢——选择最近最少被用到的页面,将它踢出去。所以有如下规则:如果使用了某个页面,在表中存在,那么可以直接获得该页面,并且由于最近使用过,所以需要将其放在头部如果使用某个页面,表原创 2021-03-08 13:01:35 · 137 阅读 · 0 评论 -
349. 两个数组的交集 & 350. 两个数组的交集 II(数组)【S】
349. 两个数组的交集本文主要是进行刷题记录,方便日后查看,参考的文章都在最后的参考链接中。题目本身并不难,但是可能会考察多种解法。每一种解法的原理都不大相似1. 辅助空间根据题目可以发现,我们需要找到所有在两个数组中都出现的数字,且需要将结果去重。去重,最先想到的就是hashset,能够保证结果的唯一性——所以hashset就是用来去重的。所以,我们将两个数组都存放到hashset中,第一个hashset是无脑将nums1数组全部丢进去;第二个hashset是先判断该数字在第一个哈希集合中原创 2021-03-07 23:43:42 · 172 阅读 · 0 评论 -
338. 比特位计数 & 191. 位1的个数(二进制的特点)【M S】
338. 比特位计数1. 暴力解写一个方法,用来计算某个数的二进制中1的个数然后循环0~num,每次循环都调用该方法。时间复杂度为O(n*sizeof(integer))——很显然,存在重复计数,我们需要发现数字时间的规律2. 基于数学的动态规划更确切说,这个是一个数学题,当你发现规律时,你会利用朴素的动态规划思想首先,我们知道*2,就是一个左移1位操作<<1,那么左移1位,是不会改变二进制表示中1的个数的所以当我们知道2,就能推出4那6如何推出呢,需要知道3,那么3如何原创 2021-03-07 22:12:05 · 280 阅读 · 0 评论 -
448. 找到所有数组中消失的数字 & 442. 数组中重复的数据(数组)&剑指 Offer 03. 数组中重复的数字【S】& 41. 缺失的第一个正数【H】
448. 找到所有数组中消失的数字1. 使用额外空间可以想到用HashSet,遍历数组将所有的内容,放在set中,最后遍历[1,n],看哪些数字没有出现2. 原地修改题目要求:不使用额外空间——不能用哈希表等存储;复杂度为O(N),那么就是常量次遍历。我的方法:一个萝卜一个坑(初始思路来自哪里找不到了)想反例:如果正好是1~n个数字,有且仅出现一次,那么经过遍历之后一定能顺序排列,即1-1,2-2,…n-n(注意这边的index是从1开始的)如果存在数字重复,那么一定有数组不存在的,数字重复原创 2021-03-07 12:42:08 · 157 阅读 · 0 评论 -
剑指 Offer 17. 打印从1到最大的n位数(扩展:大数)【M】
剑指 Offer 17. 打印从1到最大的n位数本文只是用来记录本人做题思路和过程,加深记忆。如果需要参考,建议参考下面的参考文章,图文并茂食用更佳。本题求解很简单,不是关键,关键在于对大数的求解1. 本题解法由于限定死了输出的数组是int[],所以结果一定是int范围内的,而int的最大值是21亿多一点,所以最多是9位。直接设置一个辅助数组,该数组内存放1~9位数的十进制最大值。然后这个就是遍历上限:class Solution { public int[] printNumbers(原创 2021-03-07 11:15:12 · 181 阅读 · 1 评论 -
84. 柱状图中最大的矩形 & 496 & 503 & 739(单调栈)【H, M】
84. 柱状图中最大的矩形本文只用来刷题时进行分析和记录,方便日后查看,所有思路参考自题解,题解图文并茂食用效果更好,链接见最后本题难度比较大,看到这种我能够想到是需要用到单调栈。但是,由于之前没有实际使用过单调栈,所以不知道如何上手。于是看了这篇题解。ps:写的超级好,就是有点长,于是,我看明白之后自己实现了一遍,并且将整体思路讲明白,就表明我真的吃透了这个题目这个题首先要从暴力解开始考虑,然后再想着优化。1. 暴力解思路这个矩形存在两个变量:宽和高。所以我们需要考虑这两方面的因素。同时改变这原创 2021-03-06 15:42:18 · 173 阅读 · 0 评论 -
面试题 01.07. 旋转矩阵 & 48(数学)【M】
面试题 01.07. 旋转矩阵 & 48可以发现旋转之后,竖着的147变成横着的了;258、369也横着了,即列变成了行,行变成了列那么如何实现行列转换呢,矩阵的转置RTR^TRT转置之后:[ [ [ [1, 2, 3] [1, 4, 7] [7, 4, 1] [4, 5, 6] --> [2, 5, 8] --> [8, 5, 2] --每行按照中间对称交换一下,对称翻转 [7, 8, 9] [3, 6, 9]原创 2021-03-05 20:23:35 · 450 阅读 · 0 评论 -
232. 用栈实现队列 & 225. 用队列实现栈(设计)【M】
232. 用栈实现队列《栈实现队列》也是剑指的题:想要实现该题目并不难,但是要简要且高效的实现比较难。我们可以发现:栈是FILO,后进先出,那么我们只需要把栈中的元素全部pop,放到另一个栈中,那么该栈就是按照队列顺序排列的了所以我们设置两个栈:一个栈为主栈:专门用来加入数据;一个栈为副栈:专门用来取出数据的。并且我们发现,主栈将n个数据弹出放到副栈,那么在副栈全部弹出之前,我们都可以直接通过该副栈pop数据和查询数据所以,对于一个数据,从进到出整个过程,只会出现2次入栈、2次出栈。所以,总原创 2021-03-05 19:35:23 · 356 阅读 · 0 评论 -
303. 区域和检索 - 数组不可变 & 304. 二维区域和检索 - 矩阵不可变
303. 区域和检索 - 数组不可变本文主要是记录,方便日后遇到相同题的归纳。(主要思路均来自下面两篇参考文章的提示)这两题,主要考察的是前缀和,也是包含了动态规划思想。题目要求的是:求数组[i, j]范围内的值,且会不断的调用求区域和方法,所以每次调用就计算[i, j]的和,时间复杂度太大所以,能想到的是,提前维护一个数组,该数组能够计算出[i,j]的区域和,但是由于给出的i、j范围不定,所以不可能提前想好所有可能所以,有没有间接的计算区域和的方法,使之满足O(1)的时间复杂度观察发现**[原创 2021-03-03 13:06:01 · 131 阅读 · 1 评论 -
12. 整数转罗马数字(数学)【S】
12. 整数转罗马数字本题并不难,重点就是看懂题目,分清楚有多少种情况。并且用到的是朴素的贪心思想(朴素,并不意识到用了贪心,是一种直观的贪心选择)首先读题,了解公有13种情况:肯定不能用if…else来划分,那么用双数组来移动即可,{1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}根据数字,优先选择不超过自己的表示方式,eg:7:肯定选择5 + 1 + 1,而不会选择4+1+1+1,或者是7个12999:肯定选择 1000 + 100原创 2021-03-03 11:09:39 · 181 阅读 · 1 评论 -
1103. 分糖果 II(数学、模拟)【M,S】
1103. 分糖果 II我的解法:模拟整个分配糖果的过程:时间复杂度为O(max(candies,N))O(max(\sqrt{candies}, N))O(max(candies,N)),N是人数。class Solution { public int[] distributeCandies(int candies, int num_people) { int[] getCandy = new int[num_people]; int times = 0;原创 2021-03-03 10:56:29 · 287 阅读 · 0 评论 -
反转链表 & 反转链表II【M】
92. 反转链表 II很显然,对于反转链表的题来说,会有递归和迭代两种解法。如果用递归,建议先熟悉下面的普通反转链表问题,一步步推导到指定范围内的链表反转问题:迭代法:这题,我的做法可行,但是很绕,很容易出现紧张就理不清楚思路的问题:实现了:一次遍历,完成翻转部分链表的结果。整体思路就是:从头开始找到要反转的起始结点,并保存交界处的两个结点;不断反转到需要反转的终点,保存好交界处的两个结点,最后交叉相连即可——注意:一定要在纸上画出流程,不然肯定做不出来的链表: 前头 – 前尾 -->原创 2021-03-02 14:36:35 · 182 阅读 · 0 评论 -
83. 删除排序链表中的重复元素 & 26. 删除排序数组中的重复项(双指针)【S】
83. 删除排序链表中的重复元素本文,仅用作自我记录,方便查看本题有多种解法。我的解法是最容易想到的,也是最简单的——单指针法(和后面的做区分)1. 单指针法由于该链表已经是有序的(按照val排序的),那么值一样的结点都是放在一起的我们只需要有两个指针,一个指向cur、一个指向next:cur != next(是指值),cur = cur.nextcur == next(是指值),cur = cur.next.next注意❗️删除之后,cur不能指向next,因为cur和最新的n原创 2021-03-01 21:44:37 · 156 阅读 · 0 评论 -
leetcode61. 旋转链表(链表)【S】
61. 旋转链表主要是用来自我记录的,方便归类和查看。典型链表题思路:旋转链表,其实就是将后面的结点移动到前面来,所以需要有一点点的数学技巧思考过程:先根据示例,模拟了旋转的过程,发现是将后面链表移动到前面来,即 前头 — 前尾 -> 后头 — 后尾 => 后头 — 后尾 -> 前头 -> 前尾又根据示例2,考虑到旋转次数 > 链表长度,想到了在该链表后面补上n个相同的链表,后面分析没有必要,直接做一个计算,将旋转次数控制在链表长度内所以想到:先原创 2021-03-01 20:20:15 · 126 阅读 · 0 评论