二叉树常见算法整理

2 篇文章 0 订阅

二叉树的结构定义如下:

public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

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

序列化二叉树

实现两个函数,分别用来序列化和反序列化二叉树

二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 , 表示一个结点值的结束(value,)。

二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。

例如,我们可以把一个只有根节点为1的二叉树序列化为"1,",然后通过自己的函数来解析回这个二叉树

public class Solution {
    StringBuilder sb = new StringBuilder();
     //序列化,先序遍历
    String Serialize(TreeNode root) {  
        if(root==null){
            sb.append("#,");
            return sb.toString();
        }
        sb.append(root.val+",");
        Serialize(root.left);
        Serialize(root.right);
        return sb.toString();
    }
    
    //反序列化,先序遍历
    int index = -1;
    TreeNode Deserialize(String str) {   
       index++;
       if(index >= str.length()){
           return null;
       }
       String[] s = str.split(",");
       TreeNode node = null;
       if(!s[index].equals("#")){
           node = new TreeNode(Integer.valueOf(s[index]));
           node.left = Deserialize(str);
           node.right = Deserialize(str);
       }
       return node;
    }
}

二叉搜索树的第k个节点

给定一棵二叉搜索树,请找出其中的第k小(从小到大排列,第k个节点)的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。

import java.util.Stack;
public class Solution {
	int count = 0;
	// 方法一、递归
	// 当index == k时,return root返回的是当前节点,return node的作用是结束递归
	TreeNode KthNode(TreeNode root, int k){
        if(root != null){ //中序遍历寻找第k个
            TreeNode node = KthNode(root.left,k);
            if(node != null)
                return node;
            index ++;
            if(index == k)
                return root;
            node = KthNode(root.right,k);
            if(node != null)
                return node;
        }
        return null;
    }    

    // 方法二、非递归(借助栈)
    TreeNode KthNode(TreeNode node, int k){
        if(pRoot==null || k<=0){
            return null;
        }
        Stack<TreeNode> s = new Stack<>();
        s.push(node);
        while(node.left!=null){
            s.push(node.left);
            node = node.left;
        }
        while(!s.isEmpty()){
            TreeNode cur = s.pop();
            count++;
            if(count==k){
                return cur;
            }
            if(cur.right!=null){
                s.push(cur.right);
                cur = cur.right;
                while(cur.left!=null){
                   s.push(cur.left);
                   cur = cur.left;
                }
            }
        }
        return null;
    }
}

把二叉树打印成多行

从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。

import java.util.ArrayList;
import java.util.Queue;
import java.util.LinkedList;
public class Solution {
	// 用队列存储每行的节点
	// start标记正在处理的节点,end标记每层的节点数
    ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        ArrayList<Integer> list = new ArrayList<>();
        if(pRoot==null){
            return res;
        }
        int start = 0;
        int end = 1;
        Queue<TreeNode> que = new LinkedList<>();
        que.add(pRoot);
        while(!que.isEmpty()){
            TreeNode node = que.poll();
            list.add(node.val);
            start++;
            if(node.left!=null){
                que.add(node.left);
            }
            if(node.right!=null){
                que.add(node.right);
            }
            if(start==end){
                res.add(list);
                list = new ArrayList<>();
                end = que.size();
                start=0;
            }
        }
        return res;
    }
    
}

按之字形顺序打印二叉树

请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。

import java.util.Stack;
import java.util.ArrayList;
public class Solution {
	// 用两个栈分别存储奇偶层的节点
	// 当前栈为空时即为一层节点遍历结束,可加入res集合中(list集合不为空)
	// 奇数层弹栈后向偶数层添加左右节点(先左后右)
	// 偶数层弹栈后向奇数层添加左右节点(先右后左)
    public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        ArrayList<Integer> list;
        if(pRoot==null){
            return res;
        }
        Stack<TreeNode> stack1 = new Stack<>();
        Stack<TreeNode> stack2 = new Stack<>();
        
        stack1.push(pRoot);
        while(!stack1.isEmpty() || !stack2.isEmpty()){
            list = new ArrayList<>();
            while(!stack1.isEmpty()){
                TreeNode node = stack1.pop();
                list.add(node.val);
                if(node.left!=null){
                    stack2.push(node.left);
                }
                if(node.right!=null){
                    stack2.push(node.right);
                }
            }
            if(!list.isEmpty()){
                res.add(list);
            }

            list = new ArrayList<>();
            while(!stack2.isEmpty()){
                TreeNode node = stack2.pop();
                list.add(node.val);
                if(node.right!=null){
                    stack1.push(node.right);
                }
                if(node.left!=null){
                    stack1.push(node.left);
                }
            }
            if(!list.isEmpty()){
                res.add(list);
            }
        }
        return res;
    }
}

对称的二叉树

请实现一个函数,用来判断一棵二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。

public class Solution {
	// 注意判断条件,仅当左子树和右子树同时为空(即遍历结束)时才返回true
	// 当 left.val==right.val时,继续遍历其各自的左右子树是否对应相等
	// 对应关系:左子树的左节点和右子树的右节点值相等,左子树的右节点和右子树的左节点相等  
	// return judge(left.left,right.right) && judge(left.right,right.left);
    boolean isSymmetrical(TreeNode pRoot){
        if(pRoot==null){
            return true;
        }
        return judge(pRoot.left, pRoot.right);
    }
    
    boolean judge(TreeNode left, TreeNode right){
        if(left==null){
            if(right==null){
                return true;
            }
            return false;
        }
        if(right==null){
            return false;
        }
        if(left.val==right.val){
            return judge(left.left,right.right) && judge(left.right,right.left);
        }
        return false;
    }
}

二叉树的深度

输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度(路径上的节点数)。

import java.util.Queue;
import java.util.LinkedList;
public class Solution {

    // 方法一:递归

    public int TreeDepth(TreeNode root) {
        if(root==null){
            return 0;
        }
        
        int left = TreeDepth(root.left);
        int right = TreeDepth(root.right);
        return Math.max(left,right)+1;
    }

    // 方法二:非递归
    public int TreeDepth(TreeNode root){
        if(root==null){
            return 0;
        }
        Queue<TreeNode> que = new LinkedList<>();
        que.add(root);
        int depth = 0;
        int start = 0;
        int end = 1;
        while(!que.isEmpty()){
            TreeNode node = que.poll();
            start++;
            if(node.left!=null){
                que.add(node.left);
            }
            if(node.right!=null){
                que.add(node.right);
            }
            if(start==end){
                depth++;
                start = 0;
                end = que.size();
            }
            
        }
        return depth;
    }
}

二叉树的节点数

输入一棵二叉树,求该二叉树的节点数。

public class Solution {
	// 对比计算二叉树的深度
    public int countNode(Node root){
        if (root==null){
            return 0;
        }
        int left = countNode(root.left);
        int right = countNode(root.right);
        return left + right + 1;
    }
}

平衡二叉树

输入一棵二叉树,判断该二叉树是否是平衡二叉树。

在这里,我们只需要考虑其平衡性,不需要考虑其是不是排序二叉树

public class Solution {
    // 方法一、自顶向下遍历
    // 遍历每个结点,借助一个获取树深度的递归函数
    // 根据该结点的左右子树高度差判断是否平衡,然后递归地对左右子树进行判断。
    // 缺点:在判断上层结点的时候,会多次重复遍历下层结点
    public boolean IsBalanced_Solution(TreeNode root) {
        if(root==null){
            return true;
        }
        return Math.abs(countDepth(root.left)-countDepth(root.right))<=1 && 
            IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
    }
    
    public int countDepth(TreeNode node){
        if(node==null){
            return 0;
        }
        return Math.max(countDepth(node.left),countDepth(node.right))+1;
    }
   // 方法二、自底向上遍历,在获取树深度的同时,添加判断条件
   // 如果子树是平衡二叉树,则返回子树的高度;
   // 如果发现子树不是平衡二叉树,则直接停止遍历,这样至多只对每个结点访问一次。
     public boolean IsBalanced_Solution(TreeNode root){
         return getDepth(root)!=-1;
     }
    
     public int getDepth(TreeNode node){
         if(node==null){
             return 0;
         }
         int left = getDepth(node.left);
         if(left==-1){
             return -1;
         }
         int right = getDepth(node.right);
         if(right==-1){
             return -1;
         }
         return Math.abs(left-right)<=1 ? Math.max(left,right)+1 : -1;
     }
}

二叉树的两个节点之间最远的距离

问题:如果我们把二叉树看做图,父子节点之间的连线看成是双向的,我们姑且定义“距离”为两个节点之间边的个数。写一个程序求一棵二叉树中相距最远的两个节点之间的距离。

如下图所示,树中相距最远的两个节点为A,B,最大距离为6。
在这里插入图片描述

分析:计算一个二叉树的最大距离有两个情况:

  • 情况A: 路径经过左子树的最深节点,通过根节点,再到右子树的最深节点;
  • 情况B: 路径不穿过根节点,而是左子树或右子树的最大距离路径,取其大者。

思路:递归求解每个节点的左、右子树的深度,不断更新全局变量maxLen,其值为Math.max(maxLen,(left+right));

public class Solution {
	private int maxLen = 0;
	
	public int findMaxLen(Node root){
	        if(root==null){
	            return 0;
	        }
	        int left = findMaxLen(root.left);
	        int right = findMaxLen(root.right);
	        int temp = left+right;
	        if(temp > maxLen){
	            maxLen = temp;
	        }
	        return Math.max(left,right)+1;
	    }
}

二叉树的镜像

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

源二叉树 
	    8
	   /  \
	  6   10
	 / \  / \
	5  7 9 11
	
镜像二叉树
	    8
	   /  \
	  10   6
	 / \  / \
	11 9 7  5
 public class Solution {
 // 先序遍历二叉树的每个节点,如果当前节点存在子节点(左节点或者右节点),则交换两节点
 // 递归交换所有非叶子节点的左右节点后,就得到了源二叉树的镜像二叉树
    public void Mirror(TreeNode root) {
        if(root==null){
            return;
        }
        if(root.left==null && root.right==null){
            return;
        }
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
        if(root.left!=null){
            Mirror(root.left);
        }
        if(root.right!=null){
            Mirror(root.right);
        }
        
    }
}

二叉树的下一个节点

给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。

public class Solution {
	// 分两种情况:
	// 1) 当前节点存在右子树,则右子树的最左子树即为中序遍历的下一个节点;
	// 2) 当前节点不存在右子树,向上查找满足当前节点的父节点的左节点即为当前节点的那个节点,其父节点即为所求节点。
	//    while(pNode.next!=null && pNode.next.left!=pNode)
	// 注意:根节点的next节点为null
    public TreeLinkNode GetNext(TreeLinkNode pNode){
        if(pNode==null){
            return null;
        }
        if(pNode.right!=null){
            TreeLinkNode node = pNode.right;
            while(node.left!=null){
                node = node.left;
            }
            return node;
        }
        while(pNode.next!=null && pNode.next.left!=pNode){
            pNode = pNode.next;
        }
        return pNode.next;
    }
}

二叉搜索树与双向链表

题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

思路:线索二叉树(在传统二叉树的基础上,利用空的指针域,当一个节点的左孩子为空时,让其指向其前驱节点;当节点的右孩子为空时,让其指向后继节点,前驱和后继节点,可以按照先序、中序或者后序的顺序来判定),就是把二叉树变成了一个双向链表 。

二叉搜索树按中序遍历构建线索二叉树得到的就是排序的双向链表

方法1、中序遍历二叉树,将其节点添加至链表中,遍历链表,将当前节点的右孩子指向后一个节点,后一个节点的左孩子指向当前节点;

方法 2、中序遍历(先右后左得到降序,若先左后右得到的是升序,pre指向最大节点),在递归遍历的过程中,pre作为前一个节点,pRootOfTree作为当前节点,当pre不为空时,pRootOfTree.right=pre; pre.left=pRootOfTree; pre移动赋值:pre = pRootOfTree,递归结束条件是pRootOfTree==null,返回值是pre(这时pre指向的的最小节点)

import java.util.ArrayList;
public class Solution {
    // 方法一
    ArrayList<TreeNode> list = new ArrayList<>();
    public TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree==null){
            return null;
        }
        inOrder(pRootOfTree);
        for(int i=0; i<list.size()-1; i++){
            list.get(i).right = list.get(i+1);
            list.get(i+1).left = list.get(i);
        }
        return list.get(0);
    }
    
    public void inOrder(TreeNode root){
        if(root==null){
            return;
        }
        inOrder(root.left);
        list.add(root);
        inOrder(root.right);
    }
    
	/*
    //方法二
    TreeNode pre = null;
    public TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree==null){
            return null;
        }
        Convert(pRootOfTree.right);
        if(pre!=null){
            pRootOfTree.right = pre;
            pre.left = pRootOfTree;
        }
        pre = pRootOfTree;
        Convert(pRootOfTree.left);
        return pre;
    }
    */
}

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

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

public class Solution {
	// 数组为空时返回
    public boolean VerifySquenceOfBST(int [] sequence) {
        if(sequence==null || sequence.length==0){
            return false;
        }
        if(sequence.length==1){
            return true;
        }
        return verifySquenceOfBST(sequence, 0, sequence.length-1);
    }
    // 后序遍历得到的序列最后一个值是当前子树的根节点
    // 从根节点向前搜索,找到第一个小于根节点的值,其左(包括自身)为当前根节点的左子树,其右为右子树
    // 更新区间的左右边界, 递归判断:左子树区间的所有结点值 < 根结点值 < 右子树区间所有结点值,这个条件是否满足
    // 注意:判断成立的递归出口为start>=end(不是start==end)
    public boolean verifySquenceOfBST(int[] sequence, int start, int end){
        if(start>=end){
            return true;
        }
        int base = sequence[end];
        int i = end-1;
        for(; i>=start; i--){
            if(sequence[i]<base){
                break;
            }
        }
        for(int j=i-1; j>=start; j--){
            if(sequence[j]>base){
                return false;
            }
        }
        return verifySquenceOfBST(sequence, i+1, end-1) && verifySquenceOfBST(sequence, start, i);
    }
}

重建二叉树

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

public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
    	if(pre==null || in == null || pre.length==0 || in.length==0){
            return null;
        }
        
        TreeNode root = reConstructBinaryTree(pre, 0, pre.length-1, in, 0, in.length-1);
        return root;
    }
 
/* 先序遍历第一个位置肯定是根节点node,
  
  中序遍历的根节点位置在中间p,在p左边的肯定是node的左子树的中序数组,p右边的肯定是node的右子树的中序数组
  
  另一方面,先序遍历的第二个位置到p,也是node左子树的先序子数组,剩下p右边的就是node的右子树的先序子数组
  
  把四个数组找出来,分左右递归调用即可
  
  注意:
  	1)根节点左子树的pre数组的右边界为startPre+i-startIn(而不是startPre+i);
  	2)递归出口的判断条件为 startPre > endPre || startIn > endIn, 当相等时,仍需要建立左节点或者右节点。
*/
    private TreeNode reConstructBinaryTree(int[] pre, int startPre, int endPre, int[] in, int startIn, int endIn){
        if(startPre > endPre || startIn > endIn){
            return null;
        }
        TreeNode root = new TreeNode(pre[startPre]);
        int i=startIn;
        for(; i<=endIn; i++){
            if(in[i] == pre[startPre]){
                break;
            }
        }
        root.left = reConstructBinaryTree(pre, startPre+1, startPre+i-startIn, in, startIn, i-1);
        root.right = reConstructBinaryTree(pre, i-startIn+startPre+1, endPre, in, i+1, endIn);
        return root;
    }
}

树的子结构

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

思路:

  • 子树:只要包含了一个结点,就得包含这个结点下的所有节点。
  • 子结构:包含了一个结点,可以只取左子树或者右子树,或者都不取。

若树 B 是树 A 的子结构,则子结构的根节点可能为树 A 的任意一个节点。因此,判断树 B 是否是树 A 的子结构,需完成以下两步工作:
1)先序遍历树 A 中的每个节点node;
2)判断树 A中以node为根节点的子树是否包含树 B(当node2=null时,返回true;当node1=null || node.val != node2.val 时返回false,递归遍历左右子树
return recur(A.left, B.left) && recur(A.right, B.right); )。

若树 B 是树 A 的子结构,则必满足以下三种情况之一,因此用或 || 连接;

  • 以 节点 A 为根节点的子树 包含树 B ,对应 recur(A, B);
  • 树 B 是 树 A 左子树 的子结构,对应 isSubStructure(A.left, B);
  • 树 B 是 树 A 右子树 的子结构,对应 isSubStructure(A.right, B);
// 判断一个树是否是另一个树的子结构
public class Solution {
    public boolean HasSubtree(TreeNode root1,TreeNode root2) {
        if(root1==null || root2==null){
            return false;
        }
        return hasSubtree(root1, root2) || HasSubtree(root1.left, root2) || HasSubtree(root1.right, root2);

    }
    
    public boolean hasSubtree(TreeNode root1, TreeNode root2){
        if(root2==null){
            return true;
        }
        if(root1==null || root1.val != root2.val){
            return false;
        }
        return hasSubtree(root1.left,root2.left) && hasSubtree(root1.right,root2.right);
    }
}
// 判断一个树是否是另一个树的子树
public class Solution {
    public boolean HasSubtree(TreeNode root1,TreeNode root2) {
        if(root1==null || root2==null){
            return false;
        }
        return hasSubtree(root1, root2) || HasSubtree(root1.left, root2) || HasSubtree(root1.right, root2);

    }
    
    public boolean hasSubtree(TreeNode root1, TreeNode root2){
        if(root1==null && root2==null){
            return true;
        }
        if(root1==null || root2==null || root1.val != root2.val){
            return false;
        }
        return hasSubtree(root1.left,root2.left) && hasSubtree(root1.right,root2.right);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
字节跳动常见算法面试题top50整理如下: 1. 两数之和:给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。 2. 两数相加:给定两个非空链表表示两个非负整数,将两数相加返回一个新的链表。 3. 无重复字符的最长子串:给定一个字符串,请找出其中不含有重复字符的最长子串的长度。 4. 两个排序数组的中位数:给定两个大小分别为 m 和 n 的有序数组 nums1 和 nums2,请找出这两个有序数组的中位数。 5. 电话号码的字母组合:给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。 6. 四数之和:给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a、b、c 和 d,使得 a + b + c + d 的值与 target 相等。 7. 合并两个有序链表:将两个有序链表合并为一个新的有序链表并返回。 8. 验证回文串:给定一个字符串,验证它是否是回文串。 9. 最长有效括号:给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。 10. 二叉树的最大深度:给定一个二叉树,找出其最大深度。 11. 盛最多水的容器:给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai)。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 12. 三数之和:给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ? 13. 最接近的三数之和:给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。 14. 有效的括号:给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。 15. 合并两个有序数组:给定两个有序数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。 16. 数组中的第K个最大元素:在未排序的数组中找到第 k 个最大的元素。 17. 罗马数字转整数:将罗马数字转换成整数。 18. 最小路径和:给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和最小。 19. 矩阵置零:给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。 20. 字符串相乘:给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积。 21.有效的数独:判断一个 9x9 的数独是否有效。 22. 旋转图像:给定一个 n × n 的二维矩阵表示一个图像,将图像顺时针旋转 90 度。 23. 搜索旋转排序数组:假设按照升序排序的数组在预先未知的某个点上进行了旋转。 24. 螺旋矩阵:给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。 25. 合并K个排序链表:合并 k 个排序链表,返回合并后的排序链表。 26. 不同路径:一个机器人位于一个 m x n 网格的左上角,机器人每次只能向下或者向右移动一步。 27. 跳跃游戏:给定一个非负整数数组,你最初位于数组的第一个位置。 28. 插入区间:给出一个无重叠的,按照区间起始端点排序的区间列表。 29. 最长公共前缀:编写一个函数来查找字符串数组中的最长公共前缀。 30. 螺旋矩阵 II:给定一个正整数 n,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。 31. 编辑距离:给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数。 32. 删除排序链表中的重复元素:给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。 33. 字符串转整数(atoi):请你来实现一个 atoi 函数,使其能将字符串转换成整数。 34. 平衡二叉树:给定一个二叉树,判断它是否是高度平衡的二叉树。 35. Pow(x, n):实现 pow(x, n),即计算 x 的 n 次幂函数。 36. 搜索二维矩阵:编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。 37. 接雨水:给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 38. 二进制求和:给定两个二进制字符串,返回它们的和(用二进制表示)。 39. 括号生成:给出 n 对括号,请编写一个函数来生成所有的由 n 对括号组成的合法组合。 40. 逆波兰表达式求值:根据逆波兰表示法,求表达式的值。 41. 环形链表:给定一个链表,判断链表中是否有环。 42. 环形链表 II:给定一个链表,返回链表开始入环的第一个节点。 43. 重建二叉树:根据一棵树的前序遍历与中序遍历构造二叉树。 44. 验证二叉搜索树:给定一个二叉树,判断其是否是一个有效的二叉搜索树。 45. 二叉树的中序遍历:给定一个二叉树,返回它的中序 遍历。 46. 最小栈:设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。 47. 单词拆分:给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。 48. 对称二叉树:给定一个二叉树,检查它是否是镜像对称的。 49. N皇后问题:给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。 50. 跳跃游戏 II:给定一个非负整数数组,你最初位于数组的第一个位置,在该位 我们的主要任务是根据输入来模拟对话。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值