删除链表中的节点和删除链表中的重复元素

1. 删除链表的节点

思路:当我们要删除节点i,先把i的下一个结点j的内容复制到i,然后把i的指针指向节点j的下一个节点。此时再删除节点j,其效果刚好把节点i删除了;当删除的节点位于链表的尾部,从投头顺序遍历得到该节点的前序节点,并完成删除;当链表只有一个节点的时候,把链表的头结点设置null。

//代码来自 https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof/solution/cong-on-dao-o1-by-ml-zimingmeng/

public class DeleteNode {
    public static void DeleteNode1(Node nodes, Node toBeDelete) {
        if (nodes == null && toBeDelete == null) return;
        //待删除的节点不是尾节点
        if (toBeDelete.next != null) {
            Node next = toBeDelete.next;
            toBeDelete.date = next.date;
            toBeDelete.next = next.next;
        } else if (nodes == toBeDelete) {  // 待删除节点只有一个节点,此节点为头节点
            nodes = null;
        } else {   //待删除的节点尾节点
            Node cur = nodes;
            while (cur.next != toBeDelete) {
                cur = cur.next;
            }
            cur.next = null;
        }
    }

    public static void main(String[] args) {
        Node nodes = new Node(4);
        nodes.next = new Node(5);
        nodes.next.next = new Node(1);
        nodes.next.next.next = new Node(9);
        DeleteNode1(nodes,nodes.next);
        System.out.println(nodes.date+"==>"+nodes.next.date+"====>"+nodes.next.next.date);
    }
}

如果删除节点为前面的 n-1n−1 个节点,时间复杂度均为 O(1)O(1),只有删除节点为最后一个时,时间复杂度才会变成 O(n)O(n)。平均时间复杂度为:(O(1)\times(n-1) + O(n))/n = O(1)(O(1)×(n−1)+O(n))/n=O(1),仍然为 O(1)O(1)。

2. 删除链表中的重复节点
//代码来自:剑指offer第123页

public class DeleteDuplication {
    public static void DeleteDuplication1(Node head) {
        if (head == null && head.next == null) {
            return;
        }
        Node preNode = null;  // 重复节点的前一个节点
        Node pNode = head;    // 当前节点
        while (pNode != null) {
            Node pNext = pNode.next;
            boolean needDelete = false;  // 删除标志
            if (pNext != null && pNode.date == pNext.date) {  // 重复删除  标志位true
                needDelete = true;
            }
            if (!needDelete) {  // 当删除标志为false 判断下一个节点
                preNode = pNode;
                pNode = pNode.next;
            } else {
                int value = (int) pNode.date;
                Node pToBeDel = pNode;
                while (pToBeDel != null && (int) pToBeDel.date == value) {  //判读重复值到哪个节点
                    pNext = pToBeDel.next;
                    pToBeDel = pNext;
                }
                if (preNode == null) head = pNext;  //说明从头节点开始重复
                else preNode.next = pNext;
                pNode = pNext;
            }
        }
    }

    public static void main(String[] args) {
        Node nodes = new Node(1);
        nodes.next = new Node(2);
        nodes.next.next = new Node(3);
        nodes.next.next.next = new Node(3);
        nodes.next.next.next.next = new Node(4);
        nodes.next.next.next.next.next = new Node(4);
        nodes.next.next.next.next.next.next = new Node(5);
        DeleteDuplication1(nodes);
        System.out.println(nodes.date+"==>"+nodes.next.date+"====>"+nodes.next.next.date);

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值