(A卷,200分)- 查找树中元素(Java & JS & Python)

题目描述

已知树形结构的所有节点信息,现要求根据输入坐标(x,y)找到该节点保存的内容值,其中x表示节点所在的层数,根节点位于第0层,根节点的子节点位于第1层,依次类推;y表示节点在该层内的相对偏移,从左至右,第一个节点偏移0,第二个节点偏移1,依次类推;

举例:上图中,假定圆圈内的数字表示节点保存的内容值,则根据坐标(1,1)查到的内容值是23。 

输入描述

每个节点以一维数组(int[])表示,所有节点信息构成二维数组(int[][]),二维数组的0位置存放根节点;
表示单节点的一维数组中,0位置保存内容值,后续位置保存子节点在二维数组中的索引位置
对于上图中:

  • 根节点的可以表示为{10,1,2},
  • 树的整体表示为{{10,1,2},{-21,3,4},{23,5},{14},{35},{66}}

查询条件以长度为2的一维数组表示,上图查询坐标为(1,1)时表示为{1,1}

使用Java标准IO键盘输入进行录入时,

  1. 先录入节点数量
  2. 然后逐行录入节点
  3. 最后录入查询的位置

对于上述示例为:

6
10 1 2
-21 3 4
23 5
14
35
66
1 1

输出描述

查询到内容时,输出{内容值},查询不到时输出{}
上图中根据坐标(1,1)查询输出{23},根据坐标(1,2)查询输出{}

用例

输入 6
10 1 2
-21 3 4
23 5
14
35
66
1 1
输出 {23}
说明

2023.1.16新增用例说明,之前代码只是根据用例1写的,误以为题目中说的树是二叉树,因此代码存在问题,后面发现了原题更多的用例说明,意识到本题的树是多叉树,但是本题代码中多叉树的处理逻辑和二叉树相同,只需要微调代码即可

输入 14
0 1 2 3 4
-11 5 6 7 8
113 9 10 11
24 12
35
66 13
77
88
99
101
102
103
25
104
2 5
输出 {102}
说明
输入 14
0 1 2 3 4
-11 5 6 7 8
113 9 10 11
24 12
35
66 13
77
88
99
101
102
103
25
104
3 2
输出 {}
说明
输入 1
1000
0 0
输出 {1000}
说明

题目解析

这题输入描述比较晦涩难懂,但我还是猜出来一点:

每个节点以一维数组(int[])表示,所有节点信息构成二维数组(int[][]),二维数组的0位置存放根节点;

这句话的意思就是:用例的第二行输入到倒数第二行输入可以构成一个二维数组,二维数组的元素是一维数组,如下图

[
    [10,1,2],
    [-21,3,4],
    [23,5],
    [14],
    [35],
    [66]
]

假设二维数组是matrix的话,则每一个matrix[i]对应树的一个节点,其中matrix[0] (如用例[10,1,2])代表的是树的根节点。

表示单节点的一维数组中,0位置保存内容值,后续位置保存子节点在二维数组中的索引位置

上面这句话的意思是,matrix[i] (是一个一维数组),我们用arr = matrix[i],则arr[0]表示节点的内容值,arr[1]、arr[2]表示的是该节点的子节点在matrix中的索引位置。

比如[10,1,2]表示内容值为10的节点,有两个子节点,分别是matrix[1]和matrix[2],即[-21,3,4],[23,5]。

由于本题是二叉树,因此一个节点最多有两个子节点,最少没有子节点。

以上是关于输入描述的解读。

本题并没有说二叉树是完全二叉树,因此二叉树的节点非常有可能像:

因此无法直接利用完全二叉树特性。

但是也不难,本题就是就是一个简单的深度优先搜索题

本题的意思其实就是让我们再构造一个二维数组matrix2,这个二维数组形式如上图所示,具体内容如下

[
    [10],
    [-21, 23],
    [14,35,66]
]

因此,我们很容想到利用深度优先搜索,从根节点开始递归,dfs(root, 0),dfs参数含义是:当前节点root,得到的节点值将放置于二维数组matrix2的第0行。

从根节点还可以得到其左右子节点的索引,因此我们可以继续递归其左右子节点 dfs(left, 1)、dfs(right,1),只是此时的得到的子节点将放于matrix2的第1行。

由此,我们就可以将节点值放到正确的行位置上了。

那么列位置该如何确认呢?

很好解决,matrix2的每一行都是一个数组,由于我们是优先左子树遍历,因此,总是每一行最左边的节点被优先遍历出来,我们只需要将遍历出来的节点值push压入对应行的数组中即可。比如:

matrix2一开始是空数组[],然后遍历得到根节点,压入第0行的数组元素中,但是第0行没有数组元素,因此就构造一个[val]压入,同理处理根节点的左子节点,然后继续处理左子节点的左子节点,因此第一个深搜回溯时,得到

[
    [10],
    [-21],
    [14]
]

即确认了每一行数组的第一个元素,刚好是

然后回溯过程将其余节点值依次加入每一行数组中,最终得到

 [
    [10],
    [-21, 23],
    [14,35,66]
]

此时,找任意位置的节点值都是so easy

2023.03.17 补充一个用例

本题中最后一行输入的目标节点坐标位置可能是负数,尼玛,我服了,比如下面用例

6
10 1 2
-21 3 4
23 5
14
35
66
-1 -1

如果坐标位置为负数,则会出现数组越界的问题,加了这个就100%了

JavaScript算法源码

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

const lines = [];
let n;
rl.on("line", (line) => {
  lines.push(line);

  if (lines.length === 1) {
    n = lines[0] - 0;
  }

  if (n && lines.length === n + 2) {
    lines.shift();
    const [tx, ty] = lines.pop().split(" ").map(Number);
    const nodes = lines.map((line) => line.split(" ").map(Number));

    console.log(getResult(nodes, tx, ty));

    lines.length = 0;
  }
});

/**
 *
 * @param {*} nodes 数组,存储树中所有节点,数组元素node也是数组,node = [val, left, right] ,其中val是node节点的内容值,left是node节点的左子节点的索引,right是node节点的右子节点的索引,索引是相对nodes而言的
 * @param {*} tx 目标位置x坐标
 * @param {*} ty 目标位置y坐标
 */
function getResult(nodes, tx, ty) {
  // 2023.03.17,尼玛,谁能想到还有tx,ty小于0的用例,题目描述一点没说
  if (tx < 0 || ty < 0) return "{}";

  const matrix = [];

  function dfs(node, level) {
    if (!node) return;

    // 2023.1.16更新代码逻辑,之前本题只有用例1,因此误以为题目中的树指的是二叉树,因此错误意味一个节点最多只有两个子节点,但是后面补充了更多用例,发现本题的树是多叉树
    // const [val, left, right] = node;
    const val = node[0];
    matrix[level] ? matrix[level].push(val) : (matrix[level] = [val]);

    // 2023.1.16更新代码逻辑,之前本题只有用例1,因此误以为题目中的树指的是二叉树,因此错误意味一个节点最多只有两个子节点,但是后面补充了更多用例,发现本题的树是多叉树
    // dfs(nodes[left], level + 1);
    // dfs(nodes[right], level + 1);
    for (let i = 1; i < node.length; i++) {
      dfs(nodes[node[i]], level + 1);
    }
  }

  dfs(nodes[0], 0);

  if (matrix[tx] && matrix[tx][ty]) {
    return `{${matrix[tx][ty]}}`;
  } else {
    return "{}";
  }
}

Java算法源码

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class Main {
  static ArrayList<Integer[]> nodes;

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    int n = Integer.parseInt(sc.nextLine());

    nodes = new ArrayList<>();
    for (int i = 0; i < n; i++) {
      Integer[] node =
          Arrays.stream(sc.nextLine().split(" ")).map(Integer::parseInt).toArray(Integer[]::new);
      nodes.add(node);
    }

    int tx = sc.nextInt();
    int ty = sc.nextInt();

    System.out.println(getResult(nodes, tx, ty));
  }

  public static String getResult(ArrayList<Integer[]> nodes, int tx, int ty) {
    // 2023.03.17,尼玛,谁能想到还有tx,ty小于0的用例,题目描述一点没说
    if (tx < 0 || ty < 0) return "{}";

    ArrayList<ArrayList<Integer>> matrix = new ArrayList<>();
    dfs(matrix, nodes.get(0), 0);

    if (tx < matrix.size() && ty < matrix.get(tx).size()) {
      return "{" + matrix.get(tx).get(ty) + "}";
    } else {
      return "{}";
    }
  }

  public static void dfs(ArrayList<ArrayList<Integer>> matrix, Integer[] node, Integer level) {
    if (node == null) return;

    int val = node[0];

    if (level < matrix.size()) {
      matrix.get(level).add(val);
    } else {
      ArrayList<Integer> list = new ArrayList<>();
      list.add(val);
      matrix.add(list);
    }

    // 将二叉树处理逻辑,改成多叉树
    //    if (node.length > 1) {
    //      int left = node[1];
    //      dfs(matrix, nodes.get(left), level + 1);
    //    }
    //
    //    if (node.length > 2) {
    //      int right = node[2];
    //      dfs(matrix, nodes.get(right), level + 1);
    //    }

    for (int i = 1; i < node.length; i++) {
      int child = node[i];
      dfs(matrix, nodes.get(child), level + 1);
    }
  }
}

Python算法源码

# 输入获取
n = int(input())
nodes = [list(map(int, input().split())) for i in range(n)]
tx, ty = map(int, input().split())


# 算法入口
def getResult(nodes, tx, ty):
    if tx < 0 or ty < 0:
        return "{}"

    matrix = []
    dfs(matrix, nodes[0], 0)

    if tx < len(matrix) and ty < len(matrix[tx]):
        return "{" + str(matrix[tx][ty]) + "}"
    else:
        return "{}"


def dfs(matrix, node, level):
    if node is None:
        return

    val = node[0]

    if level < len(matrix):
        matrix[level].append(val)
    else:
        matrix.append([val])

    for i in range(1, len(node)):
        child = node[i]
        dfs(matrix, nodes[child], level + 1)


# 算法调用
print(getResult(nodes, tx, ty))

免责声明:

1、IT资源小站为非营利性网站,全站所有资料仅供网友个人学习使用,禁止商用
2、本站所有文档、视频、书籍等资料均由网友分享,本站只负责收集不承担任何技术及版权问题
3、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除下载链接并致以最深的歉意
4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
5、一经注册为本站会员,一律视为同意网站规定,本站管理员及版主有权禁止违规用户
6、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和IT资源小站的同意
7、IT资源小站管理员和版主有权不事先通知发贴者而删除本文

0

评论0

站点公告

没有账号?注册  忘记密码?