
剑指Offer
我是太阳男神
这个作者很懒,什么都没留下…
展开
-
剑指Offer-75二叉树的最近公共祖先
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { // root为空就直接返回空 p和q中有等于root的最近公共祖先即为root if(root == null || root == p || root == q) { return root; } // 递归遍历左子树 在左子树中找到了p或q 先找到谁就返回谁 TreeNode left = .原创 2021-04-25 11:37:13 · 160 阅读 · 0 评论 -
剑指Offer-74二叉搜索树的最近公共祖先
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { while(root != null) { // p,q 都在 root 的右子树中 if(root.val < p.val && root.val < q.val) { // 遍历至右子节点 root = root.right; .原创 2021-04-25 10:59:22 · 141 阅读 · 0 评论 -
剑指Offer-73把字符串转换成整数
public int strToInt(String str) { // 删除头尾空白符 char[] nums = str.trim().toCharArray(); if(nums.length == 0) { return 0; } int res = 0; // 边界值 两种越界情况 res > bndry 和 res = bndry 且 x > 7 int bndry = Integer.MAX_VALUE / .原创 2021-04-25 10:35:39 · 118 阅读 · 0 评论 -
剑指Offer-72构建乘积数组
/** * 思路:看做一张表格,列和行为a、b两个数组,对角线上的数组看做1,将表格分为上下两个三角 * @author Lucas * @date 2021/04/23 18:17 * @param a * @return int[] */public int[] constructArr(int[] a) { int len = a.length; //长度为0 直接返回空数组 if(len == 0){ return new int[0]; .原创 2021-04-23 18:30:21 · 104 阅读 · 0 评论 -
剑指Offer-71不用加减乘除做加法
public int add(int a, int b) { // 当进位为 0 时跳出 while(b != 0) { // c = 进位 int c = (a & b) << 1; // a = 非进位和 a ^= b; // b = 进位 b = c; } return a;}原创 2021-03-25 13:33:46 · 99 阅读 · 0 评论 -
剑指Offer-70求1+2+…+n
int res = 0;public int sumNums(int n) { // 当 n = 1 时 n > 1 不成立 ,此时短路,终止后续递归 boolean x = n > 1 && sumNums(n - 1) > 0; res += n; return res;}原创 2021-03-25 13:10:43 · 105 阅读 · 0 评论 -
剑指Offer-69股票的最大利润
public int maxProfit(int[] prices) { // 买不了就0 int res = 0; for (int i = 0; i < prices.length; i++){ for (int j = i + 1; j < prices.length; j++){ // 遍历找到最大利润 res = Math.max(res, prices[j] - prices[i]); .原创 2021-03-23 18:30:37 · 112 阅读 · 0 评论 -
剑指Offer-68圆圈中最后剩下的数字
public int lastRemaining(int n, int m) { // 把这个0 ~ n-1存起来 List<Integer> list = new ArrayList<>(); for (int i = 0; i < n; i++){ list.add(i); } int delete = 0; // 循环直到list中只剩一个 while (list.size() > 1){ .原创 2021-03-23 17:19:17 · 120 阅读 · 0 评论 -
剑指Offer-67扑克牌中的顺子
public boolean isStraight(int[] nums) { Set<Integer> repeat = new HashSet<>(); int max = 0, min = 14; for(int num : nums) { // 跳过大小王 不用考虑有几个大小王 因为不重复且最大-最小<5是形成顺子必然事件 if(num == 0) { continue; .原创 2021-03-23 16:32:43 · 123 阅读 · 0 评论 -
剑指Offer66-n个骰子的点数
public double[] dicesProbability(int n) { // 初始化一个筛子 double[] dp = new double[6]; // 初始化数组全是六分之一 Arrays.fill(dp, 1.0 / 6.0); for (int i = 2; i <= n; i++) { // 创建临时结果集 double[] tmp = new double[5 * i + 1]; for.原创 2021-03-16 17:56:52 · 115 阅读 · 0 评论 -
剑指Offer-65队列的最大值
// 存储队列Queue<Integer> queue;// 单调双向队列Deque<Integer> deque;public MaxQueue() { queue = new LinkedList<>(); deque = new LinkedList<>();}public int max_value() { // 空返回-1 非空返回队头 return deque.isEmpty() ? -1 : de.原创 2021-03-10 13:53:26 · 99 阅读 · 0 评论 -
剑指Offer-64滑动窗口的最大值
public int[] maxSlidingWindow(int[] nums, int k) { // 数组为空 直接返回空数组 if(nums.length == 0 || k == 0) { return new int[0]; } // 返回的结果 int res[] = new int[nums.length - k + 1]; // 左边界 int j = 0; // k为右边界 超出nums.length为出口.原创 2021-03-09 18:20:34 · 101 阅读 · 0 评论 -
剑指Offer-63左旋转字符串
public String reverseLeftWords(String s, int n) { // 重新拼接字符串 n - s.length() 加上 0 - n return s.substring(n) + s.substring(0, n);}原创 2021-03-08 14:50:55 · 118 阅读 · 0 评论 -
剑指Offer-62翻转单词顺序
public String reverseWords(String s) { // 不考虑线程安全 StringBuilder性能更好 StringBuilder stringBuilder = new StringBuilder(); // 并且空格分割成数组 String[] strings = s.split(" "); for (int i = strings.length - 1; i >= 0; i--){ // 遇到连续空格 直接.原创 2021-03-05 13:43:43 · 89 阅读 · 0 评论 -
剑指Offer-61和为s的连续正数序列
public int[][] findContinuousSequence(int target) { // 滑动窗口 int i = 1; int j = 2; int sum = 3; List<int[]> res = new ArrayList<>(); // i,j相遇即为出口 while(i < j) { // 小于时 j往后走 并把j加上 if(sum < target.原创 2021-03-04 13:48:54 · 135 阅读 · 1 评论 -
剑指Offer-60和为s的两个数字
public int[] twoSum(int[] nums, int target) { // 双指针 int i = 0; int j = nums.length - 1; // i,j相遇是出口 while(i < j) { int sum = nums[i] + nums[j]; // 递增序列 和小i++ if(sum < target) { i++; .原创 2021-03-03 22:21:16 · 107 阅读 · 2 评论 -
剑指Offer-59数组中数字出现的次数 II
public int singleNumber(int[] nums) { HashMap<Integer, Boolean> hashMap = new HashMap<>(); // 遍历将出现一次的数字value置为true,出现多次的value置为false for (int num : nums){ if (hashMap.get(num) == null){ hashMap.put(num, true);.原创 2021-03-02 15:25:32 · 127 阅读 · 0 评论 -
剑指Offer-58数组中数字出现的次数
public int[] singleNumbers(int[] nums) { int x = 0, y = 0, n = 0, m = 1; // 遍历异或 for(int num : nums) { n ^= num; } // 循环左移,计算 m while((n & m) == 0) { m <<= 1; } // 遍历 nums 分组 for(int num: nums).原创 2021-03-02 14:44:35 · 97 阅读 · 0 评论 -
剑指Offer-57平衡二叉树
public boolean isBalanced(TreeNode root) { return recur(root) != -1;}public int recur(TreeNode root) { // 后续遍历 if (root == null) { return 0; } int left = recur(root.left); if(left == -1) { return -1; } in.原创 2021-03-01 13:40:27 · 82 阅读 · 0 评论 -
剑指Offer-56二叉树的深度
public int maxDepth(TreeNode root) { // 后序遍历 if (root == null){ return 0; } // 此树的深度等于左子树的深度与右子树的深度中的最大值 +1 return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;}...原创 2021-03-01 11:44:39 · 100 阅读 · 0 评论 -
剑指Offer-55二叉搜索树的第k大节点
int res;int k;public int kthLargest(TreeNode root, int k) { this.k = k; dfs(root); return res;}public void dfs(TreeNode node){ // 以右 -> 根 -> 左的方式遍历树 即可得到倒序 方便查找第k大节点 if (node == null){ return; } dfs(node.righ.原创 2021-03-01 10:20:42 · 84 阅读 · 0 评论 -
剑指Offer-54 0~n-1中缺失的数字
public int missingNumber(int[] nums) { int i = 0; int j = nums.length - 1; while(i <= j) { // 二分查找 int m = (i + j) / 2; // 如果相等 证明前面没有缺失 则取 m + 1 ~ j if(nums[m] == m) { i = m + 1; // 否.原创 2021-03-01 09:53:22 · 93 阅读 · 0 评论 -
剑指Offer-53在排序数组中查找数字 I
public int search(int[] nums, int target) { // 找target的右边界 - target-1的右边界 return helper(nums, target) - helper(nums, target - 1);}int helper(int[] nums, int tar) { int i = 0; int j = nums.length - 1; // 二分法查找 while(i <= j) { .原创 2021-02-26 16:56:26 · 80 阅读 · 0 评论 -
剑指Offer-52两个链表的第一个公共节点
if (headA == null || headB == null) { return null;}// 双指针 消除两个链表的长度差ListNode pA = headA;ListNode pB = headB;// 直到A、B相遇while (pA != pB){ // A先自己遍历完 // 然后A就变成了B 继续遍历 if(pA == null){ pA = headB; }else{ pA = pA.next;.原创 2021-02-26 15:32:24 · 96 阅读 · 0 评论 -
剑指Offer-51数组中的逆序对
public int reversePairs(int[] nums) { // 用于合并阶段存放数组 int[] tmp = new int[nums.length]; return mergeSort(0, nums.length - 1, tmp, nums);}private int mergeSort(int l, int r, int[] tmp, int[] nums) { // 终止条件 if (l >= r) { ret.原创 2021-02-26 14:35:59 · 109 阅读 · 0 评论 -
剑指Offer-50第一个只出现一次的字符
public char firstUniqChar(String s) { // 遍历 for (int i = 0; i < s.length(); i++){ char ch = s.charAt(i); // 某个字符出现的位置就是当前i的位置 且 i之前没有出现过这个字符 if (i == s.lastIndexOf(ch) && !s.substring(0, i).contains(String.valueO.原创 2021-02-25 18:02:27 · 120 阅读 · 0 评论 -
剑指Offer-49丑数
/** * 动态规划 * 有规律后面的丑数都是由前面的丑数*2或*3或*5得来的 * 求得的丑数记录dp数组中 * 三个指针p2,p3,p5 * p2指向的数字下一次永远*2,p3指向的数字下一次永远*3,p5指向的数字永远*5 * 从2*p2 3*p3 5*p5取最小的数,作为第k个丑数 * 返回第n个丑数 */public int nthUglyNumber(int n) { int p2 = 0; int p3 = 0; int p5 = 0; in.原创 2021-02-25 17:17:30 · 94 阅读 · 0 评论 -
剑指Offer-48最长不含重复字符的子字符串
public int lengthOfLongestSubstring(String s) { Map<Character, Integer> dic = new HashMap<>(); int res = 0; int tmp = 0; for(int j = 0; j < s.length(); j++) { // 获取索引 i int i = dic.getOrDefault(s.charAt(j), -.原创 2021-02-25 13:32:16 · 122 阅读 · 0 评论 -
剑指Offer-47礼物的最大价值
public int maxValue(int[][] grid) { int m = grid.length; int n = grid[0].length; // 初始化矩阵第一行 for(int j = 1; j < n; j++) { grid[0][j] += grid[0][j - 1]; } // 初始化矩阵第一列 for(int i = 1; i < m; i++) { grid[i][0].原创 2021-02-25 11:36:04 · 105 阅读 · 0 评论 -
剑指Offer-46把数字翻译成字符串
public int translateNum(int num) { // 动态规划法 String s = String.valueOf(num); int[] dp = new int[s.length()+1]; // 初始化dp[0]代表空数字 dp[1]代表第一个数字 的组合翻译方式有一种 dp[0] = 1; dp[1] = 1; for (int i = 2; i <= s.length(); i++){ Stri.原创 2021-02-25 10:34:17 · 96 阅读 · 0 评论 -
剑指Offer-45把数组排成最小的数
public String minNumber(int[] nums) { // 想到排序的时候对字符串排序是根据首位ASCII码 符合题目意愿 String[] array = new String[nums.length]; // 转成String数组 for (int i = 0; i < nums.length ; i++){ array[i] = Integer.toString(nums[i]); } // Lambda表达.原创 2021-02-24 13:15:20 · 98 阅读 · 0 评论 -
剑指Offer-44数字序列中某一位的数字
public int findNthDigit(int n) { // 表示几位数 int digit = 1; // 几位数开始的数字 long start = 1; // 几位数一共有多少个 long count = 9; // 确定所在数字的是多少位的 while (n > count) { n -= count; digit += 1; // 总结出来的规律 sta.原创 2021-02-24 11:10:13 · 83 阅读 · 0 评论 -
剑指Offer-43 1~n 整数中 1 出现的次数
public int countDigitOne(int n) { int res = 0; // 标记当前位数 个位为1 十位为10 百位为100 。。。。 int digit = 1; // 初始化 // 当前位置前面的数字 int high = n / 10; // 当前位置的数字 int cur = n % 10; // 当前位置后面的数字 int low = 0; while (high != 0 || cu.原创 2021-02-24 10:34:26 · 94 阅读 · 0 评论 -
剑指Offer-42连续子数组的最大和
public int maxSubArray(int[] nums) { // 动态规划法 // 因为不需要输出具体是哪一段得出的最大和 直接在原数组上操作 int res = nums[0]; for(int i = 1; i < nums.length; i++) { // 以元素 nums[i] 为结尾的连续子数组最大和 // 如果它前面是个负数就不要加进来拖后腿了 加个0 最大和就是它本身 nums[i] += .原创 2021-02-23 13:01:35 · 92 阅读 · 0 评论 -
剑指Offer-41数据流中的中位数
PriorityQueue<Integer> A, B;public MedianFinder41() { //规定 小顶堆 保存较大的一半 长度为N/2 或 (N+1)/2 A = new PriorityQueue<>(); //规定 大顶堆 保存较小的一半 长度为N/2 或 (N-1)/2 B = new PriorityQueue<>((x, y) -> (y - x));}public void addNum(int.原创 2021-02-23 11:36:32 · 101 阅读 · 0 评论 -
Java中PriorityQueue优先队列
PriorityQueue使用跟普通队列一样,唯一区别是PriorityQueue会根据排序规则决定谁在队头,谁在队尾。PriorityQueue 通过add方法添加,通过poll方法一次获得一个最小元素,实现原理小顶堆,也就是说元素按照小顶堆结构存放。public static void main(String[] args) { PriorityQueue<Integer> q = new PriorityQueue<>(); //入列 q.of原创 2021-02-23 10:59:24 · 189 阅读 · 0 评论 -
剑指Offer-40最小的k个数
public int[] getLeastNumbers(int[] arr, int k) { Arrays.sort(arr); return Arrays.copyOf(arr, k);}当然不能直接调API复习一下快排吧public int[] getLeastNumbers(int[] arr, int k) { quickSort(arr, 0, arr.length - 1); return Arrays.copyOf(arr, k);}.原创 2021-02-22 13:37:17 · 84 阅读 · 0 评论 -
剑指Offer-39数组中出现次数超过一半的数字
public static int majorityElement(int[] nums) { // HashMap nums作为key 出现次数作为value HashMap<Integer, Integer> hashMap = new HashMap<>(); // res保存key int res = 0; // max保存出现最多次数的value int max = 0; for (int i = 0; i <.原创 2021-02-22 11:18:11 · 74 阅读 · 0 评论 -
剑指Offer-38字符串的排列
List<String> res = new LinkedList<>();char[] c;public String[] permutation(String s) { c = s.toCharArray(); dfs(0); return res.toArray(new String[res.size()]);}public void dfs(int x){ if(x == c.length - 1) { res.a.原创 2021-02-22 10:09:34 · 99 阅读 · 0 评论 -
剑指Offer-37序列化二叉树
public static String serialize(TreeNode root) { if (root == null){ return "[]"; } // 不涉及线程安全 StringBuilder更快 StringBuilder res = new StringBuilder("["); Queue<TreeNode> queue = new LinkedList<>(); queue.add(root.原创 2021-02-20 13:21:38 · 87 阅读 · 2 评论