力扣刷题之剑指offer
迪恩_Emma
喜欢看书的Java开发
展开
-
剑指 Offer 12. 矩阵中的路径(中等)
思路:这题与岛屿数量问题类似,用深度优先(回溯算法)题目有2个限制条件:i)通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格ii)同一个单元格内的字母不允许被重复使用代码:class Solution { public boolean exist(char[][] board, String word) { ArrayDeque<Character> path=new ArrayDeque<>();..原创 2021-04-19 10:52:59 · 90 阅读 · 0 评论 -
剑指 Offer 68 - II. 二叉树的最近公共祖先(简单)
思路:注意本题是求二叉树的,而不是二叉搜索树的,区别是:二叉搜索树不需要判断null返回,而二叉树需要代码:class Solution { public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { if(root==null||p==root||q==root){ return root; } TreeNode left=lowestCommonAncesto.原创 2021-05-18 10:12:28 · 128 阅读 · 0 评论 -
剑指 Offer 68 - I. 二叉搜索树的最近公共祖先(简单)
思路:方法一:迭代(自顶向下)方法二:递归(自底向上)代码:迭代:class Solution { public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { while(root!=null){ //全在左边 if(p.val<root.val&&q.val<root.val){ root=root.left; } .原创 2021-05-18 09:57:25 · 74 阅读 · 0 评论 -
剑指 Offer 67. 把字符串转换成整数(中等)
思路:将字符串变为字符数组,然后先判断首位,再往后判断,如果超过边界,直接根据前面的符号转换为-Integer.MIN_VALUE或Integer.MAX_VALUE代码:class Solution { public int strToInt(String str) { str=str.trim(); //先去首尾空格,再判空 if(str.length()==0){ return 0; } //判断首位:1.+-号 2.数字 boolean.原创 2021-05-17 10:04:55 · 70 阅读 · 0 评论 -
剑指 Offer 66. 构建乘积数组(中等)
思路:分为左下、右上两个三角代码:class Solution { public int[] constructArr(int[] a) { int n=a.length; if(n==0){ return new int[0]; } int[] dp=new int[n]; dp[0]=1; int temp=1; //左下三角循环 for(int i=1;i<n;i++){ //dp[i-1]代表左边的所有乘积 .原创 2021-05-17 09:29:05 · 86 阅读 · 0 评论 -
剑指 Offer 65. 不用加减乘除做加法(简单)
思路:不能用普通的加减法,就用位运算,也就是二进制的加减法代码:class Solution { public int add(int a, int b) { while(b!=0){ int c=(a&b)<<1;//c=进位 a=a^b;//a=非进位和 b=c;//将进位数赋给b=进位 } return a; }}分解:1)^是异或运算,与无进位和规律相同&是与运算,与进位规律相同..原创 2021-05-16 09:35:42 · 197 阅读 · 0 评论 -
剑指 Offer 64. 求1+2+…+n(中等)
思路:常规思路是:1.for进行全部的遍历(使用了for)2.递归(终止条件使用了if)代码:class Solution { int sum=0; public int sumNums(int n) { //使用&&来终止递归,就避免了用if语句 //使用一个boolean语句来使&&成为一个语句 //sumNums(n-1)要加上>0,否则也会报错 Boolean x=(n-1)>0&&su.原创 2021-05-16 09:05:40 · 74 阅读 · 0 评论 -
剑指 Offer 61. 扑克牌中的顺子(简单)
思路:因为题目规定了只抽取5张牌,则最大值-最小值不超过5的话就是连续的(除去大小王)很妙!!!代码:set判重class Solution { public boolean isStraight(int[] nums) { Set<Integer> set=new HashSet<>(); int min=14,max=0; for(int i=0;i<5;i++){ if(nums[i]==0) .原创 2021-05-15 10:44:12 · 122 阅读 · 0 评论 -
剑指 Offer 59 - II. 队列的最大值(中等)
思路:创建一个普通队列Queue和一个双端队列Deque代码:class MaxQueue { Queue<Integer> queue; Deque<Integer> deque; //初始化,没有返回值,并且和类名字相同 public MaxQueue() { queue=new LinkedList<>(); deque=new LinkedList<>(); } pu.原创 2021-05-14 09:57:57 · 103 阅读 · 0 评论 -
剑指 Offer 59 - I. 滑动窗口的最大值(困难)
思路:滑动窗口,使用双端队列作为滑动窗口代码:class Solution { public int[] maxSlidingWindow(int[] nums, int k) { if(nums==null||k==0){ return new int[0]; } //注意是Deque而不是Queue Deque<Integer> deque=new LinkedList<>.原创 2021-05-14 09:17:59 · 84 阅读 · 0 评论 -
剑指 Offer 58 - II. 左旋转字符串(简单)
思路:方法一:使用函数substring()截取字符串方法二:循环遍历,分两次,先后面,再前面代码:方法一:class Solution { public String reverseLeftWords(String s, int n) { String s1=s.substring(0,n); String s2=s.substring(n,s.length()); return s2+s1; }}方法二:class Solutio.原创 2021-05-14 08:15:36 · 75 阅读 · 0 评论 -
剑指 Offer 58 - I. 翻转单词顺序(简单)
思路:使用split语句以空格分割字符串,再用一个栈翻转字符代码:class Solution { public String reverseWords(String s) { Deque<String> stack=new ArrayDeque<>(); String[] strs=s.split(" "); //这里解决了中间出现2个空格以及首尾出现空格的问题 for(String str:strs){ if(!str.equal.原创 2021-05-13 10:18:55 · 91 阅读 · 0 评论 -
剑指 Offer 57 - II. 和为s的连续正数序列(简单)
思路:连续正整数序列,可以想到:1)用滑动窗口2)下标和值一一对应代码:class Solution { public int[][] findContinuousSequence(int target) { //双指针滑动窗口 int i=1,j=2,s=3; List<int[]> res=new ArrayList<>(); while(i<j){ if(s==target){ in.原创 2021-05-12 10:28:55 · 222 阅读 · 1 评论 -
剑指 Offer 57. 和为s的两个数字(简单)
思路:使用双指针,可以使时间复杂度提升为O(N),而暴力法起码要O(N^2)代码:class Solution { public int[] twoSum(int[] nums, int target) { int i=0,j=nums.length-1; while(i<j){ int s=nums[i]+nums[j]; if(s<target){ i++; } else if(s>target){ j--;.原创 2021-05-12 09:50:42 · 84 阅读 · 0 评论 -
剑指 Offer 56 - II. 数组中数字出现的次数 II(中等)
思路:方法一:位运算(省略)方法二:哈希统计代码:哈希class Solution { public int singleNumber(int[] nums) { Map<Integer,Boolean> map=new HashMap<>(); for(int num:nums){ if(!map.containsKey(num)){ map.put(num,false); } else{ map.put.原创 2021-05-12 09:26:09 · 66 阅读 · 0 评论 -
剑指 Offer 56 - I. 数组中数字出现的次数(中等)
思路:要求空间复杂度为O(1),则排除哈希法一个整型数组nums里除一个数字之外,其他数字都出现了两次可以用异或运算,留下来的数字是出现一次的数字x代码:class Solution { public int[] singleNumbers(int[] nums) { int x=0,y=0,n=0,m=1; for(int num:nums){ //得到2位数 n=n^num; } //得到第一个1,相当于找不同...原创 2021-05-11 10:42:04 · 224 阅读 · 0 评论 -
剑指 Offer 55 - II. 平衡二叉树(简单)
思路:利用递归,先序遍历/后序遍历代码:先序遍历:class Solution { public boolean isBalanced(TreeNode root) { //先序遍历,自顶向下 if(root==null) return true; return Math.abs(Depth(root.left)-Depth(root.right))<2&& isBalanced(root.left)&&isBalanc.原创 2021-05-11 09:51:46 · 127 阅读 · 0 评论 -
剑指 Offer 55 - I. 二叉树的深度(简单)
思路:深度优先遍历 / 广度优先遍历代码:dfs:class Solution { public int maxDepth(TreeNode root) { if(root==null) return 0; int left=maxDepth(root.left); int right=maxDepth(root.right); return Math.max(left+1,right+1); }}bfs:class S.原创 2021-05-10 09:50:35 · 66 阅读 · 0 评论 -
剑指 Offer 54. 二叉搜索树的第k大节点(简单)
思路:二叉搜索树的中序遍历是递增的!(左、根、右)可以利用这个特性,进行中序遍历逆序的遍历(右、根、左)代码:class Solution { int res=-1,k; public int kthLargest(TreeNode root, int k) { this.k=k; dfs(root); return res; } private void dfs( TreeNode root ){ if(root==null){ ret.原创 2021-05-10 09:14:47 · 92 阅读 · 0 评论 -
剑指 Offer 53 - II. 0~n-1中缺失的数字(简单)
思路:使用二分查找分成2个子数字,左子数组的下标和元素是一一对应相等的,但右子数组就不对应相等代码:class Solution { int[] nums; public int missingNumber(int[] nums) { int i=0,j=nums.length-1; while(i<=j){ int m=i+(j-i)/2; if(nums[m]==m){ i=m+1; } else{ j=m-1;.原创 2021-05-10 08:23:40 · 87 阅读 · 0 评论 -
剑指 Offer 53 - I. 在排序数组中查找数字 I(简单)
思路:方法一:哈希方法二:查找target的左边界和有边界,相减即可得到长度,也就是出现的次数代码:方法一:class Solution { public int search(int[] nums, int target) { Map<Integer,Integer> map=new HashMap<>(); for(int num:nums){ if(num==target){ map.put(target,map.get.原创 2021-05-09 12:28:42 · 198 阅读 · 0 评论 -
剑指 Offer 52. 两个链表的第一个公共节点(简单)
思路:A和B都走两回:A先把A的走完,再走B直到相交B先把B的走完,再走A直到相交若有相交点,必相交;若无,则是都为null设相交点为c:A走了:a+(b-c)B走了:b+(a-c)代码:public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { ListNode A=headA; ListNode B=..原创 2021-05-09 10:49:11 · 58 阅读 · 0 评论 -
剑指 Offer 51. 数组中的逆序对(困难)
思路:分治+归并代码:class Solution { int[] temp; public int reversePairs(int[] nums) { temp=new int[nums.length]; int res=mergeSort(nums,0,nums.length-1); return res; } private int mergeSort( int[] nums, int l, int r ){ if(l>=r).原创 2021-05-09 10:28:23 · 105 阅读 · 1 评论 -
剑指 Offer 50. 第一个只出现一次的字符(简单)
思路:使用哈希表,value存储的是Boolean值代码:class Solution { public char firstUniqChar(String s) { Map<Character,Boolean> map=new HashMap<>(); char[] arr=s.toCharArray(); for(char a:arr){ map.put(a,map.containsKey(a)); } for(char.原创 2021-05-09 09:27:42 · 60 阅读 · 0 评论 -
剑指 Offer 49. 丑数(中等)
思路:设置三个指针,每遍历到一个位置,都将该位置上三个指针的值分别乘以2、3、5,取最小值保存在该位置取到保存在该位置的指针可以+1代码:class Solution { public int nthUglyNumber(int n) { int a=0,b=0,c=0; int[] dp=new int[n]; dp[0]=1; for(int i=1;i<n;i++){ //注意是dp[a]*2而不是a*2 int n2=dp[a].原创 2021-05-08 09:40:32 · 126 阅读 · 0 评论 -
剑指 Offer 48. 最长不含重复字符的子字符串(中等)
思路:哈希表+双指针相当于滑动窗口,用哈希表来记录下标,改变左指针的位置代码:class Solution { public int lengthOfLongestSubstring(String s) { Map<Character,Integer> map=new HashMap<>(); int i=-1,res=0; //最开始只创建i //j用做循环 //j一直往后遍历,i随着出现.原创 2021-05-07 11:20:11 · 82 阅读 · 0 评论 -
剑指 Offer 47. 礼物的最大价值(中等)
思路:动态规划dp代码:class Solution { public int maxValue(int[][] grid) { int m=grid.length; int n=grid[0].length; int[][] dp=new int[m+1][n+1]; //0行0列就算不初始化也是默认为0,所以从1开始就行 for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ dp[i][.原创 2021-05-07 10:33:15 · 84 阅读 · 0 评论 -
剑指 Offer 46. 把数字翻译成字符串(中等)
思路:一道经典的动态规划dp,判断前2个数是否满足>=10&&<=25,若满足,则有2种翻译方法,并且还要加上前面的所有情况方法一:dp方法二:用字母代替dp代码:方法一:class Solution { public int translateNum(int num) { String s=String.valueOf(num); //要比s的长度+1 int[] dp=new int[s.length()+1]; dp[.原创 2021-05-07 10:14:16 · 99 阅读 · 0 评论 -
剑指 Offer 45. 把数组排成最小的数(中等)
思路:实际上就是排序,将数组排好序,然后一个个接到StringBuilder中方法一:自定义双边快速排序方法二:重写Arrays.sort()方法,该方法本质也是一个快排方法三:小顶堆(小的在堆顶)代码:方法一:class Solution { public String minNumber(int[] nums) { StringBuilder res=new StringBuilder(); String[] str=new String[num.原创 2021-05-06 21:42:15 · 150 阅读 · 0 评论 -
剑指 Offer 42. 连续子数组的最大和(简单)
思路:动态规划dp代码:class Solution { public int maxSubArray(int[] nums) { int[] dp=new int[nums.length]; dp[0]=nums[0]; int max=dp[0]; for(int i=1;i<nums.length;i++){ dp[i]=Math.max(dp[i-1]+nums[i],nums[i]); max=Math.max(dp[i],max.原创 2021-05-05 15:18:26 · 60 阅读 · 0 评论 -
剑指 Offer 41. 数据流中的中位数(困难)
思路:使用2个优先队列,一个存储较大的一半,另一个存储较小的一半如果是奇数,就返回小顶堆(存储较大一半)的堆顶元素如果是偶数,就返回两堆堆顶元素/2.0的值代码:class MedianFinder { Queue<Integer> A,B; /** initialize your data structure here. */ public MedianFinder() { A=new PriorityQueue<>();//小.原创 2021-05-05 11:08:09 · 89 阅读 · 0 评论 -
剑指 Offer 40. 最小的k个数(简单)
思路:方法一:java给的函数方法Arrays.sort方法二:快速排序+二分方法三:大根堆(前k小),默认是小根堆,所以要重写代码:方法一:class Solution { public int[] getLeastNumbers(int[] arr, int k) { Arrays.sort(arr); int[] res=new int[k]; for(int i=0;i<k;i++){ res[i]=arr[i]; } retu.原创 2021-05-04 11:25:12 · 383 阅读 · 0 评论 -
剑指 Offer 39. 数组中出现次数超过一半的数字(简单)
思路:方法一:哈希,保存每一个num出现的次数方法二:排序,超过一半的众数一定出现在中位数上方法二:摩尔投票,将第一个数作为众数,往后遍历。若与该数相同,则vote+1,否则-1。每次vote为0时更换众数代码:方法一:class Solution { public int majorityElement(int[] nums) { Map<Integer,Integer> map=new HashMap<>(); for(int .原创 2021-05-04 09:57:14 · 57 阅读 · 0 评论 -
剑指 Offer 38. 字符串的排列(中等)
思路:与46全排列的题目一样,都是深度优先搜索(回溯算法)这里的不同点是进行2个方面的剪枝:i)当前遍历的字母,不能出现重复,也就是visited[i]!=true才行ii)当要求的几个字符串中有重复的字母出现时方法一:自定义一个方法排除重复字符串方法二:Set排序重复字符串代码:方法一:class Solution { public String[] permutation(String s) { List<String> pre=..原创 2021-05-03 11:40:10 · 124 阅读 · 1 评论 -
剑指 Offer 37. 序列化二叉树(困难)
思路:序列化:相当于一个层序遍历,使用广度优先遍历,与别的题目的区别是:如果该节点不是null,并且如果该节点的左、右节点中有null,也要把该节点算上反序列化:判断的条件有点不同,在不是null的情况下才把节点接在根节点下,并且加入队列中代码:/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * ..原创 2021-05-02 22:38:36 · 76 阅读 · 0 评论 -
剑指 Offer 36. 二叉搜索树与双向链表(中等)
思路:对二叉树进行中序遍历,也就是左、根、右的顺序,最后返回head即可// 打印中序遍历void dfs(Node root) { if(root == null) return; dfs(root.left); // 左 System.out.println(root.val); // 根 dfs(root.right); // 右}代码:/*// Definition for a Node.class Node { publ.原创 2021-05-01 11:28:46 · 71 阅读 · 0 评论 -
剑指 Offer 35. 复杂链表的复制(中等)
思路:方法一:使用哈希表方法二:原地修改代码:方法一:/*// Definition for a Node.class Node { int val; Node next; Node random; public Node(int val) { this.val = val; this.next = null; this.random = null; }}*/class Solut.原创 2021-05-01 10:57:04 · 137 阅读 · 0 评论 -
剑指 Offer 34. 二叉树中和为某一值的路径(中等)
思路:典型的深度优先遍历(回溯算法)代码:class Solution { public List<List<Integer>> pathSum(TreeNode root, int target) { List<List<Integer>> res=new ArrayList<>(); List<Integer> path=new ArrayList<Integer>();.原创 2021-04-30 11:38:39 · 75 阅读 · 0 评论 -
剑指 Offer 33. 二叉搜索树的后序遍历序列(中等)
思路:此题只是判断数组是否符合条件,只需要判断数组即可,不用返回数组方法一:深度优先搜索(递归)方法二:单调栈代码:方法一:class Solution { public boolean verifyPostorder(int[] postorder) { return dfs(postorder,0,postorder.length-1); } private boolean dfs( int[] postorder, int.原创 2021-04-30 10:40:00 · 107 阅读 · 0 评论 -
剑指 Offer 32 - III. 从上到下打印二叉树 III(中等)
思路:层序遍历(BFS)+奇偶层逻辑判断代码:/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */class Solution { public List<List<Inte.原创 2021-04-29 09:49:03 · 71 阅读 · 0 评论