331. 验证二叉树的前序序列化
序列化二叉树的一种方法是使用前序遍历。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录,例如 #。
例如,上面的二叉树可以被序列化为字符串 “9,3,4,#,#,1,#,#,2,#,6,#,#”,其中 # 代表一个空节点。
给定一串以逗号分隔的序列,验证它是否是正确的二叉树的前序序列化。编写一个在不重构树的条件下的可行算法。
每个以逗号分隔的字符或为一个整数或为一个表示 null 指针的 ‘#’ 。
你可以认为输入格式总是有效的,例如它永远不会包含两个连续的逗号,比如 “1,3” 。
思路
在写的过程中想到了用栈,但是有个问题一直无法攻克:当pop掉一个结点的所有子结点之后,这个结点怎么处理。
看了题解,有以下两种方法:
1.出度和入度
2.用栈和前序遍历相结合,当pop掉两个##时候,再添加一个#。这个方法是最好的
完整代码
public boolean isValidSerialization(String preorder) {
String[] s = preorder.split(",");
Deque<String> stack = new ArrayDeque<>();
for(int i = 0; i < s.length; i++) {
String c = s[i];
while(stack.size() >= 2 && c.equals("#") && stack.peekLast().equals("#")) {
stack.removeLast();
if(stack.removeLast().equals("#")) {
return false;
}
}
stack.addLast(c);
}
return stack.peekLast().equals("#") && stack.size() == 1;
}
语法
- final
final类不能被继承,没有子类,final类中的方法默认是final的
final方法不能被子类的方法复盖,但可以被继承
final成员变量表示常量,只能被赋值一次,赋值后不能再被改变
final不能用于修饰构造方法
private不能被子类方法覆盖,private类型的方法默认是final类型的
final修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量。
注意:final变量定义的时候,可以先声明,而不给初值,这中变量也称为final空白,无论什么情况,编译器都确保空白final在使用之前必须被初始化。
- static
static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念。
被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。
用public修饰的static成员变量和成员方法本质是全局变量和全局方法,当声明它类的对象市,不生成static变量的副本,而是类的所有实例共享同一个static变量。
- 类成员变量
- 静态变量(类变量): static修饰
- 实例变量 : 无static修饰
- 局部变量
- static和final一起使用
static final用来修饰成员变量和成员方法,可以理解为“全局变量”
对于变量,表示一旦给值就不可修改,并且通过类名可以访问。
对于方法,表示不可覆盖,并且可以通过类名直接访问。
注意:
对于被static和final修饰过的实例常量,实例本身不能再改变了,但对于一些容器类型(比如,ArrayList、HashMap)的实例变量,不可以改变容器变量本身,但可以修改容器中存放的对象。
转自:http://blog.csdn.net/qq1623267754/article/details/36190715
错误
在通过的时候,发现if(it.next() == key) 是会报空的,之前在条件中带有.size()也是结果不对
完整代码
class MyHashSet {
private LinkedList[] list;//用数组索引代表hash值
private static final int BASE = 769;//表示全局不可变
private int hash(int a) {
return a % BASE;
}
/** Initialize your data structure here. */
public MyHashSet() {
list = new LinkedList[BASE];
for(int i = 0; i < BASE; i++) {//初始化
list[i] = new LinkedList<Integer>();
}
}
//因为涉及到了集合的增删改查
//所以要使用迭代器
public void add(int key) {
int h = hash(key);
Iterator<Integer> it = list[h].iterator();
while(it.hasNext()) {
Integer e = it.next();
if(e == key) {
return;
}
}
list[h].addLast(key);
}
public void remove(int key) {
int h = hash(key);
Iterator<Integer> it = list[h].iterator();
while(it.hasNext()) {
Integer e = it.next();
if(e == key) {
list[h].remove(e);
return;
}
}
}
/** Returns true if this set contains the specified element */
public boolean contains(int key) {
int h = hash(key);
Iterator<Integer> it = list[h].iterator();
while(it.hasNext()) {
Integer e = it.next();
if(e == key) {
return true;
}
}
return false;
}
}