目录

  • 前言
  • 第一天(栈与队列)
    • 剑指 Offer 09. 用两个栈实现队列(简单)
    • 剑指 Offer 30. 包含min函数的栈(简单)
  • 第二天(链表)
    • 剑指 Offer 06. 从尾到头打印链表(简单)
    • 剑指 Offer 24. 反转链表(简单)
  • 第三天(字符串)
    • 剑指 Offer 05. 替换空格(简单)
    • 剑指 Offer 58 - II. 左旋转字符串(简单)
  • 第四天(查找算法)
    • 剑指 Offer 03. 数组中重复的数字(简单)
    • 剑指 Offer 53 - I. 在排序数组中查找数字 I(简单)
    • 剑指 Offer 53 - II. 0~n-1中缺失的数字(简单)
  • 第五天(查找算法)
    • 剑指 Offer 04. 二维数组中的查找(中等)
    • 剑指 Offer 50. 第一个只出现一次的字符(简单)
  • 第六天(搜索与回溯算法)
    • 剑指 Offer 32 - I. 从上到下打印二叉树(中等)
    • 剑指 Offer 32 - II. 从上到下打印二叉树 II(简单)
    • 剑指 Offer 32 - III. 从上到下打印二叉树 III(中等)
  • 第七天(搜索与回溯算法)
    • 剑指 Offer 26. 树的子结构(中等)*
    • 剑指 Offer 28. 对称的二叉树(简单)
    • 剑指 Offer 27. 二叉树的镜像(简单)
  • 第八天(动态规划)
    • 剑指 Offer 10- I. 斐波那契数列(简单)
    • 剑指 Offer 63. 股票的最大利润(中等)
  • 第九天(动态规划)
    • 剑指 Offer 42. 连续子数组的最大和(简单)
    • 剑指 Offer 47. 礼物的最大价值(中等)
  • 第十天(动态规划)
    • 剑指 Offer 48. 最长不含重复字符的子字符串(中等)
  • 第十一天(双指针)
    • 剑指 Offer 18. 删除链表的节点(简单)
    • 剑指 Offer 22. 链表中倒数第k个节点(简单)
  • 第十二天(双指针)
    • 剑指 Offer 25. 合并两个排序的链表(简单)
    • 剑指 Offer 52. 两个链表的第一个公共节点(简单)
  • 第十三天(双指针)
    • 剑指 Offer 21. 调整数组顺序使奇数位于偶数前面(简单)
    • 剑指 Offer 57. 和为s的两个数字(简单)
    • 剑指 Offer 58 - I. 翻转单词顺序(简单)
  • 第十四天(搜索与回溯算法)
    • 剑指 Offer 12. 矩阵中的路径(中等)
  • 第十五天(搜索与回溯算法)
    • 剑指 Offer 34. 二叉树中和为某一值的路径(中等)
    • 剑指 Offer 36. 二叉搜索树与双向链表(中等)*
    • 剑指 Offer 54. 二叉搜索树的第k大节点(简单)*

前言

该链接的学习计划如下:
剑指 Offer学习计划

第一天(栈与队列)

剑指 Offer 09. 用两个栈实现队列(简单)

题目:

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )

示例 1:

输入:
[“CQueue”,“appendTail”,“deleteHead”,“deleteHead”]
[[],[3],[],[]]
输出:[null,null,3,-1]

示例 2:

输入:
[“CQueue”,“deleteHead”,“appendTail”,“appendTail”,“deleteHead”,“deleteHead”]
[[],[],[5],[2],[],[]]
输出:[null,-1,null,null,5,2]

提示:

1 <= values <= 10000
最多会对 appendTail、deleteHead 进行 10000 次调用


思路:

class CQueue {LinkedList<Integer> stack1;LinkedList<Integer> stack2;public CQueue() {stack1 = new LinkedList<Integer>();stack2 = new LinkedList<Integer>();}public void appendTail(int value) {stack1.push(value);}public int deleteHead() {if (stack2.isEmpty()) {while (!stack1.isEmpty()) {stack2.push(stack1.pop());}}//因为源源不断的数据,如果2还是为空,没有添加进去,则返回为-1if(stack2.isEmpty()){return -1;}else return stack2.pop();}
}

剑指 Offer 30. 包含min函数的栈(简单)

题目:

定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。

示例:

MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.min(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.min(); --> 返回 -2.

提示:

各函数的调用总次数不超过 20000 次

注意:本题与主站 155 题相同:https://leetcode-cn.com/problems/min-stack/


思路:

class MinStack {LinkedList<Integer>inStack;
LinkedList<Integer>minStack;/** initialize your data structure here. *///此处的LinkedList不能用addLast和removeLastpublic MinStack() {inStack=new LinkedList<>();minStack=new LinkedList<>();//这个栈先压入一个最大的栈帧,主要为了和peek进行比较最小minStack.push(Integer.MAX_VALUE);}public void push(int x) {inStack.push(x);//最小栈帧,主要为了时刻比较最小的值,通过和栈顶进行比较minStack.push(Math.min(minStack.peek(),x));}public void pop() {//出栈的时候,两者都要同时出栈inStack.pop();minStack.pop();}public int top() {return inStack.peek();}public int min() {return minStack.peek();}
}

第二天(链表)

剑指 Offer 06. 从尾到头打印链表(简单)

题目:

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

示例 1:

输入:head = [1,3,2]
输出:[2,3,1]

限制:

0 <= 链表长度 <= 10000


思路:

class Solution {public int[] reversePrint(ListNode head) {//通过list的列表形式List <Integer> list =new ArrayList <>();ListNode node=head;while(node!=null){list.add(node.val);node=node.next;}int n=list.size();int[] ss=new int[n];for(int i=0,j=n-1;i<n&&j>=0;i++,j--){ss[i]=list.get(j);}return ss;}
}

或者通过栈的形式:

class Solution {public int[] reversePrint(ListNode head) {Deque <Integer> stack =new LinkedList <>();ListNode node=head;while(node!=null){stack.push(node.val);node=node.next;}int n=stack.size();int[] ss=new int[n];for(int i=0;i<n;i++){ss[i]=stack.pop();}return ss;}
}

剑指 Offer 24. 反转链表(简单)

题目:略


思路

class Solution {public ListNode reverseList(ListNode head) {//这两个条件缺一不可,因为递归返回值会有越界的那一刻if(head==null||head.next==null)return head;//主要是为了给递归做一个返回值           ListNode newhead=reverseList(head.next);head.next.next=head;head.next=null;return newhead;}
}

或者直接使用迭代

class Solution {public ListNode reverseList(ListNode head) {ListNode pre=null;ListNode cur=head;while(cur!=null){ListNode ans=cur.next;cur.next=pre;//这里是pre放入cur,cur指针放入ans位置中pre=cur;cur=ans;}return pre;}
}

第三天(字符串)

剑指 Offer 05. 替换空格(简单)

题目:

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

示例 1:

输入:s = “We are happy.”
输出:“We%20are%20happy.”

限制:

0 <= s 的长度 <= 10000


思路:
第一种:

class Solution {public String replaceSpace(String s) {  //通过StringBuilder进行添加StringBuilder res=new StringBuilder();for(Character c:s.toCharArray()){if(c==' ') res.append("%20");else res.append(c);}return res.toString();}
}

第二种: s.replace(" ", "%20") ;
第三种:

class Solution {public String replaceSpace(String s) {int length = s.length();char[] array = new char[length * 3];int size = 0;for (int i = 0; i < length; i++) {//不用定义成数组,直接定义成字符即可char c = s.charAt(i);if (c == ' ') {array[size++] = '%';array[size++] = '2';array[size++] = '0';} else {array[size++] = c;}}//之所以要拷贝数组,是因为newstr的数组后面都是0,所以拷贝array 的0-size距离到新的数组String newStr = new String(array, 0, size);return newStr;}
}

剑指 Offer 58 - II. 左旋转字符串(简单)

题目:
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

示例 1:

输入: s = “abcdefg”, k = 2
输出: “cdefgab”

示例 2:

输入: s = “lrloseumgh”, k = 6
输出: “umghlrlose”

限制:

1 <= k < s.length <= 10000


思路:

class Solution {public String reverseLeftWords(String s, int n) {//通过StringBuilder的追加形式StringBuilder ss=new StringBuilder();for(int i=n;i<s.length();i++){ss.append(s.charAt(i));}for(int i=0;i<n;i++){ss.append(s.charAt(i));}return ss.toString();}
}

或者通过字符串的切片

class Solution {public String reverseLeftWords(String s, int n) {return s.substring(n, s.length()) + s.substring(0, n);}
}

以及字符串的拼接:

class Solution {public String reverseLeftWords(String s, int n) {String res = "";for(int i = n; i < s.length(); i++)res += s.charAt(i);for(int i = 0; i < n; i++)res += s.charAt(i);return res;}
}

第四天(查找算法)

剑指 Offer 03. 数组中重复的数字(简单)

题目:

找出数组中重复的数字。

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

示例 1:

输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3

限制:

2 <= n <= 100000


思路:
如果使用hashmap
(耗时14ms)

class Solution {public int findRepeatNumber(int[] nums) {Map<Integer,Integer>map=new HashMap<>();for(int num:nums){map.put(num,map.getOrDefault(num,0)+1);}for(Map.Entry<Integer,Integer>entry:map.entrySet()){if(entry.getValue()==2)return entry.getKey();}return nums[0];}
}

但本身hashset就有去重
耗时(7ms)

class Solution {public int findRepeatNumber(int[] nums) {Set <Integer> xx=new HashSet<>();for(int num:nums){if(xx.contains(num))return num;xx.add(num);}return 0;}
}

原地置换,耗时0ms

class Solution {public int findRepeatNumber(int[] nums) {int i=0;//不能使用for,是因为只有满足i等于nums【i】的时候才是排序好了while(i<nums.length){if(i==nums[i]){i++;continue;}//如果已经置换过了,说明原位置已经有重复了,直接输出其值即可if(nums[nums[i]]==nums[i])return nums[i];//此处为置换排序,根本的思想其实就是nums[nums[i]]==nums[i]int temp=nums[i];nums[i]=nums[temp];nums[temp]=temp;}return -1;}
}

剑指 Offer 53 - I. 在排序数组中查找数字 I(简单)

题目:

统计一个数字在排序数组中出现的次数。

示例 1:

输入: nums = [5,7,7,8,8,10], target = 8
输出: 2

示例 2:

输入: nums = [5,7,7,8,8,10], target = 6
输出: 0

提示:

0 <= nums.length <= 105
-109 <= nums[i] <= 109
nums 是一个非递减数组
-109 <= target <= 109

注意:本题与主站 34 题相同(仅返回值不同):https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/


思路:
该题解主要参考了面试题53 - I. 在排序数组中查找数字 I(二分法,清晰图解)

class Solution {public int search(int[] nums, int target) {int l=0,r=nums.length-1;//搜索右边界相等的值while(l<=r){int mid=l+(r-l)/2;if(nums[mid]<=target)l=mid+1;else if(nums[mid]>target)r=mid-1;}//l与r越界 相反时候,while结束循环,将其右边界的值赋值给rightint right=r;// 若数组中无 target ,则提前返回//条件重要if(r >= 0 && nums[r] != target) return 0;//搜索左边界相等的值l=0;r=nums.length-1;while(l<=r){int mid=l+(r-l)/2;if(nums[mid]<target)l=mid+1;else if(nums[mid]>=target)r=mid-1;}//通过层层逼近,求得左边界的值int left=l;return right-left+1;}
}

以上代码有些冗余,可看如下将其封装

class Solution {public int search(int[] nums, int target) {return helper(nums, target) - helper(nums, target - 1);}int helper(int[] nums, int tar) {int i = 0, j = nums.length - 1;while(i <= j) {int m = (i + j) / 2;if(nums[m] <= tar) i = m + 1;else j = m - 1;}return i;}
}

拓展题,求左右边界的范围输出
题目链接如下:
34. 在排序数组中查找元素的第一个和最后一个位置

思路差不多,代码如下:

class Solution {public int[] searchRange(int[] nums, int target) {//最开始的初值条件 要先判断好if(nums.length == 0) return new int[]{-1,-1};//int []a=new int[2];int l=0;int r=nums.length-1;while(l<=r){int mid=l+(r-l)/2;if(nums[mid]<=target)l=mid+1;else if(nums[mid]>target)r=mid-1;}//如果右边界不符合,则直接返回-1,-1if(r>=0&&nums[r]!=target)return new int[]{-1,-1};int R=r;l=0;r=nums.length-1;while(l<=r){int mid=l+(r-l)/2;if(nums[mid]<target)l=mid+1;else if(nums[mid]>=target)r=mid-1;}//如果左边界不符合,则直接返回-1,-1//之所以要多判断一次,可能左边界也不符合,会返回越界值if(l>=0&&nums[l]!=target)return new int[]{-1,-1};int L=l;return new int[]{L,R};}
}

剑指 Offer 53 - II. 0~n-1中缺失的数字(简单)

题目:

一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。

示例 1:

输入: [0,1,3]
输出: 2

示例 2:

输入: [0,1,2,3,4,5,6,7,9]
输出: 8

限制:

1 <= 数组长度 <= 10000


思路:

下面的时间复杂度比较高,因为顺序遍历的查找

class Solution {public int missingNumber(int[] nums) {for(int i=0;i<nums.length;i++){if(nums[i]!=i){return i;}}  return nums.length;}
}

之所以是有序的,可以通过二分查找进行遍历
思路链接如下:
面试题53 - II. 0~n-1 中缺失的数字(二分法,清晰图解)

class Solution {public int missingNumber(int[] nums) {int l=0,r=nums.length-1;//通过越界的时候跳出循环 判定r小于lwhile(l<=r){int mid=l+(r-l)/2;//说明前面的元素都是匹配的,就看后面的元素是否匹配//直接配对右边的元素,缩小复杂度//而且即使都符合,通过判定下一个元素的值,也就是left为输出值if(nums[mid]==mid)l=mid+1;else  r=mid-1;}return l;}
}

第五天(查找算法)

剑指 Offer 04. 二维数组中的查找(中等)

题目:

在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

示例:

现有矩阵 matrix 如下:

[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]

给定 target = 5,返回 true。

给定 target = 20,返回 false。

限制:

0 <= n <= 1000

0 <= m <= 1000

注意:本题与主站 240 题相同:https://leetcode-cn.com/problems/search-a-2d-matrix-ii/


思路:

class Solution {public boolean findNumberIn2DArray(int[][] matrix, int target) {//同时遍历,从左下角或者右上角开始遍历(不能选择左上或者右下,因为不好判断)//matrix.length-1是行长,matrix【0】.length-1是列长int i=matrix.length-1,j=0;//判断的初值条件都要满足这个,否则跳出while循环while(i>=0&&j<matrix[0].length){//行长度减1if(matrix[i][j]>target)i--;//列长度加1else if(matrix[i][j]<target)j++;else return true;}return false;}
}

从另外一个角遍历,实现z字形

//区分好 i 与 j的意义,也就是行列别弄混了
int i=0,j=matrix[0].length-1;
while(i<matrix.length&&j>=0){if(matrix[i][j]>target)j--;else if(matrix[i][j]<target)i++;else return true;
}
return false;

剑指 Offer 50. 第一个只出现一次的字符(简单)

题目:

在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。

示例 1:

输入:s = “abaccdeff”
输出:‘b’

示例 2:

输入:s = “”
输出:’ ’

限制:

0 <= s 的长度 <= 50000


思路:
使用数组来标记,也可使用哈希进行标记

class Solution {public char firstUniqChar(String s) {//先判断初始条件,如果为0,提前返回空if(s.length()==0)return ' ';//用数组来标记每个字母的多少个数int []cc=new int[26];for(int i=0;i<s.length();i++){cc[s.charAt(i)-'a']++;}//重新遍历一下s这个字符串,而不是遍历cc这个数组,因为返回值是返回s某个字符//不要遍历错,也不要返回错误的格式for(int i=0;i<s.length();i++){if(cc[s.charAt(i)-'a']==1)return s.charAt(i);}return ' ';}
}

一种巧妙的哈希遍历

这部分内容讲解来源于
面试题50. 第一个只出现一次的字符(哈希表 / 有序哈希表,清晰图解)

class Solution {public char firstUniqChar(String s) {HashMap<Character, Boolean> dic = new HashMap<>();char[] sc = s.toCharArray();for(char c : sc)//如果有这个值,第一次返回true,第二次返回falsedic.put(c, !dic.containsKey(c));//第一种方式//遍历整个字符数组,如果dic这个集合中有这个值的类型为true,则返回for(char c : sc)//获取到这个值的时候,如果只有第一次,则返回true,执行该true,返回c这个字符if(dic.get(c)) return c;return ' ';}
}

或者是改变一下Map的结构,使用LinkedHashMap(在哈希表的基础上,有序哈希表中的键值对是 按照插入顺序排序 的。基于此,可通过遍历有序哈希表,实现搜索首个 “数量为 1的字符”。)

而且遍历map结构的数据,通过转换为set结构
具体部分代码如下Map.Entry<Character,Boolean>map:dic.entrySet(),函数使用getKey以及getValue

class Solution {public char firstUniqChar(String s) {HashMap<Character, Boolean> dic = new LinkedHashMap<>();char[] sc = s.toCharArray();for(char c : sc)dic.put(c, !dic.containsKey(c));for(Map.Entry<Character,Boolean>map:dic.entrySet()){if(map.getValue())return map.getKey();}return  ' ';}
}

第六天(搜索与回溯算法)

剑指 Offer 32 - I. 从上到下打印二叉树(中等)

题目:

从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。

例如:
给定二叉树: [3,9,20,null,null,15,7],

提示:

节点总数 <= 1000


思路:

class Solution {public int[] levelOrder(TreeNode root) {//不存在的特殊情况,优先返回,如下情况if(root == null) return new int[0];List<Integer>list=new ArrayList<>();Queue<TreeNode> que=new LinkedList<>();que.offer(root);while(!que.isEmpty()){TreeNode node =que.poll();list.add(node.val);if(node.left!=null)que.offer(node.left);if(node.right!=null)que.offer(node.right);}int a[]=new int[list.size()];for(int i=0;i<list.size();i++){a[i]=list.get(i);}return a;}
}

剑指 Offer 32 - II. 从上到下打印二叉树 II(简单)

题目:

从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。

例如:
给定二叉树: [3,9,20,null,null,15,7],


提示:

节点总数 <= 1000
注意:本题与主站 102 题相同:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/


思路:

层次遍历的常规代码,加强记忆

class Solution {public List<List<Integer>> levelOrder(TreeNode root) {List<List<Integer>> list =new ArrayList<List<Integer>>();//别忘记最开始的初始条件if(root==null) return list;//队列添加node字段Queue<TreeNode> que=new LinkedList<>();que.offer(root);while(!que.isEmpty()){int n=que.size();List<Integer> sonlist=new ArrayList<>();for(int i=0;i<n;i++){TreeNode node= que.poll();sonlist.add(node.val);if(node.left!=null)que.offer(node.left);if(node.right!=null)que.offer(node.right);}list.add(sonlist);}return list;}
}

剑指 Offer 32 - III. 从上到下打印二叉树 III(中等)

题目:
请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。

例如:
给定二叉树: [3,9,20,null,null,15,7],

返回其层次遍历结果:

提示:

节点总数 <= 1000


思路:

第一种:直接使用Collectons的函数集

class Solution {public List<List<Integer>> levelOrder(TreeNode root) {List<List<Integer>> list =new ArrayList<List<Integer>>();if(root==null)return list;LinkedList<TreeNode> que=new LinkedList<>();que.offer(root);int sum=0;while(!que.isEmpty()){int n=que.size();List<Integer> sonlist=new ArrayList<>();for(int i=0;i<n;i++){TreeNode node = que.pop();sonlist.add(node.val);     if(node.left!=null)que.offer(node.left);if(node.right!=null)que.offer(node.right);}//判断层次第几层,某个层次直接开始反转//调用的是Collectons的函数集if(sum%2==1){Collections.reverse(sonlist);}sum++;list.add(sonlist);}return list;}
}

第七天(搜索与回溯算法)

剑指 Offer 26. 树的子结构(中等)*

题目:
输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)

B是A的子结构, 即 A中有出现和B相同的结构和节点值。

例如:
给定的树 A:

返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。

示例 1:

输入:A = [1,2,3], B = [3,1]
输出:false

示例 2:

输入:A = [3,4,5,1,2], B = [4,1]
输出:true

限制:

0 <= 节点个数 <= 10000


思路:

知道终止条件以及判断的条件,层层递归即可

关于这个题解,比较全面的解释如下:

具体链接题解如下:
面试题26. 树的子结构(先序遍历 + 包含判断,清晰图解)

class Solution {public boolean isSubStructure(TreeNode A, TreeNode B) {//if(A==null)return false;//if(B==null)return false;//事先判断一下root节点,如果两者其中有一个为null则返回false。如果都为null,返回trueif (B == null || A == null) {return false;}//先判断根节点是否为满足以及层层遍历,如果是,则返回trueif(A.val==B.val && dfs(A.left,B.left)&&dfs(A.right,B.right)){return true;}//只需要判断一个方向即可,或并起来return isSubStructure(A.left,B)||isSubStructure(A.right,B);}public boolean dfs(TreeNode A,TreeNode B){//内部结构,如果B节点先为null则已经判断完了。A为null则返回falseif(B==null)return true;if(A==null)return false;if(A.val==B.val){return dfs(A.left,B.left)&&dfs(A.right,B.right);}else {return false;}}
}
class Solution {public boolean isSubStructure(TreeNode A, TreeNode B) {//这个写法不像上面,统一一起判断即可。判断值是否相等在递归条件中//外层调用的函数只要两个都不为null, 而且只满足一个dfs(A,B) 或者递归下一层的结构节点return (A!=null && B!=null) && (dfs(A,B) || isSubStructure(A.left,B) || isSubStructure(A.right,B));}public boolean dfs(TreeNode A,TreeNode B){//内部结构,如果B节点先为null则已经判断完了。A为null则返回falseif(B==null)return true;//如果A为null,则说明还有节点没判断完。或者是两者不相等if(A==null || A.val!=B.val)return false;return dfs(A.left,B.left)&&dfs(A.right,B.right);}
}

剑指 Offer 28. 对称的二叉树(简单)

题目:


思路:

深度优先遍历:

class Solution {public boolean isSymmetric(TreeNode root) {return ss(root,root);}public boolean ss(TreeNode L1,TreeNode L2){if(L1==null&&L2==null) return true;if(L1 ==null ||L2==null) return false;return  L1.val==L2.val && ss(L1.left,L2.right) && ss(L1.right,L2.left);}
}

广度优先遍历:

class Solution {public boolean isSymmetric(TreeNode root) {return bfs(root,root);}//返回值类型为booleanpublic boolean bfs(TreeNode L1,TreeNode L2){Queue<TreeNode>que=new LinkedList<>();que.offer(L1);que.offer(L2);//for(int i=0;i<n;i++){while(!que.isEmpty()){TreeNode v1=que.poll();TreeNode v2=que.poll();//一个个判断过于冗余//if(v1.left!=null){//    que.offer(v1.left)//}//如果两个都为null则继续if(v1==null&&v2==null)continue;//这三个条件有哪个条件不满足则返回为falseif(v1==null||v2==null||v1.val!=v2.val)return false;que.offer(v1.left);que.offer(v2.right);que.offer(v1.right);que.offer(v2.left);}return true;}}

剑指 Offer 27. 二叉树的镜像(简单)

题目:

请完成一个函数,输入一个二叉树,该函数输出它的镜像。

例如输入:

限制:

0 <= 节点个数 <= 1000

注意:本题与主站 226 题相同:https://leetcode-cn.com/problems/invert-binary-tree/


思路:

利用递归的方式,将其root的left指向right节点,但是不能同时将root的right指向left节点,因为节点互换不能这么使用

class Solution {public TreeNode mirrorTree(TreeNode root) {if(root == null) return null;TreeNode tmp = root.left;root.left = mirrorTree(root.right);root.right = mirrorTree(tmp);return root;}
}

或者用一个标记的点进行标记

class Solution {public TreeNode mirrorTree(TreeNode root) {if (root == null) {return null;}TreeNode left = mirrorTree(root.left);TreeNode right = mirrorTree(root.right);root.left = right;root.right = left;return root;}
}

广度优先遍历:

class Solution {public TreeNode mirrorTree(TreeNode root) {//不可以这么使用,返回的是TreeNode类型//List<TreeNode> list=new LinkedList<>();//if(root==null)return list;if (root == null) {return null;}Queue <TreeNode> que=new LinkedList<>();que.offer(root);while(!que.isEmpty()){int n=que.size();for(int i=0;i<n;i++){TreeNode node=que.poll();TreeNode temp = node.left;node.left = node.right;node.right = temp;if(node.left!=null)que.offer(node.left);if(node.right!=null)que.offer(node.right);}}return root;}}

第八天(动态规划)

剑指 Offer 10- I. 斐波那契数列(简单)

题目:

写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下:

F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

示例 1:

输入:n = 2
输出:1

示例 2:

输入:n = 5
输出:5

提示:

0 <= n <= 100


思路:

如果使用下面的方法会出现超时,所以不推荐下面这种动态规划

class Solution {public int fib(int n) {if(n==0)return 0;if(n==1)return 1;return fib(n-1)+fib(n-2);}
}

使用求余的计算方法:
具体如下:
Krahets的题解

class Solution {public int fib(int n) {int a=0,b=1,sum;for(int i=0;i<n;i++){//一共10个数sum=(a+b)%1000000007;//将b赋值给a,也就是移位a=b;b=sum;}return a;}
}

剑指 Offer 63. 股票的最大利润(中等)

题目:

假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?

示例 1:

输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。

示例 2:

输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

限制:

0 <= 数组长度 <= 10^5

注意:本题与主站 121 题相同:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/


思路:

class Solution {public int maxProfit(int[] prices) {//因为数组长度很大,所以要这样定义int min=Integer.MAX_VALUE;int sum=0;for(int i=0;i<prices.length;i++){//找到最小的值if(prices[i]<min){min=prices[i];}else {//如果后面的值都比前面大,则记录开始到现在的最大值,到底有多大sum=Math.max(prices[i]-min,sum);}}return sum;}
}

第九天(动态规划)

剑指 Offer 42. 连续子数组的最大和(简单)

题目:

输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。

要求时间复杂度为O(n)。

示例1:

输入: nums = [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

提示:

1 <= arr.length <= 10^5
-100 <= arr[i] <= 100
注意:本题与主站 53 题相同:https://leetcode-cn.com/problems/maximum-subarray/


思路:

通过前一段的值影响后一段的值,而且每次都记住当前最大的值

class Solution {public int maxSubArray(int[] nums) {//设置一个刚开始的临时变量值,主要为了前一个值的相加int pre=0;//设置一个最大值,主要为了保存其最大值的值int max=nums[0];for(int i=0;i<nums.length;i++){//不可以写成pre=Math.max(pre+nums[i],pre);因为他是连续的,宁愿断开重启一个,也不能断续pre=Math.max(pre+nums[i],nums[i]);//每个值都保存其最大的max=Math.max(pre,max);}return max;}
}

剑指 Offer 47. 礼物的最大价值(中等)

题目:
在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?

示例 1:

输入:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
输出: 12
解释: 路径 1→3→5→2→1 可以拿到最多价值的礼物

提示:

0 < grid.length <= 200
0 < grid[0].length <= 200


思路:

class Solution {public int maxValue(int[][] grid) {int m=grid.length;int n=grid[0].length;for(int i=0;i<m;i++){for(int j=0;j<n;j++){//不要忽略这一行,不要通过不了if(i == 0 && j == 0) continue;if(i==0){grid[0][j]=grid[0][j-1]+grid[0][j];}else if(j==0){grid[i][0]=grid[i-1][0]+grid[i][0];}else if (i!=0&&j!=0){grid[i][j]=Math.max(grid[i-1][j],grid[i][j-1])+grid[i][j];}}}return grid[m-1][n-1];}
}

或者利用辅助数组,通过多开一行一列,优化代码

class Solution {public int maxValue(int[][] grid) {int row = grid.length;int column = grid[0].length;//dp[i][j]表示从grid[0][0]到grid[i - 1][j - 1]时的最大价值int[][] dp = new int[row + 1][column + 1];for (int i = 1; i <= row; i++) {for (int j = 1; j <= column; j++) {dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];}}return dp[row][column];}
}

第十天(动态规划)

剑指 Offer 48. 最长不含重复字符的子字符串(中等)

题目:

请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。

示例 1:

输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。

示例 2:

输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。

示例 3:

输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。

提示:

s.length <= 40000

注意:本题与主站 3 题相同:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/


思路:

class Solution {public int lengthOfLongestSubstring(String s) {Set<Character>set=new HashSet<>();int n=s.length();int rk=-1,sum=0;//使用双指针的遍历方式,第一个指针为for循环for(int i=0;i<n;i++){if(i!=0){//每一个集合都是字符串的元素值,而不是下标值,不要疏忽漏掉了set.remove(s.charAt(i-1));}//第二个指针使用while结构,通过rk进行遍历while(rk+1<n&&!set.contains(s.charAt(rk+1))){set.add(s.charAt(rk+1));rk++;}//通过第二个指针减去第一个指针既为其长度值sum=Math.max(sum,rk-i+1);}return sum;        }}

第十一天(双指针)

剑指 Offer 18. 删除链表的节点(简单)

题目:


思路:

class Solution {public ListNode deleteNode(ListNode head, int val) {//使用头节点主要是因为如果删除的是第一个节点的话ListNode node=new ListNode(0);node.next=head;//使用ans假节点进行遍历ListNode ans=node;while(ans.next!=null){if(ans.next.val==val){ans.next=ans.next.next;break;}else{ans=ans.next;}}//正确的返回结果应该是头节点,也就是假头节点的下一个节点return node.next;}
}

或者使用双指针节点进行遍历

class Solution {public ListNode deleteNode(ListNode head, int val) {if(head.val == val) return head.next;ListNode pre = head, cur = head.next;while(cur != null && cur.val != val) {pre = cur;cur = cur.next;}if(cur != null) pre.next = cur.next;return head;}
}

剑指 Offer 22. 链表中倒数第k个节点(简单)

题目:

输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。

例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。

示例:

给定一个链表: 1->2->3->4->5, 和 k = 2.
返回链表 4->5.


思路:

class Solution {public ListNode getKthFromEnd(ListNode head, int k) {ListNode a=head;ListNode b=head;//a走k个节点for(int i=0;i<k;i++){a=a.next;}//a不为null的时候,b也一直走,最后输出b即可。追击问题while(a!=null){a=a.next;b=b.next;}return b;}
}

第十二天(双指针)

剑指 Offer 25. 合并两个排序的链表(简单)

题目:

输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。

示例1:

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4

限制:

0 <= 链表长度 <= 1000

注意:本题与主站 21 题相同:https://leetcode-cn.com/problems/merge-two-sorted-lists/


思路:

创建一个头节点,一个个判断,自个一开始书写的想法:

class Solution {public ListNode mergeTwoLists(ListNode l1, ListNode l2) {ListNode prev=new ListNode(0);ListNode prehead=prev;while(l1!=null||l2!=null){if(l1==null){prehead.next=l2;break;}else if(l2==null){prehead.next=l1;break;}else if(l1.val>=l2.val){prehead.next=l2;l2=l2.next;}else{prehead.next=l1;l1=l1.next;}prehead=prehead.next;}//头结点的next,记得输出这个格式return prev.next;       }
}

或者空节点在while循环之后判断:

class Solution {public ListNode mergeTwoLists(ListNode l1, ListNode l2) {ListNode prehead = new ListNode(-1);ListNode prev = prehead;while (l1 != null && l2 != null) {if (l1.val <= l2.val) {prev.next = l1;l1 = l1.next;} else {prev.next = l2;l2 = l2.next;}prev = prev.next;}// 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可prev.next = l1 == null ? l2 : l1;return prehead.next;}
}

也可通过递归遍历的形式输出

class Solution {public ListNode mergeTwoLists(ListNode list1, ListNode list2) {if(list1==null)return list2;else if (list2 ==null) return list1;else if (list1.val < list2.val) {list1.next=mergeTwoLists(list1.next,list2);return list1;}else  {list2.next=mergeTwoLists(list1,list2.next);return list2;}}
}

剑指 Offer 52. 两个链表的第一个公共节点(简单)

题目:

省略


思路:

public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {//初始值条件 要一开始就判断if(headA==null||headB==null){return null;}ListNode a=headA;ListNode b=headB;//w'hile 的判断是a!=b,毕竟找的是公共节点while(a!=b){if(a!=null){a=a.next;}else{a=headB;}if(b!=null){b=b.next;}else{b=headA;}}return a;}}

第十三天(双指针)

剑指 Offer 21. 调整数组顺序使奇数位于偶数前面(简单)

题目:

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数在数组的前半部分,所有偶数在数组的后半部分。

示例:

输入:nums = [1,2,3,4]
输出:[1,3,2,4]
注:[3,1,2,4] 也是正确的答案之一。

提示:

0 <= nums.length <= 50000
0 <= nums[i] <= 10000


思路:

类似快排的部分代码
双端开始遍历,前面找偶数,后面找奇数
然后交换即可

class Solution {public int[] exchange(int[] nums) {int i=0;int j=nums.length-1;while(i<j){while(i<j && nums[i]%2!=0)i++;while(i<j && nums[j]%2!=1)j--;swap(nums,i,j);}return nums;}public void swap(int[] nums,int i,int j){int temp=nums[i];nums[i]=nums[j];nums[j]=temp;}
}

剑指 Offer 57. 和为s的两个数字(简单)

题目:

输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[2,7] 或者 [7,2]

示例 2:

输入:nums = [10,26,30,31,47,60], target = 40
输出:[10,30] 或者 [30,10]

限制:

1 <= nums.length <= 10^5
1 <= nums[i] <= 10^6


思路:

class Solution {public int[] twoSum(int[] nums, int target) {int i=0;int j=nums.length-1;//因为本身是递增数组,此处用hashset的复杂度比双指针一次遍历要高//所以通过  最大的加最小的都比target大,所以最大的数舍弃;最小的加最大的都比target小,所以最小的舍弃while(i<j){int sum=nums[i]+nums[j];if(sum>target)j--;else if(sum<target)i++;else return new int[]{nums[i],nums[j]};}return new int[0];}
}

或者使用hashset的结构:(复杂度比上面那个高)

class Solution {public int[] twoSum(int[] nums, int target) {Set <Integer> set=new HashSet<>();for(int i=0;i<nums.length;i++){if(set.contains(target-nums[i])){return new int []{nums[i],target-nums[i]};}set.add(nums[i]);}return new int[0];}
}

剑指 Offer 58 - I. 翻转单词顺序(简单)

题目:leetcode:剑指 Offer 58 - I. 翻转单词顺序

dazhiyi

class Solutiopublic String reverseWords(String s) {List<String> list=Arrays.asList(s.trim().split("\\s+"));Collections.reverse(list);//用join函数将其列表添加空格return String.join(" ",list);}
}

或者另外一种做法:

class Solution {public String reverseWords(String s) {String[] strs = s.trim().split("\\s+"); // 删除首尾空格,分割字符串StringBuilder res = new StringBuilder();for(int i = strs.length - 1; i >= 0; i--) { // 倒序遍历单词列表if(strs[i].equals("")) continue; // 遇到空单词则跳过res.append(strs[i] + " "); // 将单词拼接至 StringBuilder}return res.toString().trim(); // 转化为字符串,删除尾部空格,并返回}
}
class Solution{public String reverseWords(String s) {StringBuilder sb=new StringBuilder();int i=s.length()-1,j=i;//使用双指针进行遍历,主要是从后往前遍历while(i>=0){while(i>=0 && s.charAt(i)!=' ')i--;sb.append(s.substring(i+1,j+1)+' ');while(i>=0 &&s.charAt(i)==' ')i--;j=i;}return sb.toString().trim();}
}

第十四天(搜索与回溯算法)

剑指 Offer 12. 矩阵中的路径(中等)

题目:

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

例如,在下面的 3×4 的矩阵中包含单词 “ABCCED”(单词中的字母已标出)。


示例 1:

输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCCED”
输出:true

示例 2:

输入:board = [[“a”,“b”],[“c”,“d”]], word = “abcd”
输出:false

提示:

1 <= board.length <= 200
1 <= board[i].length <= 200
board 和 word 仅由大小写英文字母组成

注意:本题与主站 79 题相同:https://leetcode-cn.com/problems/word-search/


思路:

class Solution {public boolean exist(char[][] board, String word) {int m=board.length;int n=board[0].length;//将其字符串 传给字符数组进行遍历char []c=word.toCharArray();//通过深度回溯遍历,一个字母一个一个往下遍历,如果最后不满足的时候,再从另外一个节点开始遍历for(int i=0;i<m;i++){for(int j=0;j<n;j++){//只有这个条件成立的时候,才会及时返回true,否则一直遍历到条件结束if(backtrace(board,c,i,j,0))return true;}}return false;}public boolean backtrace(char[][]board,char [] word,int i,int j,int k){//越界条件以及单词不匹配的时候返回falseif(i<0||i>=board.length||j<0||j>=board[0].length||board[i][j]!=word[k])return false;//数组长度等同于k的数量值的时候才返回为trueif(word.length-1==k)return true;//在回溯的时候,给予一个状态变量代表已经访问过了board[i][j]='\0';boolean falg=backtrace(board,word,i+1,j,k+1)||backtrace(board,word,i-1,j,k+1)||backtrace(board,word,i,j+1,k+1)||backtrace(board,word,i,j-1,k+1);//回溯结束的时候直接返回为初值值board[i][j] = word[k];return falg; }
}

第十五天(搜索与回溯算法)

剑指 Offer 34. 二叉树中和为某一值的路径(中等)

题目:

给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

叶子节点 是指没有子节点的节点。

示例 1:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]

示例 2:

输入:root = [1,2,3], targetSum = 5
输出:[]

示例 3:

输入:root = [1,2], targetSum = 0
输出:[]

提示:

树中节点总数在范围 [0, 5000] 内
-1000 <= Node.val <= 1000
-1000 <= targetSum <= 1000
注意:本题与主站 113 题相同:https://leetcode-cn.com/problems/path-sum-ii/


思路:

class Solution {List<List<Integer>> list=new ArrayList<List<Integer>>();LinkedList<Integer> sonlist=new LinkedList<>();public List<List<Integer>> pathSum(TreeNode root, int target) {if(root==null)return list;  backtrace(root,target);return list;}public void backtrace(TreeNode root,int target){//边界值超出的话要返回,通过root为null,返回上一层if(root==null)return;//不管有没有,先加入节点,后续在判断sonlist.addLast(root.val);  //每个节点加入之后要减去target-=root.val;//判断条件不只是为0,因为到叶子节点,还需要左右节点都为null,才可添加if(target==0 && root.left==null && root.right==null){list.add(new ArrayList<>(sonlist));//不用带return返回值}//标准的回溯,没有到叶子节点,则一直左右节点的跑backtrace(root.left,target);backtrace(root.right,target);//如果执行到这都没有,则把叶子节点删除sonlist.removeLast();//并且把刚那个节点加回去target+=root.val;}
}

剑指 Offer 36. 二叉搜索树与双向链表(中等)*

题目:leetcode:剑指 Offer 36. 二叉搜索树与双向链表

大致意思是将其二叉搜索树变为双向链表,并且是排序的


思路:
中序遍历,而且递归 前后节点的链表

class Solution {Node pre;//上一个节点,递归的cur为当前节点Node head;//记住头节点的,主要为了双向链表的头尾public Node treeToDoublyList(Node root) {if(root==null) return null;dfs(root);//双向链表的头尾节点head.left=pre;pre.right=head;return head;}public void dfs(Node cur){if(cur==null)return ;//左节点遍历dfs(cur.left);//根节点遍历,主要为了将其回溯的时候,子节点指向回溯的下一个节点(双向链表的下一个节点)if(pre!=null)pre.right=cur;//还可存储根节点else head=cur;//当前节点指向回溯上来的上一个节点(双向链表的上个节点)cur.left=pre;//pre移位置pre=cur;//右节点遍历dfs(cur.right);}
}

剑指 Offer 54. 二叉搜索树的第k大节点(简单)*

题目:

给定一棵二叉搜索树,请找出其中第 k 大的节点的值。

限制:

1 ≤ k ≤ 二叉搜索树元素个数


思路:

使用优先队列

class Solution {//默认是小顶堆,所以输入1423,输出的时候是1234,也就是出栈的时候是1234//为了修改成大顶堆,需要修改如下Queue <Integer> que=new PriorityQueue<>((o1,o2)->(o2-o1));public int kthLargest(TreeNode root, int k) {dfs(root);for(int i=1;i<=k;i++){//在等于k的时候,直接查看peek 可以减少时间内存。if(i==k)return que.peek();que.poll();}return 0;}public void dfs(TreeNode root){if(root==null)return;dfs(root.left);que.offer(root.val);dfs(root.right);}
}

或者使用如下
(二叉搜索树的原理)
因为是输出最大的第k个值所以使用先序遍历(从小到大)的反转也就是(右根左)


class Solution {int res;int index = 0; //计数器public int kthLargest(TreeNode root, int k) {dfs(root,k);return res;}void dfs(TreeNode root ,int k) {if(root == null) return;dfs(root.right,k); //右index++;if(k == index) res = root.val; //根dfs(root.left,k); //左}
}

【leetcode】 剑指 Offer学习计划(java版本含注释)(上)相关推荐

  1. 剑指Offer全题解—Java版本

    1.数组中重复的数字 题目描述 数组中重复的数字 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任 ...

  2. 剑指offer编程试题Java实现--22.从上往下打印二叉树

    个人博客:小景哥哥 22.从上往下打印二叉树 题目描述 从上往下打印出二叉树的每个节点,同层节点从左至右打印. import java.util.ArrayList; import java.util ...

  3. 【LeetCode】剑指 Offer 48. 最长不含重复字符的子字符串

    [LeetCode]剑指 Offer 48. 最长不含重复字符的子字符串 文章目录 [LeetCode]剑指 Offer 48. 最长不含重复字符的子字符串 package offer;import ...

  4. 剑指Offer第二版Java代码实现

    剑指Offer第二版Java代码实现 A.单例模式 面试题 2:实现Singleton模式 B.面试需要的基础知识 面试题 3:数组中重复的数字 面试题 4:二维数组的查找 面试题 5:替换空格 面试 ...

  5. 【LeetCode 剑指offer刷题】树题6:28 对称二叉树(101. Symmetric Tree)

    [LeetCode & 剑指offer 刷题笔记]目录(持续更新中...) 101. Symmetric Tree /**  * Definition for a binary tree no ...

  6. 【LeetCode 剑指offer刷题】数组题2:57 有序数组中和为s的两个数(167 Two Sum II - Input array is sorted)...

    [LeetCode & 剑指offer 刷题笔记]目录(持续更新中...) 57 有序数组中和为s的两个数 题目描述 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是 ...

  7. 【LeetCode 剑指offer刷题】字符串题6:67 把字符串转成整数

    [LeetCode & 剑指offer 刷题笔记]目录(持续更新中...) 67 把字符串转成整数 题目描述 将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数. 数值为0或者字符 ...

  8. 【剑指Offer学习】【全部面试题汇总】

    剑指Offer学习 剑指Offer这本书已经学习完了.从中也学习到了不少的东西,如今做一个总的文件夹.供自已和大家一起參考.学如逆水行舟.不进则退.仅仅有不断地学习才干跟上时候.跟得上技术的潮流! 全 ...

  9. 【LeetCode 剑指offer刷题】树题16:Kth Smallest Element in a BST

    [LeetCode & 剑指offer 刷题笔记]目录(持续更新中...) Kth Smallest Element in a BST Given a binary search tree, ...

最新文章

  1. Java Random()函数生成指定范围的随机数
  2. 一份字节跳动面试官给你的Java技术面试指南,彻底帮你搞懂
  3. 盲人可以也做软件工程师,反思一下老哥
  4. Mongodb3.4.4复制集群+分片配置文档
  5. 微型计算机技术第三版第三章答案,第3章微机组装技术作业(答案)
  6. “章子欣父亲”账号发文造假实锤 百度新闻负责人:是我的锅
  7. iCollections 7 for Mac(桌面整理工具)
  8. [洛谷P1501][国家集训队]Tree II(LCT)
  9. include/autoconfig.mk
  10. 基于js利用经纬度进行两地的距离计算(转)
  11. 计算机为什么逻辑判断准确,逻辑判断之评价型答题技巧
  12. 火车预购票系统设计JAVA_火车订票系统的设计与实现
  13. Struts2 通配符使用
  14. matlab zmax 光学仿真,基于ZEMAX的光栅干涉仪仿真
  15. 7.15周三晚8点,dotnet课堂全新起航,张善友/陈计节/刘腾飞我们一起来聊聊abp的故事...
  16. CSMA/CD和拥塞控制AIMD其实是一回事!
  17. openssl 制作证书, nginx https请求转http请求
  18. 32位无符号整数快开方函数
  19. 怎么把ppt弄成链接的形式_ppt链接excle表格:如何在ppt中超级链接到指定的excel工作表...
  20. 云原生时代,Kubernetes 让应用落地的 N 种招式(附 PPT)

热门文章

  1. Java字母加数字组合比较大小
  2. 进化树构建之邻接法(Neighbor-Joining)的介绍
  3. 漏洞复现----11、GlassFish任意文件读取
  4. Spring Boot 学习[四] web项目实战训练(增删改查,分页,排序)
  5. 去除 WPS 的广告
  6. Leetcode刷题-最长公共前缀
  7. 【排序算法(三)】直接插入排序及其改进
  8. 卷积神经网络 图像识别,卷积神经网络 图像处理
  9. 怎样将pdf格式转换成jpg
  10. 高德地图精确定位和获取地理位置