剑指offer

03. 数组中重复的数字

  描述:

    

 

 

   思路:set存储。遇到一个看是否在。

04. 二维数组中的查找

  描述:
    

 

 

   思路:从左下(右上)开始查找。

05. 替换空格

  描述:

    

 

 

   思路:字符数组。遍历 遇到替换。

 06. 从尾到头打印链表

  描述:

    

 

 

   思路:可以用栈。也可以反转再输出。

 07. 重建二叉树

  描述:

    

 

  思路:根据根节点取中序锁定,然后切分,前一半递归返回的作为左子树,后一半右子树。递归需要用到当前根节点的下标,左边界,右边界。

09. 用两个栈实现队列

  描述:

    

 

 

   思路:两个栈,当插入一个元素就要来回倒腾一下。保证最新插入的在栈底,最老的在栈顶。

10- I. 斐波那契数列

  描述:

    

 

 

   思路:动态规划。 dp[i]=(dp[i-1]+dp[i-2])%1000000007

10- II. 青蛙跳台阶问题

  描述:

    

 

 

   思路:动态规划。

11. 旋转数组的最小数字

  描述:

    

 

 

   思路:二分。特殊情况下回退化到N.

12. 矩阵中的路径

  描述:
    

 

 

   思路:对于每个点进行深度优先递归。先判断第一个字符是否相等,然后递归帐下左右(或),遍历一个节点的时候记着修改标记,然后回溯再改回来。

13. 机器人的运动范围

  描述:

    

 

 

   思路:广度优先。先压入(0,0).然后对于每个点,都遍历周围(准确是下和右,判断)。visited.

  14- I. 剪绳子

  描述:
    

 

 

   思路:动态规划。dp[i]=max(dp[i],   max(j,dp[j])*max( dp[i-j] , (i-j) )  )

14- II. 剪绳子 II

     增加一个取余。

15. 二进制中1的个数

  描述:
    

 

 

   思路:右移 累加。

16. 数值的整数次方

  描述:

    

 

 

   思路:根据指数的正负0;全部转为正。指数为偶数,递归 /2的平方。否则递归/2的平方*x.

 17. 打印从1到最大的n位数

  描述:

    

 

 

   思路:切记不能用10^n-1去遍历。造成越界。用字符串去字符串的深度优先遍历。遍历完再对高位为0进行过滤。

18. 删除链表的节点

  描述;

    

 

 

   思路:双指针法。

19. 正则表达式匹配

  描述:

    

 

 

   思路:

    

 

 

 20. 表示数值的字符串

  描述:

    

 

 

   思路:此问题就按照判断走即可。

21. 调整数组顺序使奇数位于偶数前面

  描述:
    

 

 

   思路:双指针即可。

22. 链表中倒数第k个节点

  描述:

    

 

 

   思路:双指针。距离k.

24. 反转链表

25. 合并两个排序的链表

26. 树的子结构

  描述:

      

 

 

   思路:递归。当然是root=root&&left==ledt&&right==right。  然后对左子树的根节点和B 右子树根节点和B  的或。

27. 二叉树的镜像

  描述:

    

 

 

   思路:temp中转进行赋值。

28. 对称的二叉树

  

 

 

   思路:递归。先是root.left==right.再==方法中,对于两个点,判断左==右&&右等于左。

29. 顺时针打印矩阵

  描述:

    

 

 

   思路:模拟走的步骤即可。

30. 包含min函数的栈

  描述:

    

 

 

   思路:用两个栈。一个栈实现正常的功能,另一个栈将栈顶元素和新来的元素比对,当小于的时候,插入一个自己。否则插入这个数。保证这个栈顶最小。

31. 栈的压入、弹出序列

  描述:

    

 

 

   思路:按照pushed.压栈,压入一个判断和poped第一个是否一样,一样的话弹栈。(这个判断用一个while)。

 32 - I. 从上到下打印二叉树

  描述:

    

 

 

   思路:bfs

 32 - II. 从上到下打印二叉树 II

  描述:

    

 

 

   思路:bfs。要注意queue的每一次长度。

32 - III. 从上到下打印二叉树 III

  描述:

    

 

 

   思路: 注意方向。

33. 二叉搜索树的后序遍历序列

  描述:

    

 

 

   思路:考虑后序遍历的特点,左右中。同时左《中《右。所以遍历数组,保证小于根的个数i和大于根的个数j的和+1等于数组的长度。然后递归左子树和右子树。并集为结果。

34. 二叉树中和为某一值的路径

  描述:
    

 

 

   思路:递归。注意浅拷贝问题。需要重新创建一个。

35. 复杂链表的复制

  描述;
    

 

 

   思路:可以通过一个hashmap<node,node>先存储这些结构。然后从头开始,遇到一个改变一个。

36. 二叉搜索树与双向链表

  描述:
    

 

 

   思路:中序遍历。遍历的同时改变node的方式。记录head和tail.然后再把head,tail连起来。

37. 序列化二叉树

  描述:
    

 

 

   思路:广度优先。存储成一个字符串。通过队列。

 38. 字符串的排列

  描述:

    

 

 

   思路:全排列的问题一般都是回溯。直接全部添加到set,去重。

39. 数组中出现次数超过一半的数字

  描述:

    

 

 

   思路:排序,nums[mid]为多数元素;;;;投票法;;;

 40. 最小的k个数

  描述:

    

 

 

   思路:排序。或者统计+堆。

41. 数据流中的中位数

  描述;

     

 

 

   思路:维护一个大顶堆(存储较小的一半),小顶堆(存储较大的一半)。偶数个数字添加小顶堆,奇数添加大顶堆。当目前数字为奇数的时候,求中位数返回小顶堆的头。

42. 连续子数组的最大和、

  描述:

    

 

 

   思路:动态规划。

 43. 1~n整数中1出现的次数

  描述:

    

 

 

   思路:递归。

  

    private int dfs(int n) {
        if (n <= 0) {
            return 0;
        }

        String numStr = String.valueOf(n);
        int high = numStr.charAt(0) - '0';
        int pow = (int) Math.pow(10, numStr.length() - 1);
        int last = n - high * pow;

        if (high == 1) {
            // 最高位是1,如1234, 此时pow = 1000,那么结果由以下三部分构成:
            // (1) dfs(pow - 1)代表[0,999]中1的个数;
            // (2) dfs(last)代表234中1出现的个数;
            // (3) last+1代表固定高位1有多少种情况。
            return dfs(pow - 1) + dfs(last) + last + 1;
        } else {
            // 最高位不为1,如2234,那么结果也分成以下三部分构成:
            // (1) pow代表固定高位1,有多少种情况;
            // (2) high * dfs(pow - 1)代表999以内和1999以内低三位1出现的个数;
            // (3) dfs(last)同上。
            return pow + high * dfs(pow - 1) + dfs(last);
        }
    }

    // 递归求解
    public int countDigitOne(int n) {
        return dfs(n);
    }
View Code

 

44. 数字序列中某一位的数字

 描述:

    

 

 

   思路:找规律。确定范围。

45. 把数组排成最小的数

  描述:
    

 

 

   思路:每个数字转换为字符串,自定义排序。Arrays.sort(strs, (x, y) -> (x + y).compareTo(y + x));

46. 把数字翻译成字符串

  描述:

    

 

 

   思路:动态规划。

    if (num % 100 < 26 && num % 100 > 9) {
            return f(num / 10) + f(num / 100);
        } else {
            return f(num / 10);
        }

47. 礼物的最大价值  

  描述:
    

 

 

   思路:动态规划。

48. 最长不含重复字符的子字符串

  描述:

    

  思路:双指针+hashmap。

49. 丑数

  描述:

    

 

 

   思路:动态规划。状态转移是求每次三个指针相乘的最小值。然后决定哪个指针移动。

50. 第一个只出现一次的字符

  描述:

    

 

 

   思路:先统计。然后再次遍历找。

51. 数组中的逆序对

  描述:

    

 

 

   思路:归并排序。(放弃。。。)

52. 两个链表的第一个公共节点

  描述:

    

 

   思路:A指针遍历完遍历B。B指针遍历A,....

53 - I. 在排序数组中查找数字 I

  描述:
    

 

   思路:hasmap.

53 - II. 0~n-1中缺失的数字

  描述:
    

 

   思路:本来的和-现有的和。

 54. 二叉搜索树的第k大节点

  描述:

    

 

   思路:中序遍历。底k个。

55 - I. 二叉树的深度

  描述;

    

 

   递归。

55 - II. 平衡二叉树

  描述;
      

 

   思路;递归。

56 - I. 数组中数字出现的次数

  

 

   思路:全体异或。找到1的部位。然后按照这个部位不同进行划分为两个集合。每个集合异或。

56 - II. 数组中数字出现的次数 II

  描述:
    

 

   思路:对每个数字的 每个位 累加。  然后堆每个位对3取余。取余后的拼接为这个数字的二进制。

57. 和为s的两个数字

  描述:
    

 

   思路:双指针。

57 - II. 和为s的连续正数序列

  描述:

    

 

   思路:滑动窗口。当窗口内和小于target.右指针往右移。否则左指针右移。相等记录。

58 - I. 翻转单词顺序

  描述:

    

 

   思路:先trim.然后从后往前,找第一个空格,然后双指针之间的。

58 - II. 左旋转字符串

  描述:

    

 

   思路:substring.

59 - I. 滑动窗口的最大值

  描述:

    

 

   思路:窗口滑动即可。

59 - II. 队列的最大值

  描述:

    

 

   思路:两个队列,一个队列实现基本的操作。另一个维护最大值。当来一个值,判断这个值和队尾,队尾小于这个,弹出队尾,直到不小于。然后弹出元素的时候,看弹出这个是不是当前的最大值。是的话最大值也一起弹出。

60. n个骰子的点数

  描述:

    

 

   思路:动态规划。

    

 

 61. 扑克牌中的顺子

  描述:
    

 

   思路:看最大值-最小值是否《5,小于就可以构成。同时还要判断重复元素,0不算。

62. 圆圈中最后剩下的数字

  描述;
    

 

   思路:循环按照逻辑来。

63. 股票的最大利润 

  描述:

    

 

   思路:单调栈。

64. 求1+2+…+n

  描述:
    

 

   思路:n(n+1)/2

65. 不用加减乘除做加法

  描述:

    

 

   思路:位运算。

66. 构建乘积数组

  描述:
    

 

   思路:左右数组。

 67. 把字符串转换成整数

  描述:
    

 

   思路:只需要按部就班即可。

  

 

 

 

  

    

 

posted @ 2020-07-16 21:06  _Meditation  阅读(161)  评论(0编辑  收藏  举报