题目1:在O(1)时间内删除链表节点
给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间内删除该节点。
思路:
如果直接从头节点遍历,找到待删节点n的上一节点,然后将上一节点的下节点设为n的下节点,即可删除n,但此方法时间复杂度为O(n)。
实际上,完成该操作不一定需要节点n的上一节点,我们把n的下一节点的值赋给n,再将n的下一节点设为下下节点即可。需要考虑的特殊情况是n不存在下一节点,此时就只能遍历了。
public class Solution {
//l1为头结点,l2为待删节点
public void DeleteNode(ListNode l1,ListNode l2){
if (l1.next==null||l2==null) {
l1=null;
return;
}
if (l2.next==null){
ListNode anode = l1;
while (anode.next!=l2){
anode=anode.next;
}
anode.next=null;
}else {
ListNode l3 = l2.next;
l2.val=l3.val;
l2.next=l3.next;
}
}
题目2:删除链表中的重复节点
在一个排序的链表中,如何删除重复的节点?
例 列表 1->2->3->3->5,删除重复列表后,结果为1->2->5
思路:
因为是排序列表,所以重复节点相连。当当前节点值与下一节点相同时,判断后续是否还有重复节点,一块删除。当两值不同,则考虑下一节点。本体可以使用递归解决,也可以设立变量存储当前值,循环解决。
public class Solution {
//递归方式
public static ListNode deleteDuplication_1(ListNode pHead) {
// 递归停止条件
if (pHead == null || pHead.next == null)
return pHead;
ListNode current = pHead.next;
// 如果pHead是重复元素
if (pHead.val == current.val) {
current = current.next;
while (current != null && current.val == pHead.val)
current = current.next;
//pHead = current;
return deleteDuplication_1(current);
} else {
// pHead不是重复元素
pHead.next = deleteDuplication_1(current);
return pHead;
}
}
//循环方式
public static ListNode deleteDeplication(ListNode pHead){
if (pHead==null){
return pHead;
}
ListNode first = new ListNode(-1);
first.next = pHead;
ListNode Node = pHead;
ListNode prenode = first;
while (Node!=null&&Node.next!=null){
if (Node.val==Node.next.val){
int val = Node.val;
while (Node!=null&&Node.val==val){
Node=Node.next;
}
prenode.next=Node;
}
else {
prenode = Node;
Node=Node.next;
}
}
return first.next;
}
}