203 删除所有值为val的节点 Easy
m18 删除链表中值为val的节点,链表元素不重复 Easy
83 删除排序链表中的重复元素,重复只保留一个 Easy
82 删除排序链表中的重复元素,重复的都删掉 Medium
m2 删除排序链表中的重复元素,重复只保留一个 Easy
203 删除所有值为val的节点
【题目】
【分析】
cur用来遍历链表。
当cur值不为val时,p.next = cur, p = p.next;
【代码】
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode removeElements(ListNode head, int val) { //head是第一个节点。head.val是第一个节点的值。
if(head == null) return head;
ListNode Head = new ListNode(-1); //虚拟头节点Head
ListNode p = Head;
ListNode cur = head; //用于遍历链表
while(cur!=null){
if(cur.val != val){
p.next = cur;
p = p.next;
}
cur = cur.next;
}
p.next = null;
return Head.next;
}
}
结果:
m18 删除链表中值为val的节点,链表元素不重复
【题目】
【分析】
链表元素不重复,所以只要找到它的前一个节点就大功告成了。
特殊情况就是要找的节点是第一个节点的情况。
【代码】
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteNode(ListNode head, int val) {
if(head.val == val) return head.next; //特殊情况,当删除的是第一个节点时
ListNode p=head;
while(p.next !=null){
if(p.next.val == val){ //找到之后,删除即可
p.next = p.next.next;
break;
}
p = p.next;
}
return head;
}
}
结果:
83 删除排序链表中的重复元素,重复只保留一个
【题目】
【分析】
尾插法重新建立一个链表。
用p遍历链表。当p.val != tail.val时,把p插入到新链表中。
【代码】
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if(head==null) return null;
ListNode tail = head; //新链表,尾指针
ListNode p=head.next; //用来遍历链表
while(p!=null){
if(p.val != tail.val){
tail.next = p;
tail=p;
}
p=p.next;
}
tail.next=null;
return head;
}
}
结果:
82 删除排序链表中的重复元素,重复的都删掉
【题目】
【方法一】
对于每一个节点,什么是不重复?
对于非尾节点: p的值不等于前一个节点的值 && p的值不等于后一个节点的值
对于尾节点: p的值不等于前一个节点的值
即:
(p!=p.front.val && p==null) || (p!=p.front.val && p!=p.next.val )
合起来为:
p !=p.front.val && (p==null || p!=p.next.val)
怎么知道前面节点的值呢?用一个变量front记录下来。front初始化为head.val-1,这样就肯定不影响head的重复性了。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if(head==null || head.next==null) return head;
ListNode Head = new ListNode(-1);
ListNode tail = Head;
ListNode p = head; //p遍历链表
int front=head.val-1; //front用来记录p的前一个节点的值
while(p!=null){
if(p.val != front && (p.next==null || p.val != p.next.val)){ //p不重复
tail.next = p;
tail = p;
}
front = p.val; //记录p的值
p = p.next;
}
tail.next = null;
return Head.next;
}
}
结果:
【方法二】
比如,1->2->2->…->2->3->3->…->3->4->5
使用p遍历链表。
(1)一旦发现p.val = p.next.val,说明它是一个重复的节点。
接下来就把所有的2都跳过去。
int tmp = p.val;
while( p!=null && p.val==tmp){
p = p.next;
}
(2)如果p.val !=p.next.val,说明不重复。加到新链表中。
代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if(head==null || head.next==null) return head;
ListNode Head = new ListNode(-1);
ListNode tail = Head;
ListNode p = head;
while(p!=null){ //遍历前n-1个节点
if(p.next!=null && p.val == p.next.val){ //发现了重复的元素,就把重复的都跳过去
int tmp = p.val;
while(p!=null && p.val == tmp){
p= p.next;
}
}else{ //元素唯一,就加到新链表中
tail.next = p;
tail = p;
p = p.next;
}
}
tail.next = null;
return Head.next;
}
}
结果:
m2 删除排序链表中的重复元素,重复只保留一个
【题目】
【分析】
搞一个数组记录一下,有没有出现过就好了。
【代码】
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode removeDuplicateNodes(ListNode head) {
if(head==null) return null;
int[] flag = new int[20001]; //记录val是否出现过
ListNode Head = new ListNode(-1);
ListNode tail=Head;
ListNode p = head;
while(p != null){
if(flag[p.val]==0){ //若之前没出现过
flag[p.val]=1;
tail.next = p;
tail = p;
}
p = p.next;
}
tail.next = null;
return Head.next;
}
}
结果: