删除链表重复节点 python_删除链表中重复的结点

211

非递归的代码:

1. 首先添加一个头节点,以方便碰到第一个,第二个节点就相同的情况

2.设置 pre ,last 指针, pre指针指向当前确定不重复的那个节点,而last指针相当于工作指针,一直往后面搜索。 if (pHead==null || pHead.next==null){return pHead;}

ListNode Head = new ListNode(0);

Head.next = pHead;

ListNode pre = Head;

ListNode last = Head.next;

while (last!=null){

if(last.next!=null && last.val == last.next.val){

// 找到最后的一个相同节点

while (last.next!=null && last.val == last.next.val){

last = last.next;

}

pre.next = last.next;

last = last.next;

}else{

pre = pre.next;

last = last.next;

}

}

return Head.next;

编辑于 2018-03-14 22:04:21

回复(81)

135

参考了大家的代码

public class Solution {

public ListNode deleteDuplication(ListNode pHead) {

if (pHead == null || pHead.next == null) { // 只有0个或1个结点,则返回

return pHead;

}

if (pHead.val == pHead.next.val) { // 当前结点是重复结点

ListNode pNode = pHead.next;

while (pNode != null && pNode.val == pHead.val) {

// 跳过值与当前结点相同的全部结点,找到第一个与当前结点不同的结点

pNode = pNode.next;

}

return deleteDuplication(pNode); // 从第一个与当前结点不同的结点开始递归

} else { // 当前结点不是重复结点

pHead.next = deleteDuplication(pHead.next); // 保留当前结点,从下一个结点开始递归

return pHead;

}

}

}

发表于 2016-09-20 13:14:55

回复(49)

147

递归

class Solution {

public:

ListNode* deleteDuplication(ListNode* pHead)

{

if (pHead==NULL)

return NULL;

if (pHead!=NULL && pHead->next==NULL)

return pHead;

ListNode* current;

if ( pHead->next->val==pHead->val){

current=pHead->next->next;

while (current != NULL && current->val==pHead->val)

current=current->next;

return deleteDuplication(current);

}

else {

current=pHead->next;

pHead->next=deleteDuplication(current);

return pHead;

}

}

};

发表于 2016-03-30 19:41:52

回复(65)

209

public static ListNode deleteDuplication(ListNode pHead) {

ListNode first = new ListNode(-1);//设置一个trick

first.next = pHead;

ListNode p = pHead;

ListNode last = first;

while (p != null && p.next != null) {

if (p.val == p.next.val) {

int val = p.val;

while (p!= null&&p.val == val)

p = p.next;

last.next = p;

} else {

last = p;

p = p.next;

}

}

return first.next;

}

编辑于 2015-08-27 20:49:38

回复(78)

48

/*

struct ListNode {

int val;

struct ListNode *next;

ListNode(int x) :

val(x), next(NULL) {

}

};

*/

class Solution {

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;//返回头结点的下一个节点

}

}

};

发表于 2016-07-26 10:58:06

回复(26)

56

1596387_1473616154125_4A47A0DB6E60853DEDFCFDF08A5CA249

1596387_1473616394704_FB5C81ED3A220004B71069645F112867

剑指offer没看,不知道是不是用的这个方法。

看懂了这个图,就明白了。

1.加一个头结点

2.两个临时指针p,q

3.找前后不相等的节点

class Solution {

public:

ListNode* deleteDuplication(ListNode* pHead)

{

if (pHead == NULL || pHead->next == NULL)

return pHead;

/*---------先为链表创建一个头结点---------*/

int firstNumber = pHead->val;

//假设我的头结点数值为-1

int myFirst = -1;

//万一链表的头结点也为-1,那么我就改成-2

if (myFirst == firstNumber)

{

myFirst = -2;

}

ListNode *head = new ListNode(myFirst);

head->next = NULL;

head->next = pHead;

ListNode *p = head;

ListNode *q = head->next;

while (q)

{

while (q->next && (q->next->val == q->val))

{

q = q->next;

}

if (p->next != q)

{

q = q->next;

p->next = q;

}

else

{

p = q;

q = q->next;

}

}

//返回的时候,注意去掉头结点(自己创建的辅助节点)

return head->next;

}

};

编辑于 2016-09-12 01:53:23

回复(23)

18

# -*- 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

编辑于 2018-05-19 15:22:25

回复(9)

16

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

编辑于 2018-10-21 22:45:43

回复(1)

10

思考:化繁为简,先找到第一个符合的结点,以后递归。

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;

}

发表于 2016-07-17 16:13:58

回复(4)

18

//q、p、r代表上个节点,当前节点,后继节点

public ListNode deleteDuplication(ListNode pHead) {

ListNode q, p, r;

p = pHead;

q = r = null;

while (p != null) {

boolean flag = false;

r = p.next;

while (r != null && r.val == p.val) {

flag = true;

r = r.next;

}

if (flag) {

if (q != null)

q.next = r;

else

pHead = null;

} else {

if (q == null)

pHead = p;

q = p;

}

p = r;

}

return pHead;

}

编辑于 2016-03-31 09:31:57

回复(4)

27

python solution:

先不管三七二十一把所有节点的值放到一个列表中,再筛选出值数量为1的值。

再新建一个链表返回即可。很暴力。 class Solution:

def deleteDuplication(self, pHead):

res = []

while pHead:

res.append(pHead.val)

pHead = pHead.next

res = list(filter(lambda c: res.count(c) == 1, res))

dummy = ListNode(0)

pre = dummy

for i in res:

node = ListNode(i)

pre.next = node

pre = pre.next

return dummy.next

编辑于 2017-10-19 19:41:46

回复(20)

8

//为方便操作,加一个头结点,最后再删掉

class Solution {

public:

ListNode* deleteDuplication(ListNode* pHead){

ListNode* head=new ListNode(0);

ListNode* p=head;

ListNode* q=pHead;

while(q){

while(q!=NULL&&q->next!=NULL&&q->next->val==q->val){

int tmp=q->val;

while(q!=NULL&&q->val==tmp)

q=q->next;

}

p->next=q;

p=p->next;

if(q)

q=q->next;

}

return head->next;

}

};

发表于 2017-06-08 19:53:29

回复(2)

6

/*

*因为需要删除重复的节点,所以需要保留一个待删除节点之前的节点,这里用一个指针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;

}

};

发表于 2017-07-31 11:06:02

回复(1)

5

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;

}

}

发表于 2016-05-05 11:19:26

回复(4)

8

// 这道题利用递归思想会使程序简洁很多,主要是理解递归的思想,这里主要是看到别人写的程序,感觉特别简洁,所以分享在这里。

代码如下: public ListNode deleteDuplication(ListNode pHead) {

if (pHead == null || pHead.next == null) { // 只有0个或1个结点,则返回

return pHead;

}

if (pHead.val == pHead.next.val) { // 当前结点是重复结点

ListNode pNode = pHead.next;

while (pNode != null && pNode.val == pHead.val) {

// 跳过值与当前结点相同的全部结点,找到第一个与当前结点不同的结点

pNode = pNode.next;

}

return deleteDuplication(pNode); // 从第一个与当前结点不同的结点开始递归

} else { // 当前结点不是重复结点

pHead.next = deleteDuplication(pHead.next); // 保留当前结点,从下一个结点开始递归

return pHead;

}

}

发表于 2018-06-02 19:35:52

回复(1)

3

单层循环的简单解法

723498259_1581782931535_072774B6B658B3603E1AA7198722775C

删除链表需要用到多个指针,比如上图中,我们想要删除节点q,只需要把p.next指向r即可。 所以我们使用3个指针,p代表前一个节点,q和r是后面两个节点,是每次循环时用来比较的。 首先,p保证与q的值不相等,因此只有当我们完成下面的一个数的操作(不论是保留还是删除),才会更新它。 比如最简单的情况,q与r不相等,那么我们直接移动指针即可(左图) 如果q与r相等呢?这时候我们需要继续往下寻找这个数的最后一个,所以不移动p,只移动q和r,直到q与r不相等时才停止。此时删除这些中间节点。 总结一下,我们只需要一直往下遍历q和r,如果他们不等,则有两种情况,一个是p的下一个就是q,那么就没有重复,更新p;如果p的下一个不是q,则说明有重复,这时更新p的next,删除节点。 这里还需要注意链表尾部是重复节点的问题,由于我们不知道什么时候会遇到最后一个重复的数,当循环结束时还没有遇到的情况,就无法执行更新p.next了,所以要在最后再进行一次判断,p与q不相连的话则需要删除它们。

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

发表于 2020-02-16 00:08:56

回复(0)

3

满屏全是递归的算法,分享一个不是用递归,单纯用指针实现的方法: 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;

}

};

发表于 2017-09-11 22:21:16

回复(0)

3

//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;

}

编辑于 2017-05-09 23:07:47

回复(0)

3

class Solution {

public:

ListNode* deleteDuplication(ListNode* pHead)

{

if(pHead==NULL || pHead->next == NULL)

return pHead;

//添加一个哨兵节点

ListNode* pFirst = new ListNode(-1);

pFirst->next = pHead;

ListNode* prev = pFirst;

ListNode* curr = pHead;

while(curr != NULL )

{

while(curr->next != NULL && curr->val

== curr->next->val)

{

curr = curr->next;

}

if(prev->next == curr)

{

prev = curr;

curr = curr->next;

}else{

curr = curr->next;

prev->next = curr;

}

}

return pFirst->next;

}

};

发表于 2016-12-08 14:40:36

回复(2)

3

/*

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 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;

}

};

编辑于 2016-08-13 12:56:19

回复(2)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值