在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表 1->2->3->3->4->4->5 处理后为 1->2->5
数据范围:链表长度满足
,链表中的值满足 
进阶:空间复杂度
,时间复杂度 %20%5C)
例如输入{1,2,3,3,4,4,5}时,对应的输出为{1,2,5},对应的输入输出链表如下图所示:
{1,2,3,3,4,4,5}{1,2,5}{1,1,1,8}{8}
# -*- coding:utf-8 -*- ''' 题目:在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5 ''' class ListNode: def __init__(self, x): self.val = x self.next = None class Solution: def deleteDuplication(self, pHead): # write code here if pHead == None or pHead.next == None: return pHead new_head = ListNode(-1) new_head.next = pHead pre = new_head p = pHead nex = None while p != None and p.next != None: nex = p.next if p.val == nex.val: while nex != None and nex.val == p.val: nex = nex.next pre.next = nex p = nex else: pre = p p = p.next return new_head.next
class Solution:
def deleteDuplication(self, pHead):
if not pHead or not pHead.next:
return pHead
if pHead.val == pHead.next.val:
temp = pHead.next
while temp and temp.val == pHead.val:
temp = temp.next
return self.deleteDuplication(temp)
else:
pHead.next = self.deleteDuplication(pHead.next)
return pHead
public ListNode deleteDuplication(ListNode pHead){
if(pHead == null){
return null;
}
if(pHead.next == null){
return pHead;
}
//两个循环,用来应付“1-1-2-2-3-3-4-5…”格式的连续重复结点
while(pHead != null && pHead.next != null && pHead.val == pHead.next.val){
while(pHead != null && pHead.next != null && pHead.val == pHead.next.val){
pHead = pHead.next;
}
pHead = pHead.next;
}
if(pHead!=null ){
pHead.next = deleteDuplication(pHead.next);
}
return pHead;
}
/*
*因为需要删除重复的节点,所以需要保留一个待删除节点之前的节点,这里用一个指针pre来
*表示,另外再用一个指针p指向正在遍历的节点。当头节点与后续节点数值相等时,需要特殊
*处理。方法比较简单,就是注意不要出现NULL->next,引起系统报错。
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if (pHead == NULL)
return NULL;
ListNode *pre = NULL;
ListNode *p = pHead;
int flag = 0; //判断是否出现重复节点,当flag==1时,当前节点出现重复
while (p)
{
while (p->next && p->val == p->next->val) //如果节点重复,一直遍历下去
{
flag = 1;
p = p->next;
}
if (flag == 0) //如果当前节点不重复,遍历下一个节点
{
pre = p;
p = p->next;
}
else //如果当前节点重复,分类处理
{
flag = 0;
if (pre == NULL) //如果从头结点开始出现重复,重置头结点指针
{
pHead = p->next;
p = pHead;
}
else //否则,跳过重复的节点
{
pre->next = p->next;
p = pre->next;
}
}
}
return pHead;
}
}; public class Solution {
public ListNode deleteDuplication(ListNode pHead)
{
if(pHead==null)return null;
ListNode preNode = null;
ListNode node = pHead;
while(node!=null){
ListNode nextNode = node.next;
boolean needDelete = false;
if(nextNode!=null&&nextNode.val==node.val){
needDelete = true;
}
if(!needDelete){
preNode = node;
node = node.next;
}
else{
int value = node.val;
ListNode toBeDel = node;
while(toBeDel!=null&&toBeDel.val == value){
nextNode = toBeDel.next;
toBeDel = nextNode;
if(preNode==null)
pHead = nextNode;
else
preNode.next = nextNode;
node = nextNode;
}
}
}
return pHead;
}
}
class Solution: def deleteDuplication(self, pHead): head = ListNode(None) head.next = pHead p = head q = pHead # 输入为空 if not q: return None # 循环整个链表 while q.next: # 当 q 不等于 r 时 if q.val != q.next.val: # p 与 q 不相连,说明有重复 if q != p.next: p.next = q.next # p 与 q 相连,不处理,继续移动 p else: p = q q = q.next # 判断链表结尾是重复的问题 if q != p.next: p.next = q.next return head.next
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
ListNode* p=pHead;
if(!p||!p->next) return pHead;
ListNode* pre=NULL;
bool check = false;
while(p){
while(p->next&&p->val==p->next->val){
p = p->next;
check = true;
}
if(check){
if(pre) pre->next = p->next;
else pHead = p->next;
check = false;
}
else{
pre = p;
}
if(p){
p = p->next;
}
}
return pHead;
}
}; //Java版递归
public ListNode deleteDuplication(ListNode pHead) {
if (pHead == null) return null;
if (pHead.next == null) return pHead;
ListNode cur;
//对重复结点的处理
if (pHead.val == pHead.next.val) {
cur = pHead.next.next;
//遍历到没有重复结点的位置
while (cur != null && cur.val == pHead.val) {
cur = cur.next;
}
return deleteDuplication(cur);
}
//该结点不重复,递归下一个结点
cur = pHead.next;
pHead.next = deleteDuplication(cur);
return pHead;
}
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if(pHead==0) return 0;
map<int,int> m;
ListNode* p=pHead;
while(p!=0)
{
m[p->val]++;
p=p->next;
}
//判断head
while(m[pHead->val]>1)
{
pHead=pHead->next;
if(pHead==0) return 0;
}
ListNode* p1=pHead;
ListNode* p2=pHead->next;
while(p2!=0)
{
if(m[p2->val]>1)
{
p2=p2->next;
p1->next=p2;
}
else
{
p2=p2->next;
p1=p1->next;
}
}
return pHead;
}
};
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
*/
import java.util.HashMap;
public class Solution {
public ListNode deleteDuplication(ListNode pHead)
{
if(pHead==null || pHead.next==null)
return pHead;
ListNode list=new ListNode(-1);
ListNode demo=list;
ListNode p=pHead;
ListNode q=null;
while(p!=null){
int value=p.val;
q=p;
if((q.next!=null) && (value==q.next.val)){
while((q.next!=null)&&(value==q.next.val)){
q=q.next;
}
p=q.next;
}else{
ListNode newnode=new ListNode(p.val);
demo.next=newnode;
demo=demo.next;
p=p.next;
}
}
return list.next;
}
}
typedef ListNode node;
typedef node* pode;
class Solution {
public:
ListNode* deleteDuplication(ListNode* p){
node h(0x23333), *q = &h, *tmp;
int cnt;
while(p){
tmp = p; p = p -> next; cnt = 0;
while(p && p -> val == tmp -> val) p = p -> next, ++cnt;
if(!cnt) q -> next = tmp, q = tmp;
}
q -> next = NULL;
return h.next;
}
};
typedef ListNode node;
typedef node* pode;
class Solution {
public:
ListNode* deleteDuplication(ListNode* p){
node h(0x23333), *q = &h;
while(p){
while(p && p -> next && p -> next -> val == p -> val){
while(p -> next && p -> next -> val == p -> val) p = p -> next;
p = p -> next;
}
if(!p) break;
q -> next = p; q = p; p = p -> next;
}
q -> next = NULL;
return h.next;
}
};
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
*/
/*
算法思想:方法一,递归实现。
public class Solution {
public ListNode deleteDuplication(ListNode pHead)
{
if(pHead == null || pHead.next == null) return pHead;
if(pHead.val != pHead.next.val){
pHead.next = deleteDuplication(pHead.next);
return pHead;
}else{
int val = pHead.val;
while(pHead.val == val){
pHead = pHead.next;
if(pHead == null) return null;
}
return deleteDuplication(pHead);
}
}
}
*/
/*
算法思想:把当前结点的前一个结点(pre)和后面值比当前结点的值要大的结点相连。
*/
public class Solution {
public ListNode deleteDuplication(ListNode pHead)
{
if(pHead == null || pHead.next == null) return pHead;
ListNode temp = new ListNode(-1);
temp.next = pHead;
ListNode curNode = pHead;
ListNode pre = temp;
while(curNode != null && curNode.next != null){
ListNode next = curNode.next;
if(curNode.val == next.val){
while(next != null && curNode.val == next.val){
next = next.next;
}
pre.next = next;
curNode = next;
}else{
pre = curNode;
curNode = curNode.next;
}
}
return temp.next;
}
}
没什么复杂绕圈的,主要还是考验逻辑和代码能力。
刚开始想在if (pHead.next != null && pHead.val == pHead.next.val)里套一个同样内容的while,但强迫症犯了看到重复部分很不爽,花了点时间写成如下形式,看起来简洁一些,我是看着挺舒服的。
说明:
如果当前结点和下一个重复,则pre.next设空,否则,如果pre.next为空,则跳过当前结点(代表当前结点为同类重复结点的最后一个).
public ListNode deleteDuplication(ListNode pHead) {
ListNode h = new ListNode(0), p = h;
h.next = pHead;
while (pHead != null) {
if (pHead.next != null && pHead.val == pHead.next.val) {
p.next = null;
} else if (pHead.next != null && p.next == null) {
p.next = pHead.next;
} else {
p = p.next;
}
pHead = pHead.next;
}
return h.next;
}
public ListNode deleteDuplication(ListNode pHead) {
if(pHead==null||pHead.next==null) return pHead;
else {
//新建一个节点,防止头结点要被删除
ListNode newHead=new ListNode(-1);
newHead.next=pHead;
ListNode pre=newHead;
ListNode p=pHead;
ListNode next=null;
while(p!=null && p.next!=null)
{
next=p.next;
if(p.val==next.val)//如果当前节点的值和下一个节点的值相等
{
while(next!=null && next.val==p.val)//向后重复查找
next=next.next;
pre.next=next;//指针赋值,就相当于删除
p=next;
}
else{ //如果当前节点和下一个节点值不等,则向后移动一位
pre=p;
p=p.next;
}
}
return newHead.next;//返回头结点的下一个节点
}
} # 思路简单版,为了便于处理头节点,手动增加虚拟首结点,分别设置4个指针
# anchor:标志链接位置,初始化为虚拟首结点
# former:标志待判断节点的直接前驱,初始化为虚拟首结点
# x:标志待判断节点本身,初始化为头节点
# latter:标志待判断节点的直接后继,初始化为头节点后继
# 根据题意,只有某节点与其直接前驱和直接后继都不相同时,才保留
# latter到链表结尾,或者整个链表为空时为退化情况
def deleteDuplication(self, pHead):
# write code here
if not pHead: # 如果链表为空
return None
Head = ListNode(None) # 虚拟首结点
Head.next = pHead
anchor, former, x, latter = Head, Head, Head.next, Head.next.next # 初始化
while(latter): # 当遍历节点都不是空(都有值)的时候
if former.val != x.val and x.val != latter.val: # 如果x为一个不重复的节点,则链入返回的链上
anchor.next = x
anchor = anchor.next
former, x, latter = x, latter, latter.next # 指针向后移动
if former.val == x.val: # 最后一个节点,如果重复就不要,否则要
anchor.next = None
else:
anchor.next = x
return Head.next # 去掉虚拟首结点,返回
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ListNode deleteDuplication(ListNode pHead)
{
ListNode newHead = new ListNode(-1);
newHead.next = pHead;
ListNode pre = newHead;
ListNode node = pHead;
while(node!=null&&node.next!=null){
if(node.val==node.next.val){
while(node!=null&&node.next!=null&&node.val==node.next.val){
node = node.next;
}
pre.next = node.next;
node = node.next;
}
else{
pre = node;
node = node.next;
}
}
return newHead.next;
}
}
public ListNode deleteDuplication(ListNode pHead){
ListNode first = new ListNode(Integer.MIN_VALUE),last;
first.next = pHead;
last = first;
while (pHead != null && pHead.next != null) {
if (pHead.val == pHead.next.val) {
int val = pHead.val;
while (pHead!= null && pHead.val == val) pHead = pHead.next;
last.next = pHead;
}
else {
last = pHead;
pHead = pHead.next;
}
}
return first.next;
}
// public ListNode deleteDuplication(ListNode pHead){
// LinkedList<ListNode> result = new LinkedList<ListNode>();
// result.addLast(new ListNode(Integer.MIN_VALUE));
// boolean isRepeated = false;
// while (pHead != null){
// if (result.getLast().val == pHead.val){
// isRepeated = true;
// }
// else {
// if (isRepeated){
// result.removeLast();
// isRepeated = false;
// }
// result.addLast(pHead);
// }
// pHead = pHead.next;
// }
// if (isRepeated) result.removeLast();
//
// if (result.size() == 1) return null;
//
// for (int i = 0; i < result.size() - 1; i++) {
// result.get(i).next = result.get(i+1);
// }
// result.get(result.size() - 1).next = null;
//
// return result.get(0).next;
// }
// public ListNode deleteDuplication(ListNode pHead){
// ListNode tHead = new ListNode(Integer.MIN_VALUE),t;
// boolean isRepeated;
// tHead.next = pHead;
//
// pHead = tHead;
// while (pHead != null){
// isRepeated = false;
//
// t = pHead.next;
// if (t == null) break;
//
// while (t.val == pHead.val){
// isRepeated = true;
// t = t.next;
// if (t == null){
// pHead.next = null;
// break;
// }
// }
//
// pHead.next = t;
// if (isRepeated) pHead.val = Integer.MAX_VALUE;
// pHead = pHead.next;
// }
//
// pHead = tHead;
// while (pHead != null){
// if (pHead.next == null) break;
// else if (pHead.next.val == Integer.MAX_VALUE){
// pHead.next = pHead.next.next;
// }else {
// pHead = pHead.next;
// }
// }
//
// return tHead.next;
// }
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
/*
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if(pHead==NULL)
return NULL;
ListNode* pPreNode = NULL;
ListNode* pNode = pHead;
while(pNode!=NULL)
{
ListNode* pNext = pNode->next;
bool needDelete = false;
if(pNext!=NULL&&pNext->val==pNode->val)
needDelete = true;
if(!needDelete)
{
pPreNode = pNode;
pNode = pNode->next;
}
else
{
int value = pNode->val;
ListNode* pToBeDel = pNode;
while(pToBeDel!=NULL&&pToBeDel->val==value)
{
pNext = pToBeDel->next;
delete pToBeDel;
pToBeDel = NULL;
pToBeDel = pNext;
}
//
if(pPreNode==NULL)
pHead = pNext;
else
pPreNode->next = pNext;
pNode = pNext;
}
}
return pHead;
}
};