一、LeetCode 203:给你一个链表的头节点head和一个整数val,请你删除链表中所有满足Node.val== val的节点,并返回新的头节点。
int[] a = {4, 4, 5, 1, 9, 9};
removeElements(nodeA, 9);
代码:
public static ListNode removeElements(ListNode head, int val) {
ListNode dummyHead =new ListNode(0);
dummyHead.next = head;
ListNode temp = dummyHead;
while(temp.next != null) {
if (temp.next.val == val) {
temp.next = temp.next.next;
}else{
temp = temp.next;
}
}
return dummyHead.next;
}
画图分析:
初始状态
前面都没9,往后走,都这停
进入while,开始处理,删除两个9
最后完成
二、LeetCode 19.删除链表的倒数第N个节点
int[] a = {4, 4, 5, 1, 9, 9};
result = removeNthFromEndByLength(nodeA, 3);
方法1:首先从头节点开始对链表进行一次遍历,得到链表的长度L。随后我们再从头节点开始对链表进行一次遍历,当遍历到第L-n+1个节点时,它就是我们需要删除的节点。代码如下:
public static ListNode removeNthFromEndByLength(ListNode head, int n) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode cur = dummy;
int length = getLength(head);
for (int i = 1;i < length-n+1;i++) {
cur = cur.next;
}
cur.next = cur.next.next;
ListNode ans = dummy.next;
return ans;
}
public static int getLength(ListNode head) {
int length = 0;
while (head.next != null) {
length++;
head = head.next;
}
return length;
}
画图分析:
初始状态
i从1开始,i<6-3+1=4结束
i = 1
i = 2
i =3
for运算结束,cur的下一个节点就是要删的,最后从头遍历就行
方法二:双指针。我们定义first和second两个指针,first先走N步,然后second再开始走,当first走到队尾的时候,second就是我们要的节点。代码如下:
public static ListNode removeNthFromEndByTwoPoints(ListNode head, int n) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode first = head;
ListNode second = dummy;
for (int i =0; i<n ; i++) {
first = first.next;
}
while (first != null){
first = first.next;
second = second.next;
}
second.next = second.next.next;
ListNode ans = dummy.next;
return ans;
}
画图分析:
初始状态
for循环后:
while后,找到要删的前一个节点,完成删除
三、LeetCode 83存在一个按升序排列的链表,请你删除所有重复的元素,使每个元素只出现一次。
int[] a = {1, 2, 3, 3, 4, 4, 5};
public static ListNode deleteDuplicate(ListNode head) {
if (head == null){
return head;
}
ListNode cur = head;
while (cur.next != null){
if (cur.val == cur.next.val){
cur.next = cur.next.next;
}else {
cur = cur.next;
}
}
return head;
}
画图分析:
初始状态:
cur走一步后,删除一个3.
往后走,删除一个4,完成
四、LeetCode 82存在一个按升序排列的链表,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中没有重复出现的数字。
public static ListNode deleteDuplicates(ListNode head) {
if (head == null) {
return head;
}
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode cur = dummy;
while (cur.next != null && cur.next.next !=null) {
if (cur.next.val == cur.next.next.val){
int x = cur.next.val;
while(cur.next != null && cur.next.val == x){
cur.next = cur.next.next;
}
}else {
cur = cur.next;
}
}
return dummy.next;
}
画图分析:
初始状态:
cur走二步, 发现2个3,此时令x=3,后面的3全会被忽略。
此时cur下面的4又有2个,也要删除。删除完,第一个while的条件已不满足,结束
总结:删除的核心:cur.next = cur.next.next。所以题都要主要循环的条件,仔细调试。