剑指offer

一刷 剑指offer 记录

目录

时间:2024/6/12

类型: 数据结构-链表

JZ6 从尾到头打印链表

进度: 1/72

JZ24 反转链表

进度: 2/72

JZ25 合并两个排序的链

进度: 3/72

时间:2024/6/13

类型:数据结构-链表

JZ52 两个链表的第一个公共结点

进度: 4/72

JZ23 链表中环的入口结

进度: 5/72

JZ22 链表中倒数最后k个结点

进度: 6/72

时间:2024/6/14

类型:数据结构-链表

JZ35 复杂链表的复制

进度: 7/72

JZ76 删除链表中重复的结点

进度: 8/72

JZ18 删除链表的节点

进度: 9/7

时间:2024/6/15

类型:数据结构-二叉树

JZ55 二叉树的深度

进度: 10/72

JZ54 二叉搜索树的第k个节点

进度: 11/72

JZ7 重建二叉树

进度: 12/72

时间:2024/6/16

类型:数据结构-二叉树

JZ26 树的子结构

进度: 13/72

JZ27 二叉树的镜像

进度: 14/72

JZ32 从上往下打印二叉树

进度: 15/72

时间:2024/6/17

类型:数据结构-二叉树

JZ33 二叉搜索树的后序遍历序列

进度: 16/72

JZ36 二叉搜索树与双向链表

进度: 17/72

JZ79 判断是不是平衡二叉树

进度: 18/72

时间:2024/6/18

类型:数据结构-二叉树

JZ8 二叉树的下一个结点

进度: 19/72

JZ78 把二叉树打印成多行

进度: 20/72

JZ37 序列化二叉树

进度: 21/72

时间:2024/6/19

类型:数据结构-二叉树

JZ84 二叉树中和为某一值的路径(三)

进度: 22/72

JZ86 在二叉树中找到两个节点的最近公共祖先

进度: 23/72

JZ68 二叉搜索树的最近公共祖先

进度: 24/72

时间:2024/6/20

类型:数据结构-栈&队列

JZ9 用两个栈实现队列

进度: 25/72

JZ30 包含min函数的栈

JZ31 栈的压入、弹出序列

进度: 27/72

JZ73 翻转单词序列

进度: 28/72

JZ59 滑动窗口的最大值

进度: 29/72

时间:2024/6/21

类型:算法-搜索算法

JZ53 数字在升序数组中出现的次数

进度: 30/72

JZ11旋转数组的最小数

进度: 31/72

JZ38 字符串的排列

进度: 32/72

JZ38 字符串的排列

进度: 33/72

时间:2024/6/22

类型:算法-动态规划

JZ85 连续子数组的最大和(二)

进度: 34/72

JZ69 跳台阶

进度: 35/72

JZ10 斐波那契数列

进度: 36/72

JZ71 跳台阶扩展问题

进度: 37/72

时间:2024/6/24

类型:算法-动态规划

JZ70 矩形覆盖

进度: 38/72

JZ47 礼物的最大价值

进度: 39/72

JZ48 最长不含重复字符的子字符串

进度: 40/72

JZ46 把数字翻译成字符串

进度: 41/72

时间:2024/6/24

类型:算法-回溯

JZ12 矩阵中的路径

进度 42/72

JZ13 机器人的运动范围

进度: 43/72

时间:2024/6/25

类型:算法-排序

JZ3 数组中重复的数字

进度: 44/72

JZ51 数组中的逆序对

进度: 45/72

JZ40 最小的K个数

进度: 46/72

JZ41 数据流中的中位数

进度: 47/72

时间:2024/6/26

类型:算法-位运算

JZ65不用加减乘除做加法

进度: 48/72

JZ15 二进制中1的个数

进度: 49/72

JZ16 数值的整数次方

进度: 50/72

JZ56 数组中只出现一次的两个数字

进度: 51/72

JZ64 求1+2+3+...+n

进度: 52/72

时间:2024/6/27

类型:算法-模拟

JZ29 顺时针打印矩阵

进度: 53/72

JZ61 扑克牌顺子

进度: 54/72

JZ20 表示数值的字符串

进度: 55/72

时间:2024/6/29

类型:算法-其他算法

JZ66 构建乘积数组

进度: 56/72

JZ50 第一个只出现一次的字符

进度: 57/72

JZ5 替换空格

进度: 58/72

时间:2024/6/29

类型:算法-其他算法

JZ21 调整数组顺序使奇数位于偶数前面(一)

进度: 59/72

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

进度: 60/72

JZ43 整数中1出现的次数(从1到n整数中1出现的次数)

进度: 61/72

时间:2024/6/30

类型:算法-其他算法

JZ45 把数组排成最小的数

进度: 62/72

JZ49 丑数

进度: 63/72

JZ74 和为S的连续正数序列

进度: 64/72

时间:2024/7/1

类型:算法-其他算法

JZ57 和为S的两个数字

进度: 65/72

JZ58 左旋转字符串

进度: 66/72

JZ62 孩子们的游戏(圆圈中最后剩下的数)

进度: 67/72

JZ75 字符流中第一个不重复的字符

进度: 68/72

JZ14 剪绳子

进度: 69/72

JZ81 调整数组顺序使奇数位于偶数前面(二)

进度: 70/72

JZ83 剪绳子(进阶版)

进度: 71/72

JZ17 打印从1到最大的n位数

进度: 72/72


时间:2024/6/12

类型: 数据结构-链表

JZ6 从尾到头打印链表
描述:

输入一个链表的头节点,按链表从尾到头的顺序返回每个节点的值(用数组返回)。

如输入{1,2,3}的链表如下图:

示例图像
返回一个数组为[3,2,1]

0 <= 链表长度 <= 10000

代码:
方法一:递归

import java.util.*;
/**
*    public class ListNode {
*        int val;
*        ListNode next = null;
*
*        ListNode(int val) {
*            this.val = val;
*        }
*    }
*
*/
import java.util.ArrayList;
public class Solution {
     ArrayList<Integer> list=new ArrayList<>();
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        recursion(listNode);
        return list;
    }

    public void recursion(ListNode listNode){
        if(listNode==null){
            return ;
        }else{
            recursion(listNode.next);
            list.add(listNode.val);
        }
    }
}

方法二:栈

import java.util.*;
/**
*    public class ListNode {
*        int val;
*        ListNode next = null;
*
*        ListNode(int val) {
*            this.val = val;
*        }
*    }
*
*/
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ArrayList<Integer> list=new ArrayList<>();
        Stack<Integer> stack =new Stack<>();
        while(listNode!=null){
            stack.push(listNode.val);
            listNode=listNode.next;
        }
        while(!stack.isEmpty()){
            list.add(stack.pop());
        }
        return list;
    }
}
进度: 1/72
JZ24 反转链表
描述:

给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。

数据范围:
0≤𝑛≤1000
0≤n≤1000
要求:空间复杂度 𝑂(1) ,时间复杂度 𝑂(𝑛)。

如当输入链表{1,2,3}时,
经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。
以上转换过程如下图所示:

示例图像

代码:

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param head ListNode类
     * @return ListNode类
     */
    public ListNode ReverseList (ListNode head) {
        // write code here

        ListNode pre=null;
        ListNode cur=head;
        ListNode temp=null;

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

        return pre;
    }
}
进度: 2/72
JZ25 合并两个排序的链
描述:

输入两个递增的链表,单个链表的长度为,合并这两个链表并使新链表中的节点仍然是递增排序的。
数据范围:0≤m≤1000,-1000≤节点值≤1000
要求:空间复杂度O(1),时间复杂度O(n)
如输入{1,3,5},{2,4,6}时,合并后的链表为{1,2,3,4,5,6},所以对应的输出为{1,2,3,4,5,6},转换过程如下
图所示:

示例图像

代码:

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param pHead1 ListNode类
     * @param pHead2 ListNode类
     * @return ListNode类
     */
    public ListNode Merge (ListNode pHead1, ListNode pHead2) {
        // write code here
        ListNode dummyHead=new ListNode(-1);
        ListNode cur=dummyHead;
        ListNode p1=pHead1;
        ListNode p2=pHead2;
        while(p1!=null&&p2!=null){
            if(p1.val<=p2.val){
                cur.next=p1;
                p1=p1.next;
            }else{
                cur.next=p2;
                p2=p2.next;
            }
            cur=cur.next;
        }

        if(p1!=null){
            cur.next=p1;
        }else{
            cur.next=p2;
        }

        return dummyHead.next;
    }
}
进度: 3/72

时间:2024/6/13

类型:数据结构-链表

JZ52 两个链表的第一个公共结点
描述:

输入两个无环的单向链表,找出它们的第一个公共结点,如果没有公共节点则返回空。(注意
因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确
的)
数据范围:m≤1000
要求:空间复杂度O(1),时间复杂度O(n)

示例图像

代码:

import java.util.*;
/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        ListNode cur1=pHead1;
        ListNode cur2=pHead2;

        int len1=0;
        int len2=0;

        while(cur1!=null){
            cur1=cur1.next;
            len1++;
        }
        while(cur2!=null){
            cur2=cur2.next;
            len2++;
        }

        int gap=len1>=len2?len1-len2:len2-len1;
        if(len1<len2){
            ListNode temp=pHead1;
            pHead1=pHead2;
            pHead2=temp;
           
        }

        while(gap-->0){
            pHead1=pHead1.next;
        }

        while(pHead1!=pHead2){
            pHead1=pHead1.next;
            pHead2=pHead2.next;
        }
        return pHead1;
    }
}
进度: 4/72
JZ23 链表中环的入口结
描述:

给一个长度为n链表,若其中包含环,请找出该链表的环的入口结点,否则,返回null。
数据范围:n≤10000,1<=结点值<=10000
要求:空间复杂度O(1),时间复杂度O(n)

示例图像

代码:

import java.util.*;
/*
 public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {

    public ListNode EntryNodeOfLoop(ListNode pHead) {

        ListNode slow = pHead;
        ListNode fast = pHead;

        //如果不存在环就会跳出while循环
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast =fast.next.next;
            if (slow == fast) {
                ListNode index = pHead;
                while (index != slow) {
                    index = index.next;
                    slow = slow.next;
                }
                return index;
            }
        }
        return null;
    }
}
进度: 5/72
JZ22 链表中倒数最后k个结点
描述:

输入一个长度为n的链表,设链表中的元素的值为1,返回该链表中倒数第k个节点。
如果该链表长度小于k,请返回一个长度为0的链表。
数据范围:0≤n≤105,0≤a,≤109,0≤k≤109
要求:空间复杂度O(n),时间复杂度O(n)
进阶:空间复杂度O(1),时间复杂度O(n)

示例图像

代码:

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param pHead ListNode类
     * @param k int整型
     * @return ListNode类
     */
    public ListNode FindKthToTail (ListNode pHead, int k) {
        // write code here
        if(pHead==null) return null;
        ListNode slow=pHead;
        ListNode fast=pHead;
        while(fast!=null&&k-->0){
            fast=fast.next;
        }
        while(fast!=null){
            fast=fast.next;
            slow=slow.next;
        }
        //存在fast==null 但k>0 即链表长度< k
        return k>0?null:slow;
    }
}
进度: 6/72

时间:2024/6/14

类型:数据结构-链表

JZ35 复杂链表的复制
描述:

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针
random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中
请不要返回参数中的节点引用,否则判题程序会直接返回空)。下图是一个含有5个结点的复杂链
表。图中实线箭头表示next指针,虚线箭头表示random指针。为简单起见,指向nul的指针没有画
出。

示例图像

代码:

import java.util.*;
/*
public class RandomListNode {
    int label;
    RandomListNode next = null;
    RandomListNode random = null;

    RandomListNode(int label) {
        this.label = label;
    }
}
*/
public class Solution {
    public RandomListNode Clone(RandomListNode pHead) {
        if(pHead==null) return null;
        //  存放  被拷贝的点      深拷贝后的点
        Map<RandomListNode,RandomListNode> map=new HashMap<>();
        RandomListNode newHead= new RandomListNode(pHead.label);

        map.put(pHead,newHead);
        RandomListNode cur=pHead;
        RandomListNode newCur=newHead;
        while(cur.next!=null){
            RandomListNode newNode=new RandomListNode(cur.next.label);
            map.put(cur.next,newNode);
            newCur.next=newNode;
            newCur=newCur.next;
            cur=cur.next;
        }
        cur=pHead;
        newCur=newHead;
        while(cur!=null){
            newCur.random=map.get(cur.random);
            cur=cur.next;
            newCur=newCur.next;
        }
        return newHead;
    }
}
进度: 7/72
JZ76 删除链表中重复的结点
描述:

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复
的结点不保留,返回链表头指针。例如,链表1->2->3->3->4->4->5处
理后为1->2->5
数据范围:链表长度满足0≤n≤1000,链表中的值满足1≤val≤
1000
进阶:空间复杂度O(n),时间复杂度O(n)
例如输入{1,2,3,3,4,4,5}时,对应的输出为{1,2,5},对应的输入输出链表如下
图所示:

示例图像

代码:
方法一:直接删除

import java.util.*;
/*
 public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    public ListNode deleteDuplication(ListNode pHead) {
        if (pHead == null || pHead.next == null) {
            return pHead;
        }
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = pHead;
        ListNode cur = dummyHead;
        //注意循环条件
        while (cur.next != null && cur.next.next != null) {
            //遇到相邻两个节点值相同
            if (cur.next.val == cur.next.next.val) {
                int temp = cur.next.val;
                //将所有相同的都跳过
                while (cur.next != null && cur.next.val == temp) {
                    cur.next = cur.next.next;
                }
            } else {
                cur = cur.next;
            }
        }
        return dummyHead.next;
    }
}

方法二:Hash表

import java.util.*;
/*
 public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    public ListNode deleteDuplication(ListNode pHead) {
        if (pHead == null) {
            return pHead;
        }
        //用Hash表统计每个节点出现的次数
        Map<Integer, Integer> map = new HashMap<>();
        ListNode cur = pHead;
        while (cur!= null) {
            map.put(cur.val, map.getOrDefault(cur.val, 0) + 1);

            //不要漏了
            cur=cur.next;
        }
       
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = pHead;
        cur = dummyHead;
        while (cur.next != null) {
            //如果为1则不是重复节点
            if (map.get(cur.next.val) != 1) {
                //跳过重复节点
                cur.next = cur.next.next;
            } else {
                cur = cur.next;
            }
        }
        return dummyHead.next;
    }
}
进度: 8/72
JZ18 删除链表的节点
描述:

<给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节
点。返回删除后的链表的头节点。
1.此题对比原题有改动
2.题目保证链表中节点的值互不相同
3.该题只会输出返回的链表和结果做对比,所以若使用C或C++语言,你不
需要free或delete被删除的节点
数据范围:
0<=链表节点值<=10000
0<=链表长度<=10000 /em>

代码:

import java.util.*;
/*
 public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    public ListNode deleteDuplication(ListNode pHead) {
        if (pHead == null) {
            return pHead;
        }
        //用Hash表统计每个节点出现的次数
        Map<Integer, Integer> map = new HashMap<>();
        ListNode cur = pHead;
        while (cur!= null) {
            map.put(cur.val, map.getOrDefault(cur.val, 0) + 1);

            //不要漏了
            cur=cur.next;
        }
       
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = pHead;
        cur = dummyHead;
        while (cur.next != null) {
            //如果为1则不是重复节点
            if (map.get(cur.next.val) != 1) {
                //跳过重复节点
                cur.next = cur.next.next;
            } else {
                cur = cur.next;
            }
        }
        return dummyHead.next;
    }
}
进度: 9/7

时间:2024/6/15

类型:数据结构-二叉树

JZ55 二叉树的深度
描述:

输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的条路径,最长路径
的长度为树的深度,根节点的深度视为1。
数据范围:节点的数量满足0≤n≤100,节点上的值满足0≤wal≤100
进阶:空间复杂度O(1),时间复杂度O(几)

示例图像

代码:
方法一:递归

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param head ListNode类
     * @param val int整型
     * @return ListNode类
     */
    public ListNode deleteNode (ListNode head, int val) {
        if(head==null) return null;
        ListNode dummyHead=new ListNode(-1);
        dummyHead.next=head;
        ListNode pre=dummyHead;
        ListNode cur=dummyHead.next;
        while(cur.val!=val){
            cur=cur.next;
            pre=pre.next;
        }
        pre.next=cur.next;
        return dummyHead.next;
    }
}

方法二:层次遍历

import java.util.*;
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    public int TreeDepth(TreeNode root) {
        if(root==null) return 0;
        int depth=0;
        Deque<TreeNode> que=new LinkedList<TreeNode>();
        que.offer(root);

        while(!que.isEmpty()){
            int size=que.size();
            depth++;
            while(size-->0){
                TreeNode node=que.poll();
                if(node.left!=null){
                    que.offer(node.left);
                }
                 if(node.right!=null){
                    que.offer(node.right);
                }
            }
        }

        return depth;
    }
}
进度: 10/72
JZ54 二叉搜索树的第k个节点
描述:

给定一棵结点数为n二叉搜索树,请找出其中的第k小的TreeNode?结点值。
1.返回第k小的节点值即可
2.不能查找的情况,如二叉树为空,则返回-1,或者k大于等等,也返回-1
3.保证n个节点的值不一样
数据范围:0≤n≤1000,0≤k≤1000,树上每个结点的值满足0≤val≤1000
进阶:空间复杂度O(n),时间复杂度O(n)

示例图像

代码:
方法一:递归

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param proot TreeNode类
     * @param k int整型
     * @return int整型
     */

    int num=0;//记录遍历到第几个数

    int ans = -1;

    //二叉搜索树 中序遍历
    public int KthNode (TreeNode proot, int k) {
        if (proot == null) return -1;
        traversal(proot, k);
        return ans;
    }

    public void traversal(TreeNode cur, int k) {
        if (cur == null) return;
        traversal(cur.left, k);
        num++;
        if (num == k) {
            ans = cur.val;
        }
        traversal(cur.right, k);
    }
}

方法二:栈

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param proot TreeNode类
     * @param k int整型
     * @return int整型
     */
    public int KthNode(TreeNode proot, int k) {
        if (proot == null) return -1;
        Stack<TreeNode> stack = new Stack<>();
        TreeNode node = proot;
       
        //两个条件缺一不可
        while (node != null || !stack.isEmpty()) {
            if (node != null) {
                stack.push(node);
                node = node.left;
            } else {
                node = stack.pop();
                k--;
                if (k == 0) {
                    return node.val;
                }
                    //不需要判断 node.right是否为空
                    node = node.right;
            }

        }
        return -1;

    }
}
进度: 11/72
JZ7 重建二叉树
描述:

给定节点数为 n 的二叉树的前序遍历和中序遍历结果,请重建出该二叉树并返回它的头结点。
例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}

示例图像

代码:

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param preOrder int整型一维数组
     * @param vinOrder int整型一维数组
     * @return TreeNode类
     */
    public TreeNode reConstructBinaryTree (int[] preOrder, int[] vinOrder) {
        // write code here
        return buildTree(preOrder,vinOrder,0,preOrder.length,0,vinOrder.length);
       
    }
    //左闭右开
    public TreeNode buildTree(int[] preOrder, int[] vinOrder,int preLeft,int preRight,int vinLeft,int vinRight){
        if(preLeft>=preRight) return null;
        TreeNode cur=new TreeNode(preOrder[preLeft]);
        int vinIndex=0;
        for(vinIndex=vinLeft;vinIndex<vinRight;vinIndex++){
            if(vinOrder[vinIndex]==cur.val) break;
        }

        int leftLen=vinIndex-vinLeft;

        cur.left=buildTree(preOrder,vinOrder,preLeft+1,preLeft+1+leftLen,vinLeft,vinIndex);
        cur.right=buildTree(preOrder,vinOrder,preLeft+1+leftLen,preRight,vinIndex+1,vinRight);
        return cur;
    }
}
进度: 12/72

时间:2024/6/16

类型:数据结构-二叉树

JZ26 树的子结构
描述:

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

示例图像

代码:

import java.util.*;
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    public boolean HasSubtree(TreeNode root1,TreeNode root2) {
        if(root1==null||root2==null) {
            return false;
        }
        return traversalroot1(root1,root2);
    }

    //遍历root1的每个节点
    public boolean traversalroot1(TreeNode root1,TreeNode root2){
        if(root1==null) return false;
        boolean ans=traversal(root1,root2);
        if(ans) return true;
        boolean left=traversalroot1(root1.left,root2);
        boolean right=traversalroot1(root1.right,root2);
        return left||right;
    }

    //判断是否为子结构
    public boolean traversal(TreeNode cur,TreeNode root2){
        // if(cur==null&&root2==null) return true;
        // if(cur!=null&&root2==null) return true;
        if(root2==null) return true;
        if(cur==null&&root2!=null) return false;
        if(cur.val!=root2.val) return false;
        boolean left=traversal(cur.left,root2.left);
        boolean right=traversal(cur.right,root2.right);

        return left&&right;
    }

}
进度: 13/72
JZ27 二叉树的镜像
描述:

操作给定的二叉树,将其变换为源二叉树的镜像。
数据范围:二叉树的节点数0≤n≤1000,二叉树每个节点的值0≤wal≤
1000
要求:空间复杂度O()。本题也有原地操作,即空间复杂度O(1)的解法,时间
复杂度O(n)

示例图像

代码:

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param pRoot TreeNode类
     * @return TreeNode类
     */
    public TreeNode Mirror (TreeNode pRoot) {
        if(pRoot==null) return null;
        traversal(pRoot);
        return pRoot;
    }


    //可以用前序或者是后序遍历,但不能用中序
    public TreeNode traversal(TreeNode cur){
        if(cur==null) return null;

        //重点
        swap(cur);
        traversal(cur.left);
        traversal(cur.right);
        return cur;

    }

    public void swap(TreeNode root){
        TreeNode temp=root.left;
        root.left=root.right;
        root.right=temp;
    }
}
进度: 14/72
JZ32 从上往下打印二叉树
描述:

不分行从上往下打印出二叉树的每个节点,同层节点从左至右打印。例如输入
{8,6,10,#,#,2,1,如以下图中的示例二叉树,则依次打印8,6,10,2,1(空节点不打印,
跳过),请你将打印的结果存放到一个数组里面,返回。

示例图像

代码:

import java.util.*;
import java.util.ArrayList;
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/

//层序遍历
public class Solution {
    public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
        ArrayList<Integer> list=new ArrayList<>();
        if(root==null) return list;
        Deque<TreeNode> que=new LinkedList<>();
        TreeNode node=root;
        que.offer(node);
        while(!que.isEmpty()){
            int size=que.size();
            while(size-->0){
                node=que.poll();
                list.add(node.val);
                if(node.left!=null){
                    que.offer(node.left);  
                }
                if(node.right!=null){
                    que.offer(node.right);
                }
            }
        }
        return list;
    }
}
进度: 15/72

时间:2024/6/17

类型:数据结构-二叉树

JZ33 二叉搜索树的后序遍历序列
描述:

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则
返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。
数据范围:节点数量0≤m≤1000,节点上的值满足1≤wal≤105,保证
节点上的值各不相同
要求:空间复杂度O(m),时间时间复杂度O(n)
提示:
1.二叉搜索树是指父亲节点大于左子树中的全部节点,但是小于右子树中的全部节点
的树。

示例图像

代码:

import java.util.*;
public class Solution {
    public boolean VerifySquenceOfBST(int [] sequence) {
        if(sequence==null||sequence.length==0){
            return false;
        }

        return f(sequence,0,sequence.length-1);
    }


    //思路:递归
    //首先从左往右找到第一个大于root值的节点
    //这时从这个节点往后到root节点到前一个节点,
    //如果发现有大于root节点的值,则不是正确的二叉树后序遍历序列
    public boolean f(int[] sequence,int i,int j){

        //如果之前一直没找到错误,返回true
        if(i>=j) return true;
        int root=sequence[j];
        int p=i;
        while(sequence[p]<root&&p<j) p++;

        for(int a=p+1;a<j;a++){
            if(sequence[a]<root){
                return false;
            }
        }
        return f(sequence,i,p-1)&&f(sequence,p,j-1);
    }
}
进度: 16/72
  • 19
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值