从头到尾打印链表
题目描述:
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
示例一:
输入:head = [1,3,2] 输出:[2,3,1]
借助栈实现,代码如下:
Java实现:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public int[] reversePrint(ListNode head) {
Stack<ListNode> stack = new Stack<ListNode>();
ListNode temp = head;
//将链表的结点一个个存入栈中
while(temp!=null){
stack.push(temp);
temp = temp.next;
}
//取出的顺序正好是倒序的
int size = stack.size();
int[] res = new int[size];
for(int i = 0;i<size;i++){
res[i] = stack.pop().val;
}
return res;
}
}
反转链表;同LeeDCode206
题目描述:
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例一:
输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
自己的想法:实现的方式跟上面那道题相似,都是借助栈的先进后出原理来实现
Java实现:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
if(head==null) return head;
Stack<ListNode> stack = new Stack<ListNode>();
ListNode temp = head;
//将链表的结点一个个存入栈中
while(temp!=null){
stack.push(temp);
temp = temp.next;
}
ListNode resHead = stack.pop();
ListNode tailNode = resHead;
while(!stack.isEmpty()){
ListNode tt = stack.pop();
tailNode.next = tt;
tailNode = tt; //这个地方的tailNode一定要后移,很容易出错
}
tailNode.next = null;
return resHead;
}
}
官方解法:(源自力扣官方)
图解算法数据结构 - LeetBook - 力扣(LeetCode)全球极客挚爱的技术成长平台
解法一:迭代(双指针)
1. 初始化pre,cur分别指向null和头结点
2. 暂存后继节点,修改引用指向
tmp = cur.next; //暂存后继节点
cur.next = pre; //修改引用指向
3. 暂存当前节点,访问下一节点
pre = cur; //暂存当前节点
cur = tmp; //访问下一节点
4. 这样循环遍历完整个链表之后就能生成以pre作为头结点的反转链表
Java实现:
class Solution {
public ListNode reverseList(ListNode head) {
ListNode cur = head, pre = null;
while(cur != null) {
ListNode tmp = cur.next; // 暂存后继节点 cur.next
cur.next = pre; // 修改 next 引用指向
pre = cur; // pre 暂存 cur
cur = tmp; // cur 访问下一节点
}
return pre;
}
}
复杂度分析:
- 时间复杂度O(N):遍历链表使用线性大小空间
- 空间复杂度O(1):变量pre和cur使用常数大小额外空间
解法二:递归
1. recur(cur,pre)递归函数
- 终止条件:当
cur
为空,则返回尾节点pre
(即反转链表的头节点); - 递归后继节点,记录返回值(即反转链表的头节点)为
res
; - 修改当前节点
cur
引用指向前驱节点pre
; - 返回反转链表的头结点res
2. reverseList(head)函数
- 调用并返回
recur(head, null)
。传入null
是因为反转链表后,head
节点指向null
class Solution {
public ListNode reverseList(ListNode head) {
return recur(head, null); // 调用递归并返回
}
private ListNode recur(ListNode cur, ListNode pre) {
if (cur == null) return pre; // 终止条件
ListNode res = recur(cur.next, cur); // 递归后继节点
cur.next = pre; // 修改节点引用指向
return res; // 返回反转链表的头节点
}
}