剑指Offer
MaRinli7
Coder
展开
-
卡特兰数-LeetCode96-不同的二叉搜索树
卡特兰数(英语:Catalan number),又称卡塔兰数、明安图数,是组合数学中一种常出现于各种计数问题中的数列。数列的前几项为:1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862,...递推公式:Cn = C0*Cn-1 + C1*Cn-2 + C2*Cn-3 + ...+ Cn-1*C0一、题目:给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的二叉搜索树有多少种?返回满足题意的二叉搜索树的种数。 题目分析:节点有...原创 2021-12-02 15:00:04 · 258 阅读 · 0 评论 -
约瑟夫环问题
一、原题目剑指Offer62:圆圈中最后剩下的数字0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。自己的做法:模拟为圆,删除元素之后计算下一个下标,直到删除至只剩一个元素class Solution { public int la原创 2021-11-05 15:47:16 · 130 阅读 · 0 评论 -
剑指Offer-58
二叉搜索树的最近公共祖先给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]做法:由于给的树是二叉搜索树,可以根据结点的值来判断结点p和q分别在哪一边;而且题目要求x的深度最大,则:...原创 2021-11-01 20:22:17 · 65 阅读 · 0 评论 -
剑指Offer-64
求1+2+..+n求 1+2+...+n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。做法:传统的使用递归是不行的,因为一般来说终止条件使用if(n ==1) return 1; 题目要求不能使用if,则采用短路 短路的本质在于:例如A && B,当判断A为false时,B判断就不会再执行;再如A || B,如果判断出A为true,B就不会再执行class Soluti...原创 2021-11-01 16:12:26 · 59 阅读 · 0 评论 -
常用排序算法(二)
六、快速排序通过一次排序将数组分为两部分,左边部分是比基准元素小的部分,右边部分是比基准元素大的部分,即准确找到了基准元素应该在的位置。与归并排序不同,归并排序用一个临时数组存储当前两个待排序部分排序后的顺序。快速排序是直接在原数组上找到基准元素应该在的位置。1、算法描述在数组中选择一个元素作为基准元素,通常选择当前待排序序列中第一个元素。用一个临时变量保存基准元素的值设置两个指针low和high,从两端开始遍历,先从high开始,遇到比基准元素小的就放到low位置此时low位置的元原创 2021-10-31 16:19:55 · 95 阅读 · 0 评论 -
常用排序算法(一)
刷题过程中对常用的排序算法有遗忘,所以写一篇笔记。一、冒泡排序一种简单的排序算法,重复地走过要需要排序的序列,比较相邻两个元素的大小。依次将较大的元素放到数组的末尾,或是依次将较小的元素放到数组的首部,直到走访工作全部结束。1、算法过程比较相邻的元素,如果顺序错误就交换对每一对相邻元素都做相同的工作,从第一对比到最后一对已经放到最后的元素在下一轮就不需要比较了,因为它已经是当前轮次最大的元素2、代码public int[] bubbleSort(int[] nums){原创 2021-10-30 20:36:04 · 77 阅读 · 0 评论 -
回溯问题-例二叉树中和为某一值的路径
一、题目剑指Offer-34题,给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。二、回溯问题这道题的思路就在于二叉树的深度优先遍历,也就是先序遍历。在到达某一结点的时候,将target = target - root.val,然后再继续递归结点的左子树和右子树,看是否满足和为target。关键点是:使用的List集合,在递归到左子树完成后,会保存左子树下结点的值(执行了path.add()操作),那么在递归右子原创 2021-10-29 10:58:24 · 94 阅读 · 0 评论 -
剑指Offer-34
二叉树中和为某一值的路径给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。叶子节点 是指没有子节点的节点。做法:dfs,回溯/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode原创 2021-10-28 22:29:18 · 60 阅读 · 0 评论 -
剑指Offer-36
二叉搜索树和双向链表输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。做法:dfs/*// Definition for a Node.class Node { public int val; public Node left; public Node right; public Node() {} public Node(int _val) { val = _v原创 2021-10-28 22:27:58 · 56 阅读 · 0 评论 -
剑指Offer-54
二叉搜索树的第k大结点给定一棵二叉搜索树,请找出其中第k大的节点。做法:二叉搜索树的中序遍历是递增序列,中序遍历之后返回第k大的元素即可/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */class原创 2021-10-27 21:54:12 · 58 阅读 · 0 评论 -
剑指Offer-13
机器人的运动范围地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?做法:典型的DFS题目class Solution { publi原创 2021-10-27 21:39:07 · 110 阅读 · 0 评论 -
剑指Offer-12
class Solution { public boolean exist(char[][] board, String word) { int m = board.length; int n = board[0].length; boolean[][] visited = new boolean[m][n]; for(int i = 0; i < m; i++){ for(int j = 0; j &.原创 2021-10-26 21:12:01 · 53 阅读 · 0 评论 -
剑指Offer-58 Ⅰ
翻转单词顺序输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. ",则输出"student. a am I"。做法:利用String类的trim()、split()方法class Solution { public String reverseWords(String s) { s = s.trim(); String[] strs = s.split("原创 2021-10-26 20:08:51 · 64 阅读 · 0 评论 -
剑指Offer-57
和为s的两个数字输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。做法:递增数组,指针指向两端,从两端开始寻找即可class Solution { public int[] twoSum(int[] nums, int target) { //递增排序数组,从两端开始找元素 int left = 0; int right = nums.length-1;原创 2021-10-26 19:33:29 · 50 阅读 · 0 评论 -
剑指Offer-21
调整数组的顺序使奇数位于偶数的前面输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数在数组的前半部分,所有偶数在数组的后半部分。做法:双指针,前指针遇到偶数就与后指针位置的元素交换,后指针--,前指针不变继续判断交换过来的元素class Solution { public int[] exchange(int[] nums) { //前后指针,前方指针遇到偶数就与后指针位置的元素交换 //交换后,后指针所指位置一定是偶数,后指针--原创 2021-10-26 19:28:52 · 59 阅读 · 0 评论 -
剑指Offer-25
合并两个排序的数组输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。做法:双指针/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */class Solution { public ListNode mergeTwo原创 2021-10-24 16:06:11 · 47 阅读 · 0 评论 -
剑指Offer-22
链表中倒数第k个结点输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。做法1:使用栈/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next;原创 2021-10-24 15:48:47 · 56 阅读 · 0 评论 -
剑指Offer-18
删除链表的节点给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。返回删除后的链表的头节点。做法:用两个指针记录下当前结点和当前结点的前一个结点即可/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */class Solutio原创 2021-10-24 15:32:43 · 48 阅读 · 0 评论 -
剑指Offer-48
最长不含重复字符串请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。做法:使用HashMap记录每个字符最后一次出现的位置,如果出现重复的字符,就把当前字符上一次出现位置的下一个位置作为新起点,继续遍历class Solution { public int lengthOfLongestSubstring(String s) { int max = 0; int left = 0; Map<Charact原创 2021-10-24 12:10:36 · 46 阅读 · 0 评论 -
剑指Offer-47
礼物的最大价值在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?做法:动态规划。每一个格子的价值最多只有两种情况:1、左边的格子最大价值+当前格子的价值;2、上边格子的最大价值+当前格子的价值 如果为第一行,那么当前格子只能从左边格子跳转来 如果为第一列,当前格子只能从上边...原创 2021-10-22 22:31:46 · 49 阅读 · 0 评论 -
剑指Offer-42
连续子数组的最大和输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。做法:动态规划,若dp[n-1] < 0,则对dp[n]为负作用,令dp[n] = nums[n]即可;若dp[n-1] > 0,则当前dp[n] = dp[n-1] + nums[n]。始终保存最大的dp[n]为maxclass Solution { public int maxSubArray(int[] nums) {原创 2021-10-22 21:55:48 · 55 阅读 · 0 评论 -
剑指Offer-10 Ⅱ*
青蛙跳台阶问题一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。做法:青蛙来到最后一步有两种情况:跳1阶,此时对应有f(n-1)种方法;跳2阶,此时对应有f(n-2)种方法。即f(n) = f(n-1) + f(n-2),为斐波那契数列问题,只是初始值不同而已class Solution { public int numWays(in原创 2021-10-21 19:08:33 · 60 阅读 · 0 评论 -
剑指Offer-10 Ⅰ
斐波那契数列写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下:F(0) = 0, F(1)= 1F(N) = F(N - 1) + F(N - 2), 其中 N > 1.斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。做法:递归会栈溢出,这里使用动态规划来解决class S...原创 2021-10-21 18:55:08 · 66 阅读 · 0 评论 -
剑指Offer-26**
树的子结构输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)B是A的子结构, 即 A中有出现和B相同的结构和节点值。做法:判读当前A树是否包含B树,当A、B都不为空,遍历到B为空时返回true,如果A先遍历到空或值不相等,返回false。 再递归判断A的左子树是否包含B,A的右子树是否包含B/** * Definition for a binary tree node. * public class TreeNode {...原创 2021-10-20 21:14:05 · 50 阅读 · 0 评论 -
剑指Offer-28
对称的二叉树请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。做法:将二叉树的右子树镜像,与左子树比较是否相同/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * }原创 2021-10-20 20:42:44 · 57 阅读 · 0 评论 -
剑指Offer-27
二叉树的镜像请完成一个函数,输入一个二叉树,该函数输出它的镜像。做法:定义一个函数递归完成反转即可/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */class Solution { publ原创 2021-10-20 19:24:56 · 56 阅读 · 0 评论 -
剑指Offer-32 Ⅲ
从上到下打印二叉树请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。核心思想:判断当前层是第几层,来决定是顺序打印还是逆序打印/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; *原创 2021-10-19 20:30:24 · 54 阅读 · 0 评论 -
剑指Offer-32 Ⅱ
从上到下打印二叉树从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。核心思想:要求每层单独打印,可以根据当前队列中元素的个数判断需要循环几次 for(int i = queue.size(); i > 0; i--)/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; ...原创 2021-10-19 20:11:56 · 71 阅读 · 0 评论 -
剑指Offer-32 Ⅰ
从上到下打印二叉树从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。核心思想:采用队列实现/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */class Solution {原创 2021-10-19 19:58:11 · 59 阅读 · 0 评论 -
剑指Offer-04
二维数组中的查找在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。核心思想:每次以当前左下角的元素为基准,设为flag1、flag < target,则flag当前列的元素都小于target,则当前列可消除2、flag > target,则flag当前行的元素都大于target,则当前行可消除3、下标出界都没找到,返回falsecla原创 2021-10-18 21:17:37 · 53 阅读 · 0 评论 -
剑指Offer-50
第一个只出现一次的字符在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。做法:使用HashMapclass Solution { public char firstUniqChar(String s) { //哈希表遍历两次 char[] str = s.toCharArray(); Map<Character,Boolean> map = new HashMap<Charact原创 2021-10-18 20:53:08 · 47 阅读 · 0 评论 -
剑指Offer-11
旋转数组的最小值把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组[3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。核心思想:递增排序数组,考虑用二分。左边数组的值一定大于右边数组的值。计算出numbers[mid]:1、如果numbers[mid] > numbers[right],则说明此时mid在左边递增数组,旋转点区间为:(mid,right],此时lef...原创 2021-10-18 20:37:51 · 57 阅读 · 0 评论 -
剑指Offer-58
左旋转字符串字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。核心思想:拆分前后缀,再拼接到一起class Solution { public String reverseLeftWords(String s, int n) { char[] pre = s.toCharArray(); int leng原创 2021-10-15 20:11:06 · 59 阅读 · 0 评论 -
剑指Offer-53 Ⅱ
0~n-1中缺失的数字一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字核心思想:二分法查找,当前元素不等于下标值的位置,左边 nums[index] = index,右边nums[index] != indexclass Solution { public int missingNumber(int[] nums) { //排序数组的问题统一用二分法解决原创 2021-10-16 22:05:26 · 96 阅读 · 0 评论 -
剑指Offer-53 Ⅰ
在排序数组中查找数字 Ⅰ统计一个数字在排序数组中出现的次数。核心思想:得到元素第一次出现的位置,然后从原数组中统计出现次数class Solution { public int search(int[] nums, int target) { int index = firstIndex(nums,target); int count = 0; for(int i = index; i < nums.length; i++){原创 2021-10-16 21:46:58 · 65 阅读 · 0 评论 -
剑指Offer-03
数组中重复的数字在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。方法一:利用HashSet,O(N)\O(N)方法二:原地交换位置,把对应索引位置的数字换回来,如果重复就返回核心思想:由于n长度的数组中的元素范围是0~n-1,就把对应位置的元素放到对应的位置,如果当前位置的元素值就等于下标值,则向后一位判断;如果不等于下标值,就把该元素换到对应的下标处,原创 2021-10-16 21:13:39 · 60 阅读 · 0 评论 -
剑指Offer-05
替换空格请实现一个函数,把字符串 s 中的每个空格替换成"%20"。very easyclass Solution { public String replaceSpace(String s) { char[] str = s.toCharArray(); StringBuilder sb = new StringBuilder(); for(int i = 0; i < str.length; i++){原创 2021-10-15 20:01:23 · 52 阅读 · 0 评论 -
剑指Offer-24**
复杂链表的复制请实现 copyRandomList() 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null方法一:利用哈希表的查询特点,考虑构建 原链表节点 和 新链表对应节点 的键值对映射关系,再遍历构建新链表各节点的 next 和 random 引用指向即可。算法流程: 若头节点 head 为空节点,直接返回 nullnullnull ; 初始化: 哈希表 dic , 节点 ...原创 2021-10-14 20:45:27 · 48 阅读 · 0 评论 -
剑指Offer-24 *
反转链表定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。核心思想:修改链表的next指向/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */class Solution { public ListNode reve原创 2021-10-14 20:01:40 · 70 阅读 · 0 评论 -
剑指Offer-06
从尾到头打印链表输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。核心思想:使用一个栈,依次访问链表结点,将值入栈。再依次出栈添加到数组中即可/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */class Solution {原创 2021-10-14 19:45:07 · 50 阅读 · 0 评论