剑指Offer代码总结

本文总结了《剑指Offer》中的多个经典编程题目,包括二维数组查找整数、字符串替换空格、从尾到头打印链表、重建二叉树、用两个栈实现队列、斐波那契数列、调整数组顺序、链表操作(如找到倒数第k个节点、反转链表、合并两个有序链表)以及二叉树相关问题(如子结构、镜像、中序遍历)。此外,还涉及到了栈的最小元素、数组旋转、链表环检测、删除重复节点、二叉树的下一个节点、对称二叉树、之字形打印、序列化与反序列化、二叉搜索树的第k个节点、数据流中中位数、滑动窗口最大值、矩阵路径、机器人运动范围和剪绳子等算法问题,提供了详细的代码实现。
摘要由CSDN通过智能技术生成

剑指Offer总结:

1、二维数组查找某个整数。

public class Solution {

    public boolean Find(int target, int [][] array) {

        for(int i=0;i<array.length;i++){

            for(int j=0;j<array[i].length;j++){

                if(array[i][j]==target){

                    return true;

                }

            }

        }

        return false;

    }

}

2、请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

import java.lang.StringBuffer;

import java.lang.String;

public class Solution {

    public String replaceSpace(StringBuffer str) {

        StringBuffer sb = new StringBuffer();

        int n=str.length();

        for(int i=0;i<n;i++){

            if(str.charAt(i)==' '){

                sb.append("%20");

            }else{

                sb.append(str.charAt(i));

            }

        }

        String s = sb.toString();

        return s;

    }

}

3、从尾到头打印链表

方法1:

public class Solution {

    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {

        ArrayList<Integer> list = new ArrayList<>();

        ListNode node = listNode;

        while(node!=null){

            list.add(0,node.val); //此方法每次将链表结点插入到ArrayList的0位置处

            node = node.next;

        }

        return list;

    }

}

方法2:

public class Solution {

    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {

        ArrayList<Integer> list = new ArrayList();

        Stack<Integer> s = new Stack();

        if(listNode==null){

            return list;

        }

        while(listNode!=null){

            s.push(listNode.val);

            if(listNode.next==null){

                break;

            }else{

                listNode=listNode.next;

            }

        }

        while(s.size()!=0){

            int x = s.pop();

            list.add(x);

        }

        return list;

    }

}

4、重建二叉树:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

//树,用递归

//前序[1][2,4,7][3,5,6,8] 根左右 left1、right1表示前序遍历的下标

//中序[4,7,2][1][5,3,8,6] 左根右 left2、right2表示中序遍历的下标

import java.util.Arrays;

public class Solution {

    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {

        if (pre.length == 0 || in.length == 0) {

            return null;

        }

        TreeNode root = new TreeNode(pre[0]);

        for (int i = 0; i < in.length; i++) {      // 在中序遍历中找到前序的根

            if (in[i] == pre[0]) {

                // 左子树,注意 copyOfRange 函数,左闭右开

                root.left = reConstructBinaryTree(Arrays.copyOfRange(pre, 1, i + 1), Arrays.copyOfRange(in, 0, i));

                // 右子树,注意 copyOfRange 函数,左闭右开

                root.right = reConstructBinaryTree(Arrays.copyOfRange(pre, i + 1, pre.length), Arrays.copyOfRange(in, i + 1, in.length));

                break;

            }

        }

        return root;

    }

}

5、用两个栈实现一个队列

public class Solution {

    Stack<Integer> stack1 = new Stack<Integer>();

    Stack<Integer> stack2 = new Stack<Integer>();

   

    public void push(int node) {

        stack1.push(node);

    }

   

    public int pop() {

        if(stack2.size()==0){

            while(stack1.size()!=0){

                stack2.push(stack1.pop());

            }

        }

        return stack2.pop();

    }

}

6、把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。

//二分法

public class Solution {

    public int minNumberInRotateArray(int [] array) {

        if(array.length==0) return 0;

        int low=0;

        int high=array.length-1;

        int mid;

        while(low<high){

            if(array[low]<array[high])

                return array[low];

            mid=(low+high)/2;

            if(array[mid]>array[low])

                low=mid+1;

            else if(array[mid]<array[high])

                high=mid;

            else

                low++;

        }

        return array[low];

    }

}

7、斐波那契数列

public class Solution {

    public int Fibonacci(int n) {

        if(n==0) return 0;

        if(n==1) return 1;

        return Fibonacci(n-1)+Fibonacci(n-2);

    }

}

8、跳台阶

public class Solution {

    public int JumpFloor(int target) {

        if(target==0) return 1;

        if(target==1) return 1;

        return JumpFloor(target-1)+JumpFloor(target-2);

    }

}

9、变态跳台阶

//f(n)=f(n-1)+f(n-2)+...+f(1)

//f(n-1)=f(n-2)+f(n-3)+...+f(1)

//两式相加,f(n)=2^n-1,利用左移乘2

//口诀:左移乘2,右移除2

public class Solution {

    public int JumpFloorII(int target) {

        return 1<<(target-1);

    }

}

10、矩阵覆盖(斐波那契数列)

public class Solution {

    public int RectCover(int target) {

        if (target==0) return 0;

        if(target<2) return 1;

        int[] a = new int[target];

        a[0]=1;

        a[1]=2;

        for(int i=2;i<target;i++){

            a[i]=a[i-1]+a[i-2];

        }

        return a[target-1];

    }

}

11、二进制中1的个数

public class Solution {

    public int NumberOf1(int n) {

        int count=0;

        while(n!=0){

            count++;

            n=n&(n-1);

        }

        return count;

    }

}

12、数值的整数次方

public class Solution {

    public double Power(double base, int exponent) {

        if(base==0&&exponent==0) return 0;

        if(exponent<0){

            base=1/base;

            exponent=-exponent;

        }    

        double sum=1;

        for(int i=0;i<exponent;i++){

            sum=sum*base;

        }

        return sum;

  }

}

13、调整数组顺序使奇数位于偶数前面

方法1:

public class Solution {

    public void reOrderArray(int [] array) {

        int[] a = new int[array.length];

        int count=0;

        for(int i=0;i<array.length;i++){

            if(array[i]%2!=0){

                a[count]=array[i];

                count++;

            }

        }

        for(int i=0;i<array.length;i++){

            if(array[i]%2==0){

                a[count]=array[i];

                count++;

            }

        }

        for(int i=0;i<a.length;i++){

            array[i]=a[i];

        }

    }

}

方法2:

public class Solution {

    public void reOrderArray(int [] array) {

        int i=0,j;

        while(i<array.length){

            while(i<array.length&&array[i]%2!=0){

                i++;

            }

            j=i+1;

            while(j<array.length&&array[j]%2==0){

                j++;

            }

            if(j<array.length){

                int temp=array[j];

                for(int k = j - 1; k >= i; k--){

                    array[k + 1] = array[k];

                }

                array[i++] = temp;

            }else{

                break;

            }

        }

    }

}

 

14、链表中倒数第k个结点

public class Solution {

    public ListNode FindKthToTail(ListNode head,int k) {

        if(head==null || k==0) return null;

        ListNode left=head,right=head;

        for(int i=0; i<k; i++){

            if(right==null) return null;    //这里要加上判断,否则出现空指针异常

            right=right.next;

        }

        while(right!=null){

            left=left.next;

            right=right.next;

        }

        return left;

    }

}

15、反转链表

import java.util.Stack;

public class Solution {

    public ListNode ReverseList(ListNode head) {

        ListNode dynmy = null;

        ListNode current=head;

        ListNode last= null;

        while(current!=null){

            last=current.next;

            current.next=dynmy;

            dynmy=current;

            current=last; 

        }

        return dynmy;

    }

}

16、合并两个有序链表

public class Solution {

    public ListNode Merge(ListNode list1,ListNode list2) {

        ListNode head= new ListNode(0);

        ListNode current=head;

        while(list1!=null && list2!=null){

            if(list1.val<=list2.val){

                current.next=list1;

                list1=list1.next;

            }else{

                current.next=list2;

                list2=list2.next;

            }

            current=current.next;

        }

        if(list1!=null){

            current.next=list1;

        }

        if(list2!=null){

            current.next=list2;

        }

        return head.next;

    }

}

17、树的子结构

public class Solution {

    public boolean HasSubtree(TreeNode A,TreeNode B) {

        //树的问题,肯定递归解决

        //三种情况,A根是B根,A左子树是B,A右子树是B

        if (A==null || B==null){

            return false;

        }

        return issubtree(A,B) || HasSubtree(A.left,B) || HasSubtree(A.right,B);

    }

    public boolean issubtree(TreeNode A,TreeNode B){

        //何时为ture或false

        if(B==null) return true;

        if(A==null || A.val!=B.val) return false;

        return issubtree(A.left,B.left)&&issubtree(A.right,B.right);

    }

}

18、二叉树镜像

public class Solution {

    public void Mirror(TreeNode root) {

        if(root==null) return;

        if(root.left!=null || root.right!=null){

            TreeNode temp;

            temp=root.left;

            root.left=root.right;

            root.right=temp;

        }

        if(root.left!=null) Mirror(root.left);

        if(root.right!=null) Mirror(root.right);

    }

}

19、顺时针打印数组

public class Solution {

    public ArrayList<Integer> printMatrix(int [][] matrix) {

        ArrayList<Integer> list = new ArrayList<Integer>();

        if(matrix == null) return list;

        int up = 0;

        int down = matrix.length-1;

        int left = 0;

        int right = matrix[0].length-1;

        while(true){

            for(int i=left;i<=right;i++) //先输出最上面一行,然后up++一次

                list.add(matrix[up][i]);

            if(++up > down) break;       //向右遍历完向下遍历,需判断下边界是否越界

            for(int i=up;i<=down;i++)

                list.add(matrix[i][

Offer》 1. 赋值运算函数 2. 单例设计模式 3. 二维数组中查找目标值 4. 替换字符串中的空格 5. 从尾到头打印链表 6. 由前序和中序遍历重建二叉树 7. 用两个栈实现队列 8. 求旋转数组的最小数字 9. 斐波那契数列的第n项(青蛙跳台阶) 10. 二进制中1的个数 11. 数值的整数次方 12. 打印1到最大的n位数 13. O(1)时间删除链表节点 14. 使数组中的奇数位于偶数前面 15. 找链表中倒数第K个节点 16. 输出反转后的链表 17. 合并两个有序链表 18. 判断二叉树A中是否包含子树B 19. 二叉树的镜像 20. 顺时针打印矩阵 21. 包含min函数的栈 22. 判断一个栈是否是另一个栈的弹出序列 23. 层序遍历二叉树 24. 后序遍历二叉搜索树 25. 二叉树中和为某值的路径 26. 复杂链表的复制 27. 二叉搜索树转换为双向链表 28. 打印字符串中所有字符的排列 29. 数组中出现次数超过一半的数字 30. 找出最小的K个数 31. 连续子数组的最大和 32. 从1到整数n中1出现的次数 33. 把数组中的数排成一个最小的数 34. 求第N个丑数 35. 第一个出现一次的字符 36. 数组中逆序对的个数 37. 两个链表的第一个公共节点 38. 数字在排序数组中出现的次数 39. 二叉树的深度 40. 数组中只出现一次的两个数,而其他数都出现两次 41. 和为s的连续整数序列 42. 翻转字符串 43. n个骰子的点数及出现的概率 44. 扑克牌的顺子 45. 圆圈中最后剩下的数 46. 1+2+3+...+n的和 47. 不用加减乘除做加法 48. 不能被继承的类 49. 字符串转换为整数 50. 树中两个节点的最低公共祖先 51. 找出重复的数 52. 构建乘积数组 53. 正则表达式匹配 54. 表示数值的字符串 55. 字符流中第一个不重复的字符 56. 链表中环的入口节点 57. 删除链表中重复的节点 58. 二叉树的下一个节点 59. 对称的二叉树 60. 按之字形顺序打印二叉树 61. 把二叉树打印成多行 62. 序列化二叉树 63. 二叉搜索树的第K个节点 64. 数据流中的中位数 65. 滑动窗口的最大值 66. 矩阵中的路径 67. 机器人的运动范围
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值