209移除元素:
给你一个链表的头节点 head
和一个整数 val
,请你删除链表中所有满足 Node.val == val
的节点,并返回 新的头节点 。
示例 1:
输入:head = [1,2,6,3,4,5,6], val = 6 输出:[1,2,3,4,5]
示例 2:
输入:head = [], val = 1 输出:[]
示例 3:
输入:head = [7,7,7,7], val = 7 输出:[]
分析:主要是对于虚拟头节点的使用;
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
//删除链表中符合目标值的元素
public ListNode removeElements(ListNode head, int val) {
//设置虚拟头节点;虚拟头节点的下一个元素指向head
ListNode dummyHead = new ListNode(-1, head);
//设置当前节点;
ListNode cur=dummyHead;
while (cur.next !=null){
if (cur.next.val == val) {
cur.next = cur.next.next;//删除节点元素;
}else{//如果cur不是目标值,就继续往下移动元素;
cur=cur.next;
}
}
return dummyHead.next;
}
}
206:翻转链表:
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
示例 1:
输入:head = [1,2,3,4,5] 输出:[5,4,3,2,1]
示例 2:
输入:head = [1,2] 输出:[2,1]
示例 3:
输入:head = [] 输出:[]
双指针的解法:
-
初始化:cur指向head,pre为cur的前一个元素并且为null;
-
然后使用一个临时指针指向cur.next;tempNode用于保留cur.next。然后改变cur的指向,cur.next指向pre;
-
最后:pre 前移到cur;cur前移到tempNode。
-
循环终止的条件是cur节点不为空的情况下;
class Solution {
public ListNode reverseList(ListNode head){
ListNode cur = new ListNode();
cur=head;//cur指向头指针
ListNode pre=null;//pre是cur的前一个节点,指向空;
while (cur !=null){//循环终止条件;
ListNode tempNode=cur.next;//tempNode 用于保存cur.next节点;
cur.next=pre;//翻转指向;
pre=cur;//pre向前移动一位;
cur=tempNode;//cur前移一位
}
return pre;
}
}
递归的解法:与双指针的思路相同;注意递归出口:cur ==null ;直接返回pre;
class Solution {
public ListNode reverseList(ListNode head){
return reverse(head,null);//初始化pre 和cur
}
public ListNode reverse(ListNode cur,ListNode pre){
if(cur==null){
return pre;//递归终止条件;
}
ListNode tempNode=cur.next;
cur.next=pre;
return reverse(tempNode,cur);//递归到下一层;
}
}