剑指Offer编程整理(二)

1、数值的整数次方

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

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

4、反转链表

5、合并两个排序的链表

6、树的子结构

7、二叉树的镜像

8、顺时针打印矩阵

9、包含min函数的栈

10、栈的压入、弹出序列

11、从上往下打印二叉树


1、数值的整数次方

(1)问题描述:

给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。

(2)解题思路:

法一:直接使用Math.power()

法二:先判断指数的正负性,然后执行乘法

(3)代码实现:

法一:

public static double power(double base,int exponent){
        return Math.pow(base,exponent);
    }
法二:

public double Power(double base, int exponent) {
        if(exponent==0)
            return 1;
        double result=1.0;
        if(exponent>0){
            for(int i=1;i<=exponent;i++){
            result*=base;
        	}
        }else if(exponent<0){
            exponent=-exponent;
            for(int i=1;i<=exponent;i++){
                result/=base;
            }
        }
        return result;
  }

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

(1)问题描述:

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。

(2)解题思路:

法一:两两比较,如果遇到相邻两个数左边的是偶数,右边的是奇数,则互换位置;

法二:新建两个数组,分别存放奇数和偶数,然后在将两个数组中的数据返回,空间换时间。

(3)代码实现:

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

(1)问题描述:

输入一个链表,输出该链表中倒数第k个结点。

(2)解题思路:

法一:复制两个结点,当第一个结点从头走到第k个结点时,第二个结点从头开始走且第一个结点也继续往前走,直到第一个结点走到链表结尾时,第二个结点刚好走到倒数第k

个结点的位置;

法二:使用栈。

(3)代码实现:

法一:

public static ListNode findKthNode(ListNode head,int k){
        if (head == null || k<=0){
            return null;
        }
        ListNode pre = head;
        ListNode last = head;
        for (int i=1;i<k;i++){
            if (pre.next != null){
                pre = pre.next;
            }else {
                return null;
            }
        }

        while (pre.next != null){
            pre = pre.next;
            last = last.next;
        }

        return last;
    }
法二:

 public static ListNode findKthNode(ListNode head,int k){
        Stack<ListNode> stack = new Stack<ListNode>();
        while (head!=null){
            stack.push(head.next);
        }
        int i = 0;
        while (i<k-1){
            stack.pop();
        }

        return stack.pop();
    }

4、反转链表

(1)问题描述:

输入一个链表,反转链表后,输出链表的所有元素。

(2)解题思路:

一旦调整了指针的指向,链表就断开了,所以在调整指针指向之前,要把该指针指向的结点先保存下来

(3)代码实现:

public ListNode reverseNode(ListNode head){
        ListNode pre=null;
        ListNode last=null;
        while(head!=null)
        {
            last=head.next;
            head.next=pre;
            pre=head;
            head=last;
        }
        return pre;
    }
5、合并两个排序的链表

(1)问题描述:

输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

(2)解题思路:

每次找出最小的元素,加入到新的链表的后面

(3)代码实现:

 public ListNode Merge(ListNode list1,ListNode list2){
        if (list1 ==null){
            return list2;
        }
        if (list2 == null){
            return list1;
        }

        ListNode listNode = null;
        if (list1.val > list2.val){
            listNode = list2;
            listNode.next = Merge(list1,list2.next);
        }else {
            listNode = list1;
            listNode.next = Merge(list1.next,list2);
        }
        return listNode;
    }
6、树的子结构

(1)问题描述:

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

(2)解题思路:

先在树A种找到和树B的根节点的值一样的结点R;

再判断树A中以R为根节点的子树是否包含和树B一样的结构。

(3)代码实现:

public boolean HasSubtree(TreeNode root1,TreeNode root2) {
        if(root1==null||root2==null)
            return false;
        return IsSubtree(root1,root2)||HasSubtree(root1.left,root2)||HasSubtree(root1.right,root2);
    }
    public boolean IsSubtree(TreeNode root1,TreeNode root2){
        if(root2==null)
            return true;
        if(root1==null)
            return false;
        if(root1.val==root2.val)
            return IsSubtree(root1.left,root2.left)&&IsSubtree(root1.right,root2.right);
        else 
            return false;
    }
7、二叉树的镜像

(1)问题描述:

操作给定的二叉树,将其变换为源二叉树的镜像。

(2)解题思路:

迭代

(3)代码实现:

public void Mirror(TreeNode root) {
        TreeNode temp=null;
        if(root!=null&&(root.left!=null||root.right!=null)){
            temp=root.left;
            root.left=root.right;
            root.right=temp;
            Mirror(root.left);
            Mirror(root.right);
        }
    }
8、顺时针打印矩阵

(1)问题描述:

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.

(2)解题思路:

法一:记录四个角的位置

法二:记录两个角的位置即左上角和右下角

(3)代码实现:

法一:

public ArrayList<Integer> printMatrix(int [][] matrix) {
        int left=0,right=matrix[0].length-1,top=0,boom= matrix.length-1;//记录四个角的位置
        ArrayList<Integer> list = new ArrayList<Integer>();

        while((right>left)&&(boom>top)){
            for(int i=left;i<=right;i++){//从左到右
                list.add(matrix[top][i]);
            }
            for(int i=top+1;i<=boom;i++){//上到下
                list.add(matrix[i][right]);
            }
            for(int i = right-1;i>=left;i--){//右到左
                list.add(matrix[boom][i]);
            }
            for(int i = boom-1;i>top;i--){//下到上
                list.add(matrix[i][left]);
            }
            left++;
            right--;
            top++;
            boom--;
        }

        if((boom==top)&&(left<right)){//单独剩下一行的情况
            for(int i=left;i<=right;i++){
                list.add(matrix[top][i]);
            }
        }
        if((left==right)&&(boom>top)){//单独剩下一列的情况
            for(int i =top;i<= boom;i++){
                list.add(matrix[i][left]);
            }
        }
         if((boom==top)&&(right==left)){//单独剩下一个元素的情况
           list.add(matrix[left][boom]); 
        }
        return list;
    }
法二:

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

        ArrayList<Integer> lst = new ArrayList<Integer>();
        int i = 0, j = 0;
        int x = matrix.length - 1, y = matrix[0].length - 1;
        while (i <= x && j <= y) {
            lst = add(lst, matrix, i, j, x, y);
            i++;
            j++;
            --x;
            --y;
        }
        return lst;
    }

    public static ArrayList<Integer> add(ArrayList<Integer> lst, int[][] matrix, int i, int j, int x, int y) {
        int a, b;
        for (b = j; b <= y; b++)
            lst.add(matrix[i][b]);
        for (a = i + 1; a < x; a++)
            lst.add(matrix[a][y]);
        for (b = y; b >= j && i != x; b--)
            lst.add(matrix[x][b]);
        for (a = x - 1; a > i && j != y; a--)
            lst.add(matrix[a][j]);
        return lst;
    }

9、包含min函数的栈

(1)问题描述:

定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。

(2)解题思路:

使用两个栈,data栈存需要存储的元素,min栈存小元素;

push栈的时候,元素存进data栈,如果该元素小于上一个存入的元素,则存入min栈,否则不入min栈;

pop:如果data栈和min栈pop出的元素不等,则再将min栈pop出的元素push进去;该步是为了防止min元素被pop出;

top函数为了将min元素移动到栈顶;

min函数均是得到最小元素,得到pop后在push进去,类似与peek()函数。

(3)代码实现:

public class GetMinStack {
    Stack<Integer> stack = new Stack<Integer>();
    Stack<Integer> min = new Stack<Integer>();
    Integer temp = null;
    public void push(int node) {
        if (temp != null){
            if (node <= temp){
                temp = node;
                min.push(node);
            }
            stack.push(node);
        }else {
            temp = node;
            min.push(node);
            stack.push(node);
        }

    }

    public void pop() {
        int num = stack.pop();
        int num1 = min.pop();
        if (num != num1){
            min.push(num1);
        }
    }

    public int top() {
        int num = min.pop();
        stack.push(num);
        return num;
    }

    public int min() {
        int num = min.pop();
        min.push(num);
        return num;
    }
}
另:

import java.util.Stack;

public class Solution {

    Stack stack=new Stack();
    public void push(int node) {
        stack.push(node);
    }
    
    public void pop() {
        stack.pop();
    }
    
    public int top() {
        int top=(int)stack.pop();
        return top;
    }
    
    public int min() {
        Stack stack1=new Stack();
        int min=(int)stack.pop();
        stack1.push(min);
        while(!stack.isEmpty()){
            int temp=(int)stack.pop();
            if(min>temp){
                min=temp;
            }
            stack1.push(temp);
        }
        while(!stack1.isEmpty()){
            stack.push(stack1.pop());
        }
        return min;
    }
}
10、栈的压入、弹出序列

(1)问题描述:

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

(2)解题思路:

按顺序入栈 同时按弹出顺序出栈,若栈顶元素等于出栈的顺序元素,则出栈;

执行完后判断栈是否为空。

(3)代码实现:

public class PopOrder {
    public static boolean isPopOrder(int[] pushA,int[] popA){
       if (pushA.length == 0 || popA.length == 0) return false;
       if (pushA.length != popA.length) return false;
        Stack<Integer> stack = new Stack<>();
        for (int i=0,j=0;i<pushA.length;i++){
            stack.push(pushA[i]);
            while (j < popA.length && stack.peek()==popA[j]){
                stack.pop();
                j++;
            }
        }

        return stack.isEmpty();
    }
11、从上往下打印二叉树

(1)问题描述:

从上往下打印出二叉树的每个节点,同层节点从左至右打印。

(2)解题思路:

层序遍历

(3)代码实现:

public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
            ArrayList<Integer> intList=new ArrayList<Integer>();
			ArrayList<TreeNode> treeList=new ArrayList<TreeNode>();
			if(root==null){
				return intList;
			}
			treeList.add(root);
			for(int i=0;i<treeList.size();i++){
				TreeNode node=  treeList.get(i);
				if(node.left!=null){
					treeList.add(node.left);
				}
				if(node.right!=null){
					treeList.add(node.right);
				}
				intList.add(node.val);
			}
			return intList;
    }

用队列实现:

public ArrayList<Integer> printValFromTop2Bott(TreeNode tree){
        if (tree == null){
            return new ArrayList<Integer>();
        }

        LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
        ArrayList<Integer> list = new ArrayList<Integer>();
        queue.offer(tree);
        while (!queue.isEmpty()){
            TreeNode treeNode = queue.poll();
            list.add(treeNode.val);

            if (tree.leftTree!= null){
                queue.offer(treeNode.leftTree);
            }

            if (treeNode.rightTree != null){
                queue.offer(treeNode.rightTree);
            }
        }

        return list;

    }







1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.m或d论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 、1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值