
leetcode
花椒胡椒小辣椒
这个作者很懒,什么都没留下…
展开
-
剑指offer41.数据流中的中位数
思路因为堆只是保证了某一条路径的元素顺序是递减或递增的,而并没有保证按照数组索引的顺序是有序的,这也是堆和二叉搜索树的区别所在。所以本题:用一个小顶堆A保存最大的m个数,用一个大顶堆B保存最小的n个数;当m==n时,向B中插入一个数,并将B的堆顶元素插入到A中;当m≠\neq=n时,向A中插入一个数,并将A的堆顶元素插入到B中;这样保证了A.size()>=B.size()。当相等时,中位数就是A、B的栈顶元素相加除以2,不等时中位数就是A的栈顶元素。class MedianFin原创 2020-10-25 17:30:46 · 185 阅读 · 0 评论 -
offer42.连续子数组的最大和
题目描述输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)解析思路:我的第一思路是滑动窗口,遍历每个子数组并计算子数组的和,但是n个数字有n(n+1)/2个子数组,时间复杂度是O(n*n),显然有更好的解决办法。这道题最简单的做法是利用动态规划,后一个状态是与前一个状态有关的,根据题意得到状态转移方程是max(f(i)) = max(f(i-1),0)+nums[i],所以这里将数组的nums[i]值直接替换成计算得到的max(f(i-1原创 2020-09-08 22:12:53 · 242 阅读 · 0 评论 -
offer21.调整数组顺序使奇数位于偶数前面
题目描述输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。解析思路此题其实本质是排序,让奇数位于偶数前面,可以想到快速排序的思想,利用首尾指针同时遍历数组,左指针遇到偶数则停下,右指针遇到奇数则停下,交换这两个数字,直到左指针大于等于右指针则停下。时间复杂度:O(n)public int[] exchange(int[] nums) { int left=0, right=nums.length-1; if原创 2020-08-28 16:57:16 · 178 阅读 · 0 评论 -
剑指offer57-II.和为s的连续正数序列
题目描述输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。(1 <= target <= 10^5)例如:输入:target = 9输出:[[2,3,4],[4,5]]解析解法一思路:...原创 2020-08-13 16:23:56 · 129 阅读 · 0 评论 -
剑指offer57.和为s的两个数字
题目描述输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。解析解法一思路:递增排序的数组一般会想到二分查找,和为数字s,可遍历数组元素,查找s-nums[i],一旦找到就退出循环。二分查找的复杂度为O(logN),遍历N个节点,所以总的时间复杂度是O(NlogN),空间复杂度是O(1)。public int[] twoSum(int[] nums, int target) { for(int i=0;i<num原创 2020-08-10 09:57:54 · 138 阅读 · 0 评论 -
offer58-I.翻转单词顺序
题目描述输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. “,则输出"student. a am I”。注:输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。解析思路:我的第一思路是利用栈先入后出的特点,进行单词的翻转;第二个想法是直接利用string.spilt(" ")切分字符串,但一直没想到合适的数据结构原创 2020-08-08 12:08:50 · 195 阅读 · 0 评论 -
剑指offer58-II.左旋转字符串
题目描述字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。解析法一利用String的substring方法,对字符串以n为界线分割,再翻转顺序连接字符串public String reverseLeftWords(String s, int n) { if(s.length()==0 || n==0) return s; String原创 2020-08-08 11:32:24 · 181 阅读 · 0 评论 -
offer11.旋转数组的最小数字
题目描述把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。解析解法一思路:递增排序的数组的旋转会破坏其递增性,所以遍历数组元素找到变小的那个数便是最小元素,若没找到变小的那个数,则第一个元素为最小元素时间复杂度O(N)public int minArray(int[] numbers) { for(int i=原创 2020-08-06 19:38:52 · 122 阅读 · 0 评论 -
剑指offer52.两个链表的第一个公共节点
题目描述输入两个链表,找出它们的第一个公共节点。(链表非循环结构)按照题目示例,公共节点指的是该节点内存地址相同,而非仅val值相同。链表节点结构如下:public class ListNode { int val; ListNode next; ListNode(int x) { val = x; next = null; }}解析解法一:双重循环思路:第一思路当然是双重循环遍历链表,但时间复杂度是O(MN)。public ListNode getIntersection原创 2020-08-06 10:59:18 · 148 阅读 · 0 评论 -
剑指offer35.复杂链表的复制
题目描述请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。解析思路原创 2020-08-06 17:04:03 · 120 阅读 · 0 评论 -
剑指offer24.反转链表
题目描述解析思路原创 2020-08-05 11:33:38 · 234 阅读 · 0 评论 -
剑指offer22.链表中倒数第k个节点
题目描述输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点。解析思路倒数第k个节点即是正数第n-k+1个节点(n是链表长度)。首先想到的便是:第一次遍历链表,得到链表长度n,第二次遍历链表,直到第n-k+1个节点,返回即可。代码如下:public ListNode getKthFromEnd(ListNode he原创 2020-08-04 17:38:08 · 239 阅读 · 0 评论 -
剑指offer18.删除链表的节点
题目描述解析思路删除链表节点只需将该节点的前驱节点的后继节点修改为该节点的后继节点即可,题目要求返回删除节点后的头节点,所以开辟两个链表节点的空间:iterNode用来遍历链表找到所要删除的节点,preNode用来表示所要删除节点的前驱节点。需要考虑的额外情况是:链表为空;val值不存在于链表中;所要删除的节点是头节点三种情况。代码如下:public ListNode deleteNode(ListNode head, int val) { if(head==null) ret原创 2020-08-04 16:25:00 · 132 阅读 · 0 评论 -
剑指offer06.从尾到头打印链表
题目描述输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。链表结构:public class ListNode { int val; ListNode next; ListNode(int x) { val = x; } }解析解法一思路:首先遍历链表,将节点值按照从头到尾的顺序存入ArrayList中,再从后往前遍历ArrayList,将值输入到数组中。(这里的ArrayList解决了不知链表长度无法动态分配数组的问题)。pub原创 2020-08-03 16:55:53 · 113 阅读 · 0 评论 -
剑指offer50.第一个只出现一次的字符
题目描述在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。解析解法一遍历字符串,用HashMap<k,v>存储<字符,字符出现的次数对>,再遍历哈希表,当当前键的值为1时,返回当前键。(第一次用的是HahsMap,提交代码后执行错误,本地debug才发现put到哈希表时,顺序发生了变化,因此用LinkedHashMap代替HahsMap)代码public char firstUniqChar(String s) {原创 2020-08-03 10:36:45 · 120 阅读 · 0 评论 -
剑指offer59_I.滑动窗口的最大值
题目描述给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。解析解法一:没有任何优化,直接截取数组,依次遍历求各数组最大值public int[] maxSlidingWindow(int[] nums, int k) { if(nums.length==0) return new int[0]; int n=nums.length-k+1; int[] maxNums = new int[n]; for(int i=0;i<=nums.lengt原创 2020-08-02 17:00:34 · 139 阅读 · 0 评论 -
剑指offer10.斐波那契数列及青蛙跳台阶问题
斐波那契数列题目描述写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项。斐波那契数列的定义:F(0) = 0, F(1) = 1;F(N) = F(N - 1) + F(N - 2), 其中 N > 1解析解法一:递归第一想法必是递归求解,代码如下,然而由代码可以看出该方法存在着大量的重复计算。当计算fib(n-1)时,会需要计算fib(n-2)和fib(n-3),而在递归完fib(n-1)后,又需要递归计算fib(n-2),而无法利用前者已计算过的值(因为并不会在内存原创 2020-08-01 11:47:15 · 279 阅读 · 0 评论 -
剑指offer68_II.二叉树的最近公共祖先
题目: 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。这道题与68_I题不同的是,此树并不是BST,没有顺序关系,也可自行拓展,若连二叉树树都不是呢?若有指向父节点的指针呢?思路若树为空,或树根的值等于p、q中任何一个节点的值,则返回root为其最近公共祖先;否则:在树的左子树中搜索p、q中的任何一个,找到则返回该节点node1,否则返回null; 在树的右子树中搜索p、q中的任何一个,找到则返回该节点node2,否则返回null;若在树的左右两原创 2020-07-25 15:54:19 · 113 阅读 · 0 评论 -
剑指offer68-I.二叉搜索树的最近公共祖先
纪念自己做出来的第n道题(1<=n<10)题目描述: 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。最近公共祖先 :“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”思路因为二叉搜索树(BST)按照先序遍历排序后是升序排序的,其左子树节点均比根小,右子树节点均比根大,所以利用这一性质:若p、q的值一个大于根,一个小于根,或者其中一个等于根,则其最近公共祖先均为根节原创 2020-07-25 12:06:56 · 131 阅读 · 0 评论 -
剑指offer55-II.平衡二叉树
题目: 输入一棵二叉树的根节点,判断该树是不是平衡二叉树。分析: 平衡二叉树(Balance Tree)的定义是:二叉树中任意节点的左右子树的深度相差不超过1。注意是任意节点,并不只是根节点的|左深度-右深度|,还有其子树也必须是平衡二叉树。从该定义也可知是利用递归来解决这个问题。代码:class Solution { public boolean isBalanced(TreeNode root) { if(root==null) return true; return Math.原创 2020-07-25 11:19:38 · 131 阅读 · 0 评论 -
剑指offer54.二叉搜索树的第k大节点
题目: 一棵二叉搜索树,请找出其中第k大的节点思路自己的思路是层序遍历,再排序,找到第k大的节点,然而却忽略了最重要的一个线索二叉搜索树!二叉搜索树: 即二叉排序树,若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值(左<根<右)。所以本题中,找第k大的数即按照降序排序后,第k个数即为所求。而根据BST的性质,降序排序就是“右根左”的中序遍历得到的顺序。代码public int kthLargest(TreeN原创 2020-07-21 17:36:19 · 140 阅读 · 0 评论 -
剑指offer32-III.从上到下打印二叉树(蛇形打印)
又是被自己傻到的一天…题目 按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。思维断点 这道题和32-II类似,思路也大致相同,然而我却过度关注入队列和出队列的方式,忽略了树节点的val值入列表的方式。"若为奇数层,将 node.val 添加至 tmp 尾部;否则,添加至 tmp 头部"贴上原错代码警示自己public List<List<Integer>> levelOrder原创 2020-07-20 18:09:51 · 233 阅读 · 0 评论 -
剑指offer32-II.从上到下打印二叉树
题目: 从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。题目分析题目的本质是层序遍历,这里依旧可以用递归和迭代的思想解决。递归迭代思路: 初始化一个队列,按照层数将节点依次入队列,随着该层节点依次出队列并将val值存入List中,将这些节点的左右子节点分别入队列,重复此过程,直到队列为空。与此同时,需要考虑两个问题:若是满二叉树的情况下,二叉树的每层的树节点为 2n−12^{n-1}2n−1 (n为层数),因此可用此数作为循环控制的条件,但是这里的二叉树并不一定是满原创 2020-07-20 12:00:12 · 94 阅读 · 0 评论 -
剑指offer32-I.从上到下打印二叉树
题目: 从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。函数定义为public int[] levelOrder(TreeNode root),分析 由题意可知需要层序遍历二叉树,将树节点的val值存入int[]数组内。此时即使二叉树不是满二叉树,为空的树节点也不会影响结果的输出,同时根据28题的思路,初始化一个队列,将根节点入队列,当队列不为空时,依次出队列,同时保存val值,同时将出队列的节点的非空子节点入队列。 在写代码的过程中才发现由于树节点个数不知,数组初始化时未知原创 2020-07-19 17:59:32 · 115 阅读 · 0 评论 -
剑指offer.28对称的二叉树
题目: 判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。思路分析 刚解答过27题,容易受上题影响,但大致思路是一致的:递归和迭代。举一个对称的二叉树例子可知,若二叉树是对称的,则其左子树的左节点和其右子树的右节点相等,左子树的右节点和其右子树的左节点相等。递归代码public boolean isSymmetric(TreeNode root) { if(root==null) return true; return recheck(root.left,r原创 2020-07-18 16:11:41 · 102 阅读 · 0 评论 -
剑指offer27.二叉树的镜像(递归&辅助队列)
看题第一思路原创 2020-07-18 10:24:20 · 172 阅读 · 0 评论 -
剑指offer55-1.二叉树的深度
IPO原创 2020-06-30 18:34:18 · 101 阅读 · 0 评论 -
剑指offer39.数组中出现次数超过一半的数字
看题第一思路IO(input、output)分别为:I:数组(1=<长度<=1000;O:出现次数超过一半的数字思路1:排序。即对数组进行排序,数组中位数则为所求。思路2:map(key-value)。以数组元素为key,遍历计算key出现的次数,存入value,当value>n/2时即为所求。思路1:排序时间复杂度是:O(NlogN)public int majorityElement(int[] nums) { Arrays.sort(nums);原创 2020-06-25 18:27:22 · 96 阅读 · 0 评论 -
剑指offer15.二进制中1的个数
public class Solution { // you need to treat n as an unsigned value public int hammingWeight(int n) { String str = Integer.toBinaryString(n); int count=0; char[] res = str.toCharArray(); for(int i=0;i<str.length();i++) { if(res[i]=='原创 2020-06-23 18:57:54 · 129 阅读 · 0 评论 -
leetcode-面试题45.把数组排成最小的数
看题第一感觉:IPO(input、process、output)分别为:I:非负 整数的数组; P:拼接数组元素; O:拼接成的最小的数。分析一些例子感觉应该是按照数的最高位排序,再按次高位排序,但对于没有次高位的数来说,那又如何比较呢。例如3和30比较次高位时,3并没有次高位,如果用补0操作的话就无法判断是个位数3补的0,还是原本30就存在的0。所以这个方法弃用。那是不是和整除有关,或者对数进行归一化?——想不通了,看评论吧。题解思路: 对于两个数x和y,如果x+y<y+x,那么可以原创 2020-06-16 22:56:00 · 283 阅读 · 0 评论 -
leetcode-面试题64.求1+2+...+n
思路求1+2+…+n,首先想到的便是:for循环至n,逐项求和(需要用for循环)用等差数列求和公式(需要用乘除法、条件判断语句)题目中要求“不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)”,以往的学习积累中想到:for循环可以用递归实现(着重练习递归)位运算符的左右移可以实现加减乘除:用位运算实现四则运算之加减乘除逻辑运算符&&、||具有短路的性质:一分钟搞懂逻辑运算符&(并且) , |(或者) ,原创 2020-06-02 20:01:26 · 222 阅读 · 0 评论 -
leetcode1431.拥有最多糖果的孩子
思路 其实题目的示例解释已经很明确了,只要遍历数组每个元素:{candies[i]+extraCandies>=max(candies[])返回truecandies[i]+extraCandies<max(candies[])返回false\begin{cases}candies[i]+extraCandies>=max(candies[]) &\text{返回true}\\candies[i]+extraCandies<max(candies[]) &\原创 2020-06-01 11:21:42 · 221 阅读 · 0 评论 -
leetcode-面试题40.最小的k个数
1. 快速排序对数组元素进行快速排序,再顺序遍历前k个数即为所求class Solution { public int[] getLastNumbers(int[] arr,int k) { if(arr.length==0 || k==0) { return new int[0]; } int[] nums = new int[k]; Arrays.sort(arr); for(int i=0;i<k;i++) nums[i]=arr[i]; re原创 2020-06-03 20:01:04 · 194 阅读 · 0 评论 -
leetcode-面试题53.0~n-1中缺失的数字
题中信息:递增排序n-1长度的数组内有n-1个数字,范围是0~n-1,即只缺失一个数字。1. 遍历 最简单的方法就是从前到后遍历数组,直到找到第一个数组下标和当前元素不等的数据,此时的下标值即为缺失的数字。有对应关系:{在缺失的数字前:数组下标==当前元素在缺失的数字后:数组下标+1==当前元素\begin{cases}在缺失的数字前:数组下标==当前元素& \\在缺失的数字后:数组下标+1==当前元素&\\\end{cases}{在缺失的数字前:数组下标==当前原创 2020-05-29 11:59:25 · 235 阅读 · 0 评论 -
leetcode-面试题53.在排序数组中查找数字
题目中的信息有:排序数组数组长度0<=n<=500001. 从前往后顺序遍历 从前往后顺序遍历,当target==nums[i]时,次数+1,直到碰到第一个比target大的数为止,返回次数。时间复杂度O(n);空间复杂度O(1)class Solution { public int search(int[] nums,int target) { int length = nums.length; int n=0,i=0; while(i<len原创 2020-05-28 22:57:32 · 158 阅读 · 0 评论 -
leetcode-面试题29.顺时针打印矩阵-矩阵消除法
思路 延续上题的矩阵消除法的思路,从外向里访问矩阵元素时,始终是在当前矩阵的最上方从左到右——>最右列从上到下——>最下方从右到左——>最左列从下到上访问。遍历结束的条件是每个元素均被访问到,即返回的含有m*n个元素的一维数组被填满。时间复杂度O(mn)代码public int[] spiralOrder(int[][] matrix) { if(matrix==null || matrix.length==0 || matrix[0].length==0) {原创 2020-05-26 18:32:32 · 220 阅读 · 0 评论 -
leetcode-面试题04.二维数组中的查找
1. 暴力法遍历 双重循环遍历二维数组,直到matrix[i][j]==target,返回true。未利用到题目中所说的行递增、列递增的特点。二维数组的行列长度判断:行长度matrix.length;列长度matrix[0].length二维数组为空的判断matrix[0].length=0和matrix.length=0都代表矩阵为空,只有一行或一列的情况必有一length=1,而非0 .false={matrix.null首地址为空matrix.length==0二维数组是否为{ 原创 2020-05-25 16:26:42 · 284 阅读 · 0 评论 -
leetcode-面试题03.数组中重复的数字
1. 暴力枚举 简单的方法便是双层循环嵌套遍历数组,直到找到第一个出现重复的数字则输出,时间复杂度是O(n2),空间复杂度是O(1)。代码略。2. 排序 遍历数组前完全可以先对数组进行排序,从而可降低时间复杂度,然后遍历数组,相邻项存在相等的情况则输出。java.util.Arrays提供了Arrays.sort()方法可以对数组进行升序排序,源码中该方法提供的是快速排序算法./* * 时间复杂度O(nlogn),空间复杂度O(1) */public int findRepeatNumbe原创 2020-05-22 17:41:02 · 142 阅读 · 0 评论 -
leetcode-队列的最大值
主要思想 在剑指offer面试题30:“包含min函数的栈”的解题思路中,可以想到这道题同样需要一个辅助队列,将当前队列的最大值存入辅助队列,但和栈又有所不同。 本题中:当一个元素value入队的时候,它前面所有比它小的元素的出队不会对求最大值的结果产生影响,而它前面比它大的元素出队时,使得value成为当前队列的最大值,直到有更大的数入队。 因此:设计辅助队列的入队、出队规则为:value入队时,将辅助队列中比value小的数依次出队。即“维持队列单调递减,保证每个元素的前面都没有比它小的元素原创 2020-05-21 18:11:07 · 183 阅读 · 0 评论 -
leetcode-最小栈
1. 思路题目要求push、pop、top、getMin的时间负责度是O(1),那么:每push一个新数据都要比较当前数据与min,更新——>item存比较后的min;接着考虑发现:如果pop的是min值,则再getMin时,就需要知道第二最小值…这样的结果是需要将数据排序,那么时间复杂度肯定不会是常数级。陷入困境,翻看评论,看到一句话:“每个节点加一个额外属性:当前最小值”。…(省略内心戏),需要用一个辅助栈存对应位置的当前的最小值。(用一个链栈实现也可以)2.代码class Min原创 2020-05-18 16:52:54 · 124 阅读 · 0 评论