4、二叉树的垂序遍历(Weekly Contest 122)
题目描述:
写在前面
HashMap和LinkedHashMap了,HashMap不保证数据有序,LinkedHashMap保证数据可以保持插入顺序,而如果我们希望Map可以保持key的大小顺序的时候,我们就需要利用TreeMap了。
没考虑顺序,这道题没写出来,需要注意的是按照的是Y坐标递减,X轴坐标递增并且初始的坐标是(0,0),如果坐标相同,那么按照从小到大顺序进行加入,我这点没有考虑,最后就没写出来
这道题需要用到之前看到的那个Comparable接口来实现类排序,首先使用TreeMap对x进行增序排序,由于TreeMap本身就是增序的,因此无需进行操作,但是如果是降序的话,那么应该这么写,以Comparator实现匿名内部类,这样就是升序,默认是降序
Map<Integer, Integer> map = new TreeMap<>(
new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
// TODO 自动生成的方法存根
return o1.compareTo(o2);
}
});
map.put(1, 2);
map.put(2, 1);
map.put(0, 3);
for (Map.Entry<Integer, Integer> s : map.entrySet()) {
System.out.println(s.getKey());;
}
由于这里就是对x进行升序,因此无需进行操作,直接定义即可,以x作为键,以List作为值形成键值对,注意的是list中是新定义的一个类,其中就包括了y值和val,两个都需要进行排序,首先排序的是y值,y是增序,如果y值相同那么val就是升序,这样需要implements Comparator接口,或者是Comparatable
方法基本类似
代码:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
class Solution {
public List<List<Integer>> verticalTraversal(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if(root == null){
return result;
}
Map<Integer, List<mysorted>> tem = new TreeMap<>();
get(root,0,0,tem);
for (List<mysorted> list : tem.values()) {
Collections.sort(list);
List<Integer> x = new ArrayList<>();
for (mysorted mysorted : list) {
x.add(mysorted.val);
}
result.add(x);
}
System.out.println(tem.toString());
return result;
}
public void get(TreeNode tree,int x,int y,Map<Integer,List<mysorted>> result){
List<mysorted> tem = new ArrayList<>();
if(result.get(x)!= null){
tem = result.get(x);
}
tem.add(new mysorted(x, y, tree.val));
result.put(x,tem);
if(tree.left != null){
get(tree.left, x - 1,y - 1,result);
}
if(tree.right != null){
get(tree.right, x + 1,y - 1,result);
}
}
}
class mysorted implements Comparable<mysorted>{
int x;
int y;
int val;
public mysorted(int x, int y, int val) {
super();
this.x = x;
this.y = y;
this.val = val;
}
@Override
public int compareTo(mysorted o) {
if(o.x == x){
if(o.y == y){
//val进行排序,从小到达进行排序
return val - o.val;
}else {
//y是按照从大到小排列
return o.y - y;
}
}else {
//x按照从小到达进行排序
return x - o.x;
}
}
}
相同的思路,不过用的是TreeMap,就是上面说的,默认是递增的,因此无需进行操作,否则要有一个匿名内部类:
class Solution {
public List<List<Integer>> verticalTraversal(TreeNode root) {
SortedMap<Integer, List<Item>> map = new TreeMap<>();
mark(root, 0, 0, map);
List<List<Integer>> res = new ArrayList<>();
for (Map.Entry<Integer, List<Item>> entry : map.entrySet()) {
Collections.sort(entry.getValue());
List<Integer> list = new ArrayList<>();
for (Item item : entry.getValue()) {
list.add(item.val);
}
res.add(list);
}
return res;
}
public void mark(TreeNode node, int x, int y, SortedMap<Integer, List<Item>> map) {
if (node != null) {
if (!map.containsKey(x)) {
map.put(x, new ArrayList<>());
}
map.get(x).add(new Item(node.val, y));
mark(node.left, x - 1, y - 1, map);
mark(node.right, x + 1, y - 1, map);
}
}
class Item implements Comparable<Item> {
int val;
int y;
Item(int val, int y) {
this.val = val;
this.y = y;
}
@Override public int compareTo(Item o) {
if (o.y - y != 0) {
return o.y - y;
}
return val - o.val;
}
}
}