目录
19.删除链表的倒数第N个节点
删除链表的倒数第N个节点
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
双指针:
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
if(head == null){
return null;
}
ListNode pre = new ListNode(0);
pre.next = head;
ListNode start = pre,end = pre;
while(n != 0){
start = start.next;
n--;
}
while(start.next != null){
start = start.next;
end = end.next;
}
end.next = end.next.next;
return pre.next;
}
}
# 203. 移除链表元素
删除链表中等于给定值 val 的所有节点。
示例:
输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5
class Solution {
public ListNode removeElements(ListNode head, int val) {
if(head == null){
return null;
}
ListNode pre = new ListNode(0);
pre.next = head;
while(pre.next != null){
if(pre.next.val == val){
pre.next = pre.next.next;
}else{
pre = pre.next;
}
}
return pre;
}
}
82. 删除排序链表中的重复元素 II
给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。
示例 1:
输入: 1->2->3->3->4->4->5
输出: 1->2->5
示例 2:
输入: 1->1->1->2->3
输出: 2->3
这里我们使用双指针的方式,定义a,b两个指针。
考虑到一些边界条件,比如1->1->1->2这种情况,需要把开头的几个1给去掉,我们增加一个哑结点,方便边界处理。
初始的两个指针如下:
将a指针指向哑结点
将b指针指向head(哑结点的下一个节点)
如果a指向的值不等于b指向的值,则两个指针都前进一位
否则,就单独移动b,b不断往前走,直到a指向的值不等于b指向的值。
注意,这里不是直接比较a.val==b.val,这么比较不对,因为初始的时候,a指向的是哑结点,所以比较逻辑应该是这样:
a.next.val == b.next.val
当两个指针指向的值相等时,b不断往前移动,这里是通过一个while循环判断的,因为要过滤掉1->2->2->2->3重复的2。
那么整个逻辑就是两个while,但时间复杂度不是O(N^2),而是O(N),空间上也只是常数级别。
class Solution_82 {
//递归版本,删除链表的节点
/*
public ListNode deleteDuplicates(ListNode head) {
if (head == null ||head.next == null)
return head;
if (head.val == head.next.val){
while(head.next != null && head.val == head.next.val){
head = head.next;
}
return deleteDuplicates(head.next);
}else {
head.next = deleteDuplicates(head.next);
return head;
}
}
*/
public ListNode deleteDuplicates(ListNode head) {
if(head==null || head.next==null) {
return head;
}
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode a = dummy;
ListNode b = head;
while(b!=null && b.next!=null) {
//初始化的时a指向的是哑结点,所以比较逻辑应该是a的下一个节点和b的下一个节点
if(a.next.val!=b.next.val) {
a = a.next;
b = b.next;
}else {
//如果a、b指向的节点值相等,就不断移动b,直到a、b指向的值不相等
while(b!=null && b.next!=null && a.next.val==b.next.val) {
b = b.next;
}
a.next = b.next;
b = b.next;
}
}
return dummy.next;
}
}
83. 删除排序链表中的重复元素
给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
示例 1:
输入: 1->1->2
输出: 1->2
示例 2:
输入: 1->1->2->3->3
输出: 1->2->3
public ListNode deleteDuplicates(ListNode head) {
ListNode current = head;
while (current != null && current.next != null) {
if (current.next.val == current.val) {
current.next = current.next.next;
} else {
current = current.next;
}
}
return head;
}
138 .复制带随机指针的链表
138 .