持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第23天,点击查看活动详情
反转链表
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
样例
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
解题思路
这题我的思路是用头插法,就是每次插入都是放在链表的头结点处,这样可以一边插入一边往后走,也不用维护其他的变量,非常适合这道题。操作步骤:
- 先构造一个新的头结点 myHead ,用来充当我们操作的载体,假设该头结点所对应的链表为 B,原链表为 A。
- 构造一个新节点 node,其值为链表 A 的头结点。
- 让 node.next 指向 myHead.next ,先把 myHead 的下一个节点进行保存,防止后面丢失。
- 让 myHead.next 指向 node,完成 node 节点的头插。
- 让 head 后移,重复步骤 2 - 5,直到 head 等于 null停止。
复杂度分析
时间复杂度:O(n),其中 n 是链表的长度。需要遍历链表一次。 空间复杂度:O(1)。
代码
Java代码:
class Solution {
public ListNode reverseList(ListNode head) {
// 这题用尾插法
ListNode myHead = new ListNode();
while (head != null) {
ListNode node = new ListNode(head.val);
// 别让链表断了
node.next = myHead.next;
myHead.next = node;
head = head.next;
}
// 我这里的头结点是空的,所以返回next
return myHead.next;
}
}
从尾到头打印链表
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
样例
输入:head = [1,3,2]
输出:[2,3,1]
解题思路
这题的话,我的思路是用两个数组来存,第一个数组存把链表里的数全部拿出来(顺便记个数),第二个数组就直接把第一个数组翻转过来就好了,这个思路对应我下面的代码,时间复杂度 O(n)。
还有就是可以用上面反转链表的方式,先把链表进行反转,再遍历该链表进行打印,这种方式的解题步骤和上面的反转链表是差不多的,但占用内存更少,时间复杂度也是 O(n)。
代码
这速度直接无敌,Java代码:
class Solution {
public int[] reversePrint(ListNode head) {
int[] list = new int[10000];
int count = 0;
while ( head != null ) {
list[count++] = head.val;
head = head.next;
}
int[] ans = new int[count];
for (int i=0;i<count;i++) {
ans[i] = list[count - i - 1];
}
return ans;
}
}