剑指offer--链表--删除链表中重复的结点

                                 删除链表中重复的结点

题目

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5。

思路

删除重复结点,只需要记录当前结点前的最晚访问过的不重复结点pPre、当前结点pCur、指向当前结点后面的结点pNext的三个指针即可。如果当前节点和它后面的几个结点数值相同,那么这些结点都要被剔除,然后更新pPre和pCur;如果不相同,则直接更新pPre和pCur。

需要考虑的是,如果第一个结点是重复结点我们该怎么办?这里我们分别处理一下就好,如果第一个结点是重复结点,那么就把头指针pHead也更新一下。

代码

/*
 public class ListNode {
    int val;
    ListNode next = null;
    ListNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
     /**
     * 主要参考博客的解题思路
     * @param pHead
     * @return
     */
    public ListNode deleteDuplication(ListNode pHead)
    {
            if(pHead == null)
            	return null;
            // 新建一个节点,防止头结点被删除
            ListNode firstNode = new ListNode(-1);
            firstNode.next = pHead;
            ListNode p = pHead;
            // 指向前一个节点
            ListNode preNode = firstNode;
            //这里相当于把preNode 和firstNode 绑定到了一起
            while (p!=null &&p.next !=null) {//注意条件的顺序,否则不对 因为如果p为null,p.next肯定异常
				if(p.val == p.next.val) {
					int val = p.val;
					 // 向后重复查找
					while (p != null&&p.val == val) {
						p = p.next;
					}
					// 上个非重复值指向下一个非重复值:即删除重复值
					preNode.next = p;
                    //记住这里和下面的preNode = p;不一样,因为这里还不确定是否真的是不重复,            
                    所以只能放到preNode.next
				}
				else {
					 // 如果当前节点和下一个节点值不等,则向后移动一位
					preNode = p;
                    这里的意思就是如果确定了不是就直接替换
					p = p.next;
				}
			}
            return firstNode.next;
            
    }
}

 

 这一步的代码图示如下面的图

 

LeetCode

删除排序链表中的重复元素 II

给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。

示例 1:

输入: 1->2->3->3->4->4->5

输出: 1->2->5

示例 2:

输入: 1->1->1->2->3

输出: 2->3

代码

遍历链表,将当前节点的上个节点的值保存在temp中,每次遍历的时候比较当前值与temp、下一节点的值是否相同,若不相同就将当前节点添加进来。
public ListNode deleteDuplicates(ListNode head) {
        ListNode result = new ListNode(0);
        ListNode curr = result;
        int temp = -100;
        while (head != null) {
            ListNode next = head.next;
            if ((next == null && temp != head.val) || (next != null && temp != head.val && next.val != head.val)) {
                ListNode node = new ListNode(head.val);
                curr.next = node;
                curr = curr.next;
            }
            temp = head.val;
            head = head.next;
        }
        return result.next;
    }

删除排序链表中的重复元素

给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。

示例 1:

输入: 1->1->2

输出: 1->2

示例 2:

输入: 1->1->2->3->3

输出: 1->2->3

代码

这是一个简单的问题,仅测试你操作列表的结点指针的能力。由于输入的列表已排序,因此我们可以通过将结点的值与它之后的结点进行比较来确定它是否为重复结点。如果它是重复的,我们更改当前结点的 next 指针,以便它跳过下一个结点并直接指向下一个结点之后的结点。
public ListNode deleteDuplicates(ListNode head) {
    ListNode current = head;
    while (current != null && current.next != null) {
        if (current.next.val == current.val) {
            current.next = current.next.next;
        } else {
            current = current.next;
        }
    }
    return head;
}


这里注意head值的变化 、

全部评论

相关推荐

10-15 09:13
已编辑
天津大学 soc前端设计
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务