19. 删除链表的倒数第 N 个结点
判断只有1个结点的特殊情况
p,q指向head
for q移动n次
if q为空:
说明删除的是首结点,返回head.next
while q.next!=null:
p和q后移
while结束时,p移到了删除节点的上一个
删除p的下一个结点
上面的思路中,p和q是从head开始的,所以会出现当删除倒数第 len 个节点时(意味着首节点),q此时为空,还得单独特殊判断。所以,让p和q从dummyHead开始。
p,q,start指向dummyHead
q移动n次
while q.next!=null:
p和q后移
删除p的下一个结点
返回start.next
144. 二叉树的遍历(迭代)
前序遍历
stack加入root
while stack不空:
出栈结点tmp,值加入res
入栈右节点(非空) tmp.right
入栈左节点 tmp.left
中序遍历
迭代的解法有点复杂,所以能想到的是怎么更好的记住思路。
抽象出来的循环,依然是针对每个子树抽象出来的。主要是三步:
while stack非空 || cur !=null(这个条件是处理开始时stack为空的)
1. 用cur记录该子树的根,对于每棵新子树,
首先要把根和 从根到最左边这条路径上的所有结点都入栈,然后cur==null停止压栈。
(这一步,cur==null时则无需进行,只是处理每个新子树第一步要做的事情)
2. 弹出栈顶,记录值,此时的值,第一次是“最左的结点”,
后面根据不同的情况,代表了左、中、右结点
3. 判断弹出的结点,有没有右结点
如果有,则cur指向它的右节点,即下一个循环处理新的一棵子树。
后序遍历
思路有点巧妙
,前序遍历是 根左右,先转成 根右左,再倒一下就变成了 左右根,也就是需要的后序遍历了。怎么倒过来呢?那就是把 变形的前序遍历 结果放入到 stack 2 中,再把栈2的值取出来就行了。
stack1 加root
while stack1 非空:
stack1 取出来加入 stack2
if 左非空,左压栈
if 右非空,右压栈
while stack2 非空:
stack2 循环出栈
143. 重排链表
最简单的思路
创建一个List存放所有的node
双指针 i=0,j=size-1
while i<j:
list.get(i)的next连接上list.get(j)
i++
list.get(j)的next连接上list.get(i)
j--
最后list.get(i).next=null
递归的思路