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

题目:

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

思路:一般都是设置一个先前的结点,因为第一个也可能是重复的。


public class Solution{

    public static void main(String[] args) {
        int[] arr = new int[]{1, 2, 3, 3, 3, 4, 4, 4, 4, 5};
        ListNode head = Insert(arr);
        show(head);
        show(deleteDuplication1(head));
    }
    
    //常用新建3个节点来判断
    public static ListNode deleteDuplication(ListNode pHead) {
        if (pHead == null || pHead.next == null) {
            return pHead;
        }

        //建先前结点,因为头结点可能是重复的。
        ListNode first = new ListNode(-1), pre;
        first.next = pHead;
        pre = 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;
                }
                pre.next = pHead;
            } else {
                pre = pHead;
                pHead = pHead.next;
            }
        }
        return first.next;
    }

    //容器类,简化代码
    public static ListNode deleteDuplication1(ListNode pHead) {
        LinkedList<ListNode> result = new LinkedList<ListNode>();
        result.addLast(new ListNode(-1));
        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 static ListNode deleteDuplication2(ListNode pHead) {
        if (pHead == null || pHead.next == null) {
            return pHead;
        }

        if (pHead.val == pHead.next.val) {    // 当前结点是重复结点
            ListNode pNode = pHead.next;
            while (pNode != null && pNode.val == pHead.val) {
                //跳过值与当前结点相同的结点,找打第一个与当前结点不同的结点
                pNode = pNode.next;
            }
            // 从第一个与当前结点不同的结点开始递归
            return deleteDuplication2(pNode);
        } else {//当前不是重复结点
            //保留当前结点,从下一个结点开始递归
            pHead.next = deleteDuplication2(pHead.next);
            return pHead;
        }
    }
    

    static class ListNode {
        int val;
        ListNode next = null;

        ListNode(int val) {
            this.val = val;
        }
    }


    private static ListNode Insert(int[] array) {
        if (array == null) return null;

        ListNode head = new ListNode(array[0]);
        ListNode cur = head;
        for (int i = 1; i < array.length; i++) {
            ListNode node = new ListNode(array[i]);
            cur.next = node;
            cur = node;
        }
        return head;
    }

    public static void show(ListNode head) {
        if (head == null) return;

        ListNode cur = head;
        while (cur.next != null) {
            System.out.print(cur.val + " ");
            cur = cur.next;
        }
        System.out.println(cur.val);
    }


}

本题注意点:

  • 不仅仅要对,还要做快,用容易的方法
  • 要想到用容器去便捷的处理
  • 递归的思想用的不6
  • 如果要留一个重复的值呢?

猜你喜欢

转载自blog.csdn.net/jae_wang/article/details/80324542