今天遇到了一个算法题,具体的描述我已经忘了,但是大概是这么个意思,输入是三个数组,当然数组的个数是不固定的,数组的长度也是不固定的,举个例子,比如:
a=[1,2]
b=[1,2]
c=[5]
输出是
[1,1,5]
[1,2,5]
[2,1,5]
[2,2,5]
乍一看好像看不出规律,但是其实就是从上往下看,然后依次去遍历,这个题就让我想到了把这三个数组构建一个树,然后把数字作为树的节点,输出的时候全遍历输出就可以了,大概思路就是下面这个图
上面的想法很简单,但是实现起来却让我有点捉急,因为这段时间一直在写一些python的东西,对算法这块的知识都忘了好的,比如二叉树的构建或者遍历,以及这种简单的数据结构,都快写不出来了,无奈,只好去网上找了一些,才勉勉强强把这个算法写出来,代码写得比较仓促,所以命名和格式化都比较粗糙,而且借鉴了这个博客的不少代码哈哈哈,因为自己已经快忘了怎么写了。。
首先需要构建一个TreeNode类用来存放数据
package com.test.letcode;
import java.util.List;
public class TreeNode {
private String id;
private String parentId;
private String name;
private List<TreeNode> children;
public TreeNode(String id, String name, String parentId) {
this.id = id;
this.parentId = parentId;
this.name = name;
}
public TreeNode(String id, String name, TreeNode parent) {
this.id = id;
this.parentId = parent.getId();
this.name = name;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<TreeNode> getChildren() {
return children;
}
public void setChildren(List<TreeNode> children) {
this.children = children;
}
@Override
public String toString() {
return "TreeNode{" +
"id='" + id + '\'' +
", parentId='" + parentId + '\'' +
", name='" + name + '\'' +
", children=" + children +
'}';
}
}
接着就是进行树的数据存储和树的遍历的类TreeBuilder
package com.test.letcode;
import java.util.ArrayList;
import java.util.List;
public class TreeBuilder {
/**
* 使用递归方法建树
*
* @param treeNodes
* @return 树集合
*/
public static List<TreeNode> buildByRecursive(List<TreeNode> treeNodes) {
List<TreeNode> trees = new ArrayList<TreeNode>();
for (TreeNode treeNode : treeNodes) {
if ("0".equals(treeNode.getParentId())) {
trees.add(findChildren(treeNode, treeNodes));
}
}
return trees;
}
/**
* 递归查找子节点
*
* @param treeNodes
* @return
*/
public static TreeNode findChildren(TreeNode treeNode, List<TreeNode> treeNodes) {
for (TreeNode it : treeNodes) {
if (treeNode.getId().equals(it.getParentId())) {
if (treeNode.getChildren() == null) {
treeNode.setChildren(new ArrayList<TreeNode>());
}
treeNode.getChildren().add(findChildren(it, treeNodes));
}
}
return treeNode;
}
public static void showTrees(List<TreeNode> trees, List<String> vals) {
for (TreeNode tree : trees) {
vals.add(tree.getName());
List<TreeNode> child = tree.getChildren();
if (child != null) {
showTrees(child, vals);
} else {
vals.forEach(System.out::println);
String first = vals.get(0);
vals.clear();
vals.add(first);
System.out.println("-----------");
}
}
}
public static void main(String[] args) {
String[] a = {"1", "2"};
String[] b = {"1", "2"};
String[] c = {"5"};
List<TreeNode> list = new ArrayList<TreeNode>();
int num = 0;
for (String s : a) {
num++;
TreeNode treeNode = new TreeNode(String.valueOf(num), s, "0");
list.add(treeNode);
for (String value : b) {
num++;
TreeNode treeNode1 = new TreeNode(String.valueOf(num), value, treeNode);
list.add(treeNode1);
for (String item : c) {
num++;
TreeNode treeNode2 = new TreeNode(String.valueOf(num), item, treeNode1);
list.add(treeNode2);
}
}
}
List<TreeNode> trees = TreeBuilder.buildByRecursive(list);
for (TreeNode tree : trees) {
List<String> vals = new ArrayList<>();
vals.add(tree.getName());
showTrees(tree.getChildren(), vals);
}
}
}
最终的输出结果
后面如果需要进行多个数组不定长度的输出,只是在for循环那块进行修改就行,改成迭代就能实现了
总结
我自从2019年进入了软通的外包,发现自己的很多技能都已经退步了,最近刷letcode的题也发现,自己之前会的或者可以直接秒的题,都已经刷不出来了。。。可见我这一年是有多混。。只不是在外包学到了一些项目开发的东西和代码的编码规范,让我写出来的代码最起码能够看了,当然今天的代码除外,但是还是提醒了我,干这一行,如果不随时随地的去学习和进步,迟早要被资本家所淘汰。。