203. 移除链表元素https://leetcode-cn.com/problems/remove-linked-list-elements/
给你一个链表的头节点 head
和一个整数 val
,请你删除链表中所有满足 Node.val == val
的节点,并返回 新的头节点 。
对于头结点有两种处理方式:
1、直接使用原来的链表来进行删除操作。
移除头结点和移除其他节点的操作是不一样的,因为链表的其他节点都是通过前一个节点来移除当前节点,而头结点没有前一个节点。
所以对于头结点,需要单独写一段逻辑来处理移除头结点的情况。只要将头结点向后移动一位就可以,这样就从链表中移除了一个头结点。
2、设置一个虚拟头结点在进行删除操作。
可以设置一个虚拟头结点,这样原链表的所有节点就都可以按照统一的方式进行移除了
1、迭代
//设置哑节点
public ListNode removeElements2(ListNode head,int val){
if (head==null){
return head;
}
//设置哑节点
ListNode dummy=new ListNode(-1,head);
//指向前一个
ListNode pre=dummy;
//指向当前元素
ListNode cur=head;
while (cur!=null){
//如果相等
if(cur.val==val){
pre.next=cur.next;
}else {
pre=cur;
}
//不管相等与否 都要移动到下一元素
cur=cur.next;
}
return dummy.next;
}
//不设置哑节点
public ListNode removeElements(ListNode head,int val){
//先找到新链表的第一个结点
//为了防止空指针异常 需要判断是否为空
while (head!=null&&head.val==val){
head=head.next;
}
//可能全部为空 需要判断head是否为空再进行下一步
if (head==null){
return head;
}
//到此为止 head.val!=val 并且head!=null
ListNode pre=head;
ListNode cur=head.next;
while (cur!=null){
if(cur.val==val){
pre.next=cur.next;
}else {
pre=cur;
}
cur=cur.next;
}
return head;
}
2、递归
public ListNode removeElements(ListNode head,int val){
if(head==null){
return head;
}
head.next=removeElements(head.next,val);
return head.val==val?head.next:head;
}
206. 反转链表https://leetcode-cn.com/problems/reverse-linked-list/
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
1、双指针
//双指针
public ListNode reverseList1(ListNode head){
if(head==null){
return head;
}
//定义一个节点 指向操作元素之前
ListNode pre=null;
// 指向当前操作元素
ListNode cur=head;
//保存下一下节点
ListNode temp=null;
while (cur!=null){
temp=cur.next;
cur.next=pre;
pre=cur;
cur=temp;
}
// 此时cur为null
return pre;
}
2、递归
//递归
public ListNode reverseList(ListNode head){
// 边缘条件判断 考虑只有一个节点的特殊情况
if(head==null||head.next==null){
return head;
}
// 递归调用,翻转第二个节点开始往后的链表
ListNode last=reverseList(head.next);
// 翻转头节点与第二个节点的指向
head.next.next=head;
// 此时的 head 节点为尾节点,next 需要指向 NULL
head.next=null;
return last;
}