链表的反转
在做一些题的时候需要将链表进行反转。一般有两种方法,使用栈和插入法。
1.栈:由于栈的特点是元素先入后出,那么将链表的元素压栈后再弹出就得到了反序。
代码如下:
public ListNode ReverseList(ListNode head) {
Stack<ListNode> stack = new Stack<>();
//遍历链表元素,并将个元素压栈
while (head!=null){
stack.push(head);
head = head.next;
}
//判断是否是空表
if(stack.size()==0){
return null;
}
//记录第一个元素,头节点
head = stack.pop();//作为返回的元素,不动他了,后续处理就用另外temp变量来解决
ListNode temp = head;//这一步是应该注意的,我第一次写成了ListNode temp = head.next
//我想的是指向head的next,但是没用,因为头节点还没有处理完毕,他的next还没有赋值,需要指向头节点。
while (stack.size()!= 0){
temp.next = stack.pop();
temp = temp.next;
}
temp.next = null;
return head;
}
2.使用插入法,将后续出来的元素作为新的顺序链表的表头。如图
图片来源牛客网的题解。
说白了就是按顺序取出每一个元素,取出的元素作为新链表的表头。
代码如下:
public class Solution {
public ListNode ReverseList(ListNode head) {
//创建新表头,并且遍历链表元素表头都会更新为当前链表元素
ListNode newHead = null;
//使用ln指向表头
ListNode ln = head;
//遍历链表
while (ln!=null){
//首先保存下一个节点的值
ListNode temp = ln.next;
//将原表头插入到当前元素后面
ln.next = newHead;
//更新新表头为当前元素
newHead = ln;
//ln指向原链表中的下一个元素,继续遍历
ln = temp;
}
return newHead;
}
}
PS:虽然第二种方法看起来要短,但我更喜欢使用栈来做,因为思路清晰得多。