【Java版本】剑指offer所有面试题(完整版题解3)

33 篇文章 1 订阅
29 篇文章 3 订阅
本文介绍了多种链表操作,包括调整数组顺序使奇数位于偶数前面,链表中倒数第k个节点的查找,检测链表环的入口节点,链表的反转以及合并两个已排序链表。同时,还涵盖了矩阵的顺时针打印和一个支持min功能的栈实现。
摘要由CSDN通过智能技术生成

第二十一题-调整数组顺序使奇数位于偶数

image-20220413083641931

public class Test14 {
    public static void reorderOddEven(int[] arr){
        if(arr == null || arr.length < 2) return;
        int start = 0;
        int end = arr.length-1;
        while(start < end){
            while(start <end && arr[start] % 2 !=0)
                start ++;
            while(start < end && arr[end] %2==0)
                end --;
            int temp = arr[start];
            arr[start] = arr[end];
            arr[end] = temp;
        }
    }
    public static void  printArray(int[] arr){
        if (arr == null || arr.length == 0) return;
        for(int i : arr){
            System.out.print(i + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        int[] array = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        reorderOddEven(array);
        printArray(array);
    }
}

第二十二题-链表中倒数第k个节点

image-20220413085431626

public class Test15 {
    public static ListNode findKthToTail(ListNode head,int k){

        if(k < 1 || head==null) return null;
        ListNode node1 = head;
        ListNode node2 = head;
        for(int i = 0;i<k-1;i++){
            if(node1 != null)
                node1 = node1.next;
            else return null;
        }
        while(node1.next != null){
            node1 = node1.next;//找到最后一个节点的位置
            node2 = node2.next;
        }
        return node2;
    }

    public static void main(String[] args) {


        ListNode head = new ListNode();
        head.val = 1;

        head.next = new ListNode();
        head.next.val = 2;

        head.next.next = new ListNode();
        head.next.next.val = 3;

        head.next.next.next = new ListNode();
        head.next.next.next.val = 4;

        ListNode middle = head.next.next.next.next = new ListNode();
        head.next.next.next.next.val = 5;

        head.next.next.next.next.next = new ListNode();
        head.next.next.next.next.next.val = 6;

        ListNode last = head.next.next.next.next.next.next = new ListNode();
        head.next.next.next.next.next.next.val = 7;

        System.out.println(findKthToTail(head, 7).val);
        System.out.println(findKthToTail(head, 3).val);

    }
}

第二十三题-链表中环的入口节点

image-20220423091500122

·

import java.util.List;

public class Test24_1 {
    public static ListNode meetingNode(ListNode head){
        ListNode fast = head;
        ListNode slow = head;

        while(fast != null && slow != null){
            fast = fast.next.next;
            slow = slow.next;
            if (fast == slow) break;
        }
        if (fast == null || fast.next == null) return null; //没有环

        fast = head;
        while (fast != slow){
            fast = fast.next;
            slow = slow.next;
        }
        return fast;
    }

    public static void main(String[] args) {
        // 1->2->3->4->5->6
        //       ^        |
        //       |        |
        //       +--------+
        ListNode n1 = new ListNode(1);
        ListNode n2 = new ListNode(2);
        ListNode n3 = new ListNode(3);
        ListNode n4 = new ListNode(4);
        ListNode n5 = new ListNode(5);
        ListNode n6 = new ListNode(6);

        n1.next = n2;
        n2.next = n3;
        n3.next = n4;
        n4.next = n5;
        n5.next = n6;
        n6.next = n3;

        System.out.println(meetingNode(n1).val);
    }
}

第二十四题-反转链表

image-20220413090648636

public class Test16 {
    public static ListNode reverse(ListNode cur){
        ListNode pre = null;
        while (cur != null){
            ListNode next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }

    public static void printList(ListNode head){
        ListNode temp = head;
        while (temp != null){
            System.out.println(temp.val);
            temp = temp.next;
        }
    }
    public static void main(String[] args) {


        ListNode head = new ListNode();
        head.val = 1;

        head.next = new ListNode();
        head.next.val = 2;

        head.next.next = new ListNode();
        head.next.next.val = 3;

        head.next.next.next = new ListNode();
        head.next.next.next.val = 4;

        ListNode middle = head.next.next.next.next = new ListNode();
        head.next.next.next.next.val = 5;

        head.next.next.next.next.next = new ListNode();
        head.next.next.next.next.next.val = 6;

        ListNode last = head.next.next.next.next.next.next = new ListNode();
        head.next.next.next.next.next.next.val = 7;
        ListNode reverse = reverse(head);
        printList(reverse);

    }
}

第二十五题-合并两个链表

image-20220413093345469

public class Test17 {
    public static ListNode merge(ListNode head1,ListNode head2){
        if(head1 == null) return head2;
        if(head2 == null) return head1;
        ListNode root = new ListNode();
        ListNode temp = root;
        while(head1 != null && head2 != null){
            if(head1.val < head2.val) {
                temp.next = head1;
                head1 = head1.next;

            }else{
                temp.next = head2;
                head2 = head2.next;
            }
            temp = temp.next;
        }
        if(head1 != null) temp.next = head1;
        if(head2 != null) temp.next = head2;

        return root.next;
    }

    public static ListNode merge2(ListNode head1,ListNode head2){
        if(head1 == null) return head2;
        if(head2 == null) return head1;
        if(head1.val < head2.val) {
            head1.next = merge2(head1.next,head2);
            return head1;
        }
        else {
            head2.next = merge2(head1,head2.next);
            return head2;
        }

    }


    public static void printList(ListNode head){
        ListNode temp = head;
        while (temp != null){
            System.out.print(temp.val);
            temp = temp.next;
        }
        System.out.println();
    }

    public static void main(String[] args) {
        ListNode head = new ListNode();
        head.val = 1;

        head.next = new ListNode();
        head.next.val = 3;

        head.next.next = new ListNode();
        head.next.next.val = 5;

        head.next.next.next = new ListNode();
        head.next.next.next.val = 6;

        ListNode middle = head.next.next.next.next = new ListNode();
        head.next.next.next.next.val = 7;

        ListNode head2 = new ListNode();
        head2.val = 2;

        head2.next = new ListNode();
        head2.next.val = 4;

        head2.next.next = new ListNode();
        head2.next.next.val = 8;

        head2.next.next.next = new ListNode();
        head2.next.next.next.val = 9;

        ListNode middle2 = head.next.next.next.next = new ListNode();
        head.next.next.next.next.val = 10;

        //ListNode merge = merge(head, head2);
        ListNode merge2 = merge2(head,head2);
        //printList(merge);
        printList(merge2);

    }
}

第二十六题-树的结构

image-20220413101656182

public class Test18 {
    public static boolean hasSubtree(TreeNode root1,TreeNode root2){
        if(root1 == root2) return true; 
        if(root2 == null) return true;
        if(root1 == null) return false;
        boolean res = false;
        // 如果结点的值相等就,调用匹配方法
        if(root1.val == root2.val) res = mach(root1,root2);
        if(res) return true; //如果匹配成功 返回
        return hasSubtree(root1.left,root2) || hasSubtree(root1.right,root2); //匹配失败。找下一个相等的节点继续匹配
    }
    public static boolean mach(TreeNode root1,TreeNode root2){
        if(root1 == root2) return true;
        if(root2 == null) return true;
        if(root1 == null) return false;
		//匹配根节点下的所有左右子树
        if(root1.val == root2.val) return mach(root1.left,root2.left) && mach(root1.right,root2.right);

        return false;
    }

    public static void main(String[] args) {
        TreeNode root1 = new TreeNode();
        root1.val = 8;
        root1.right = new TreeNode();
        root1.right.val = 7;
        root1.left = new TreeNode();
        root1.left.val = 8;
        root1.left.left = new TreeNode();
        root1.left.left.val = 9;
        root1.left.right = new TreeNode();
        root1.left.right.val = 2;
        root1.left.right.left = new TreeNode();
        root1.left.right.left.left = new TreeNode();
        root1.left.right.left.left.val = 3;
        root1.left.right.left.right = new TreeNode();
        root1.left.right.left.right.val = 8;

        TreeNode root2 = new TreeNode();
        root2.val = 8;
        root2.left = new TreeNode();
        root2.left.val = 9;
        root2.right = new TreeNode();
        root2.right.val = 2;

        System.out.println(hasSubtree(root1, root2));
        System.out.println(hasSubtree(root2, root1));
        System.out.println(hasSubtree(root1, root1.left));
        System.out.println(hasSubtree(root1, null));

    }
}

第二十七题-二叉树的镜像

image-20220413103550194

public class Test19 {
    public static TreeNode mirror(TreeNode node){
        if(node == null) return null;
        mirror(node.left);
        mirror(node.right);
        swap(node);
        return node;

    }
    public static  void swap(TreeNode node){
        TreeNode temp = node.left;
        node.left = node.right;
        node.right = temp;
    }

    public static void printTreeNode(TreeNode node){
        if (node != null) {
            System.out.print(node.val + " ");
            printTreeNode(node.left);
            printTreeNode(node.right);
        }
    }

    public static void main(String[] args) {
        TreeNode root = new TreeNode();
        root.val = 1;
        root.left = new TreeNode();
        root.left.val = 2;
        root.right = new TreeNode();
        root.right.val = 3;
        root.left.left = new TreeNode();
        root.left.left.val = 4;
        root.left.right = new TreeNode();
        root.left.right.val = 5;
        root.right.left = new TreeNode();
        root.right.left.val = 6;
        root.right.right = new TreeNode();
        root.right.right.val = 7;
        printTreeNode(root);
        System.out.println();
        TreeNode mirror = mirror(root);
        printTreeNode(mirror);

    }
}

第二十八题-对称二叉树

public class Test28_1 {
    public static boolean  isSymmetrical(TreeNode root){
        return isSymmetrical(root,root);
    }

    public static boolean isSymmetrical(TreeNode left,TreeNode right){
        if (left == null && right == null) {
            return true;
        }

        if (left == null || right == null) {
            return false;
        }
        if (left.val != right.val ) {
            return false;
        }

        return isSymmetrical(left.left, right.right) && isSymmetrical(left.right, right.left);
    }

    public static void main(String[] args) {
        TreeNode root = new TreeNode();
        root.val = 1;
        root.left = new TreeNode();
        root.left.val = 2;
        root.right = new TreeNode();
        root.right.val = 3;
        root.left.left = new TreeNode();
        root.left.left.val = 4;
        root.left.right = new TreeNode();
        root.left.right.val = 5;
        root.right.left = new TreeNode();
        root.right.left.val = 6;
        root.right.right = new TreeNode();
        root.right.right.val = 7;

        System.out.println(isSymmetrical(root));
    }
}

第二十九题-顺时针打印矩阵

image-20220413110933936

image-20220413111007304

public class Test20 {
    public static void printMatrixClockWisely(int[][] numbers){
        if (numbers == null) return;
        int x = 0;
        int y = 0;
        //最后一圈起始的行号列号
        //(number-1)/2
        //一共(number-1)/2
        while(x*2 < numbers.length && y*2<numbers.length){
            printMatrixCircle(numbers,x,y);
            x++;
            y++;
        }
    }
    public static void printMatrixCircle(int[][] numbers,int x,int y){
        //数组行数
        int row = numbers.length;
        //数组列数
        int col = numbers.length;
        int i= x;
        int j = y;
        //输出上面的一行
        for(;j<col-y;j++) System.out.print(numbers[i][j]+" ");
        if (row-x-1>x){
            //输出右边的一行
            for(i = x+1;i<row-x;i++) System.out.print(numbers[i][j-1]+ " ");
        }
        if (col-y-1 >y && row-x-1>x){
            //输出下面的一行
            for(j=col-y-2;j>=y;j--) System.out.print(numbers[i-1][j] + " ");
        }
        if (row-x-2>x & col-y-1 >y){
            //输出左边一行
            for (i=row-x-2;i>x;i--) System.out.print(numbers[i][j+1] + " ");
        }
    }

    public static void main(String[] args) {
        int[][] numbers = {
                {1, 2, 3, 4, 5},
                {16, 17, 18, 19, 6},
                {15, 24, 25, 20, 7},
                {14, 23, 22, 21, 8},
                {13, 12, 11, 10, 9},
        };
        printMatrixClockWisely(numbers);
        System.out.println();
    }
}

第三十题-包含min函数的栈

image-20220414090623640

import java.util.Stack;

public class Test21 {
    public static class StackWithMin<T extends Comparable<T>>{
        private Stack<T> dataStack;
        private Stack<T> minStack;

        public StackWithMin() {
            dataStack = new Stack<>();
            minStack = new Stack<>();
        }

        public T pop(){
            if (dataStack.isEmpty()){
                throw new RuntimeException("IS Empty");
            }
            // 如果有数据,最小数位置栈和数据栈必定是有相同的元素个数,
            // 两个栈同时出栈
            minStack.pop();
            return dataStack.pop();
        }

        public void push(T t){
            if (t == null) throw new RuntimeException("can not be null");
            if(dataStack.isEmpty()){
                dataStack.push(t);
                minStack.push(t);
            }else{
                dataStack.push(t);
                T temp = minStack.peek();
                if(temp.compareTo(t) > 0){
                    minStack.push(t);
                    // 插入的元素不比原来的最小元素小,复制最小栈栈顶元素,将其入栈
                }else minStack.push(minStack.peek());
            }
        }

        public T min(){
            if (minStack.isEmpty()) throw new RuntimeException("No element in stack.");
            return minStack.peek();
        }
    }
    public static void main(String[] args) {
        StackWithMin<Integer> stack = new StackWithMin<>();
        stack.push(3);
        System.out.println(stack.min());
        stack.push(4);
        System.out.println(stack.min());
        stack.push(2);
        System.out.println(stack.min());
        stack.push(3);
        System.out.println(stack.min());
        stack.pop();
        System.out.println(stack.min());
        stack.pop();
        System.out.println(stack.min());
        stack.push(0);
        System.out.println(stack.min());
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小七rrrrr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值