ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

面试题4、5、6、7

2021-03-05 14:01:36  阅读:117  来源: 互联网

标签:面试题 遍历 return int TreeNode inorder 节点


面试题4:二维数组中的查找

在这里插入图片描述
以 matrix 中的左下角元素为标志数 flag,则有:

  • 若 flag > target,则 target 一定在 flag 所在行的上方,即 flag 所在行可被消去。
  • 若 flag < target,则 target 一定在 flag 所在列的右方,即 flag 所在列可被消去。

在这里插入图片描述
在这里插入图片描述

class Solution {
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
		int len = matrix.length;
		if(len < 1) return false;
		int row = len - 1, col = 0;
		while(row >= 0 && col < len) {
			if(matrix[row][col] > target) row--;
			else if(matrix[row][col] < target) col++;
			else return true; 
		}
		return false;
    }
}

————————————————————————————————————————

面试题5.替换空格

在这里插入图片描述

方法:遍历添加

1、初始化一个 StringBuilder,记为 res

2、遍历列表 s 中的每个字符 c:

  • 当 c 为空格时,向 res 后添加字符串“%20”;
  • 当 c 不为空格时:向 res后添加字符 c;

3、将 res 转化为字符串并返回

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

class Solution {
    public String replaceSpace(String s) {
		StringBuilder res = new StringBuilder();
		for(char c : s.toCharArray()){
			if(c == ' ') res.append("%20");
			else res.append(c);
		}
		return res.toString();
    }
}

//调用库函数
class Solution {
    public String replaceSpace(String s) {
		return s.replaceAll(" ", "%20");
    }
}

————————————————————————————————————————

面试题6.从尾到头打印链表

在这里插入图片描述

方法一:辅助栈法

解题思路:

链表的遍历顺序是从头到尾访问节点,而题目要求从尾到头输出,先入后出可以借助栈来实现

1、入栈:遍历链表,将各节点值 push 入栈

2、出栈:将各节点 pop 出栈,存储于数组并返回

在这里插入图片描述

class Solution {
    public int[] reversePrint(ListNode head) {
		LinkedList<Integer> stack = new LinkedList<>();
		while(head != null) {
			stack.addLast(head.val);
			head = head.next;
		}
		int[] res = new int[stack.size()];
		for(int i = 0; i < stack.size(); i++) {
			res[i] = stack.removeLast();
		}
		return res;
    }
}

方法二:递归

解题思路:

先走至链表末端,回溯时依次将节点值加入列表,这样就实现链表的倒序输出

1、递推阶段:每次传入 head.next,以 head == null 为递归终止条件
2、回溯阶段:层层回溯时,将当前节点值加入结果数组

在这里插入图片描述
在这里插入图片描述

class Solution {
    int[] res; //结果数组
    int i = 0; //记录链表的元素总个数,表示结果数组的长度
    int j = 0; //数据要存入数组的索引
    public int[] reversePrint(ListNode head) {
		dfs(head);
		return res;
    }
    public void dfs(ListNode head) {
    	if(head == null) {
    		res = new int[i];
    		return;
    	}
    	i++; //每遍历到一个元素,则总个数加1
    	dfs(head.next);
    	res[j] = head.val; //从尾到头输出,所以链表最后一个元素要存在数组第一个位置,依次往后存
    	j++;
    }
}

————————————————————————————————————————

面试题7.重建二叉树

在这里插入图片描述
解题思路:

前序遍历性质:节点按照 [ 根节点 | 左子树 | 右子树 ] 排序
中序遍历性质:节点按照 [ 左子树 | 根节点 | 右子树 ] 排序

1、前序遍历的首元素为树的根节点 root 的值

2、在中序遍历中搜索根节点 root 的索引,可将中序遍历划分为 [ 左子树 | 根节点 | 右子树 ]。

3、根据中序遍历中的左右子树的节点数量,可将前序遍历划分为 [ 根节点 | 左子树 | 右子树 ]。
在这里插入图片描述
在这里插入图片描述

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int x) {
        val = x;
    }
}

public class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
		int preLen = preorder.length;
		int inLen = inorder.length;
		if(preLen != inLen) return null;
		return buildTree(preorder, 0, preLen - 1, inorder, 0, inLen - 1);
    }
    /**
     *  使用数组preorder在索引区间[preLeft, preRight]中的所有元素
     *  和数组inorder在索引区间[inLeft, inRight]中的所有元素来构造二叉树
     *  
     * preorder 二叉树前序遍历的数组
     * preLeft  前序遍历结果的左边界
     * preRight 前序遍历结果的右边界
     * inorder  二叉树中序遍历的数组
     * inLeft   中序遍历结果的左边界
     * inRight  中序遍历结果的右边界
     * return 二叉树的根节点
     */
    public TreeNode buildTree(int[] preorder, int preLeft, int preRight,
    						  int[] inorder, int inLeft, int inRight) {
    	//先写递归终止条件
    	if(preLeft > preRight || inLeft > inRight) return null;
    	int pivot = preorder[preLeft];
    	TreeNode root = new TreeNode(pivot); //构造当前根节点
    	int pivotIndex = inLeft; //用来找pivot节点在inorder数组中的索引位置
    	while(pivotIndex < inRight && inorder[pivotIndex] != pivot) {
    		pivotIndex++;
    	}			
    	//构建根节点的左子节点	
    	root.left = buildTree(preorder, preLeft + 1, preLeft + pivotIndex - inLeft,
    						  inorder, inLeft, pivotIndex - 1);
    	//构建根节点的右子节点
    	root.right = buildTree(preorder, preLeft + pivotIndex - inLeft + 1, preRight,
    						   inorder, pivotIndex + 1, inRight);
    	return root; //返回当前根节点		  
    }
}

优化

将中序遍历的值和索引存在一个哈希表中,这样就可以一下子找到根节点在中序遍历数组中的索引

public class Solution {

    private int[] preorder;
    private Map<Integer, Integer> hash;

    public TreeNode buildTree(int[] preorder, int[] inorder) {
        int preLen = preorder.length;
        int inLen = inorder.length;
        if (preLen != inLen) {
            return null;
        }
        this.preorder = preorder;
        this.hash = new HashMap<>();
        for (int i = 0; i < inLen; i++) {
            hash.put(inorder[i], i);
        }

        return buildTree(0, preLen - 1, 0, inLen - 1);
    }


    private TreeNode buildTree(int preLeft, int preRight, int inLeft, int inRight) {
        // 因为是递归调用的方法,按照国际惯例,先写递归终止条件
        if (preLeft > preRight || inLeft > inRight) {
            return null;
        }
        // 先序遍历的起点元素很重要
        int pivot = preorder[preLeft];
        TreeNode root = new TreeNode(pivot);
        int pivotIndex = hash.get(pivot); //这一步相较于前一个方法,就省去了遍历匹配的过程
        root.left = buildTree(preLeft + 1, pivotIndex - inLeft + preLeft,
                inLeft, pivotIndex - 1);
        root.right = buildTree(pivotIndex - inLeft + preLeft + 1, preRight,
                pivotIndex + 1, inRight);
        return root;
    }
}

变换题:从中序与后序遍历序列构造二叉树

在这里插入图片描述
解题思路:

中序遍历性质:节点按照 [ 左子树 | 根节点 | 右子树 ] 排序
后序遍历性质:节点按照 [ 左子树 | 右子树 | 根节点 ] 排序

1、后序遍历的尾元素为树的根节点 root 的值

2、在中序遍历中搜索根节点 root 的索引,可将中序遍历划分为 [ 左子树 | 根节点 | 右子树 ]。

3、根据中序遍历中的左右子树的节点数量,可将前序遍历划分为 [ 左子树 | 右子树 | 根节点 ]。

在这里插入图片描述
在这里插入图片描述

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    Map<Integer, Integer> map = new HashMap<>();
    public TreeNode buildTree(int[] inorder, int[] postorder) {
		int inLen = inorder.length;
		int postLen = postorder.length;
		if(inLen != postLen) return null;
		for(int i = 0; i < inLen; i++) {
			map.put(inorder[i], i);
		}
		
    }
    public TreeNode dfs(int[] inorder, int inLeft, int inRight,
    					int[] postorder, int postLeft, int postRight) {
    	if(inLeft > inRight || postLeft > postRight) return null;
    	int pivot = postorder[postRight];
    	int pivotIndex = map.get(pivot);
    	root.left = dfs(inorder, inLeft, pivot - 1, 
    					postorder, postLeft, postLeft + pivot - inLeft - 1);
    	root.right = dfs(inorder, pivot + 1, inRight,
    					postorder, postLeft + pivot - inLeft, postRight - 1);
    	return root;					
    }
}

标签:面试题,遍历,return,int,TreeNode,inorder,节点
来源: https://blog.csdn.net/weixin_44460781/article/details/114382586

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有