3、从头到尾打印链表
listNode 是链表,只能从头遍历到尾,但是输出却要求从尾到头,这是典型的"先进后出",我们可以想到栈!
ArrayList 中有个方法是 add(index,value),可以指定 index 位置插入 value 值
所以我们在遍历 listNode 的同时将每个遇到的值插入到 list 的 0 位置,最后输出 listNode 即可得到逆序链表
Listnode list = new Listnode();
那么list.val表示当前链表指针的值,list.next表示当前链表指针的下一个指针的地址
import java.util.*;
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> list = new ArrayList<>();
ListNode tmp = listNode;
while(tmp!=null){
list.add(0,tmp.val); //进栈
tmp = tmp.next;//出栈
}
return list;
}
}
递归
import java.util.*;
public class Solution {
ArrayList<Integer> list = new ArrayList();
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
if(listNode!=null){
printListFromTailToHead(listNode.next);
list.add(listNode.val);
}
return list;
}
}
python的异常简洁
class Solution:
def reversePrint(self, head: ListNode) -> List[int]:
resList = []
while head:
resList.append(head.val)
head = head.next
return resList[::-1]
14、链表中倒数第K个节点
快慢指针
import java.util.*;
public class Solution {
public ListNode FindKthToTail (ListNode pHead, int k) {
ListNode fast=pHead,slow=pHead;
for (int i=0;i<k;i++){
if(fast!=null){
fast=fast.next;
}
else{
return null;
}
}
while(fast!=null){
fast=fast.next;
slow=slow.next;
}
return slow;
}
}
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode p = head, q = head;
int num = 1;
while(num < k){
q = q.next;
num++;
}
while(q.next != null){
p = p.next;
q = q.next;
}
return p;
}
}
15、反转链表
要灵活认识到链表中 指针的概念------.next保存地址即指针
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;
}
}
递归
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; // 返回反转链表的头节点
}
}
16、合并两个排序的链表
初始化: 伪头节点 dumdum ,节点 curcur 指向 dumdum 。
ListNode list=new ListNode(0) 初始化一个节点值为0的空节点,最常用最正规写法
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dum = new ListNode(0), cur = dum;
while(l1 != null && l2 != null) {
if(l1.val < l2.val) {
cur.next = l1;
l1 = l1.next;
}
else {
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
}
cur.next = l1 != null ? l1 : l2;
return dum.next;
}
}