zoukankan      html  css  js  c++  java
  • Remove Duplicates from Sorted List II 解答(有个比較特殊的case leetcode OJ没有覆盖)

             昨天被考了一道数据结构题,当时的实现比較一般。回来翻看leetcode,果然是上面的题。遂解之。

    accept之后翻看discuss别人的解法。发现非常多能够accept的代码都过不了我设计的一个case。网上搜了一些别人的代码,也过不了。遂有这篇博客,与君交流

             题目是这种:
            Given a sorted linked list, delete all nodes that have duplicate numbers, leaving onlydistinct numbers from the original list.
             For example,Given 1->2->3->3->4->4->5, return 1->2->5.Given 1->1->1->2->3, return 2->3.

            

            当时拿到这个题目,一眼首先想到的就是类似于手游《糖果粉碎传奇》的连续消除的画面。一个比較强的case浮入脑海:
            输入:1->2->3->3->3->5->6->2->2->6->5->2->7
            输出:1->7

            分析:当3 和 第一段连续的2 被消除后,链表变成1->2->5->6->6->5->2->7;
                        此时出现了连续的6。遂须要消除6,结果是1->2->5->5->2->7。
                        同理消除5和2之后剩下1->7

             可是不管是leetcode里面的discuss还是网上搜到的别人能够accept的代码。都不是上面的这样的输出,得到的输出一般例如以下:
             输出1:1 2 5 6 6 5 2 7
             输出2:1 2 5 5 2 7 
             当然,不知道是题目表意不明,或者是case太弱,可是题目明显写着‘distinct’。当然我觉得我的case应该是对的。遂我来讲一下我的思路和做法。

    就拿 1->2->3->3->3->5->6->2->2->6->5->2->7 这个case举例。

             

            在这个题目中。链表是单链表。那么我们用指针遍历链表的时候,是无法回头的,这是个明显的限制条件。可是在这个case中,当删掉3和第一段连续2的之后链表变成1->2->5->6->6->5->2->7。不论你的代码怎么实现,此时你的指针可能在第一个6或者第一个5那里,当链表继续删除连续节点的时候,指针是不得不回头的。否则不可以删除出现的两个5的连续节点。既然这样,题目的解法基本思路可以确定:递归或者栈,当然,两者是想通的。只是栈的实现会方便一些(当时做这个题的时候硬着头皮写递归,没写好,哈哈)。

            用堆的方式解题,思路是比較简单的:
    1、将头节点放入栈中,设置变量flag=false(flag表示栈顶节点是否须要被删除),检查下个节点
    2、假设当前节点是NULL,则跳到第4步;
          假设当前节点跟栈顶节点同样。则跳过链表上这个节点,flag=true,继续运行第2步。
          假设跟栈顶节点值不同。则跳到第3步;
    3、假设flag是true,那么把栈顶节点pop掉,flag置false。
          假设flag是false,把当前节点压入栈中,检查下个节点;
          运行第2步;
    4、假设flag是true,则pop掉栈顶节点
    5、链表的检查到此结束。栈内的节点就是结果链表的逆序存储。又一次组织一下便可
    6、注意:栈仅仅须要存节点的指针

            复杂度分析:时间复杂度能够简单分析一下,由于每一个节点要么被push要么被丢掉,push也有可能被pop,一共就这三种操作,每种最多运行一次,所以我们能够觉得时间复杂度是O(n)。空间复杂度,最坏情况下会把整个链表的指针都放到栈里面,最好情况下是结果链表的长度,所以空间复杂度是O(n)


    最后是我的代码:

    struct ListNode {
      int val;
      ListNode *next;
      ListNode(int x) : val(x), next(NULL) {}
    };
    
    class Solution {
     public:
      ListNode* deleteDuplicates(ListNode* head) {
        if (head == NULL) return NULL;
    
        stack<ListNode *> stk;
        bool flag = false;
        ListNode * cur = head;
        while (cur != NULL) {
          if (stk.empty()) {
              stk.push(cur);
              cur = cur->next;
              flag = false;
          } else if (cur->val == stk.top()->val) {
            flag = true;
            // because we don't know how the program frame manage the memory,
            // so i didn't free the  duplicate ListNode
            cur = cur->next;
            continue;
          } else if (flag) {
            stk.pop();
            flag = false;
          } else {   
            stk.push(cur);
            cur = cur->next;
          }   
        }   
        if (flag) stk.pop(); 
        
        // the remaining node in the stack is the result
        ListNode * res = NULL;
        while(!stk.empty()) {
          ListNode* t = stk.top();
          stk.pop();
          if (res == NULL) {
            res = t;
            res->next = NULL;
          } else {
            t->next = res;
            res = t;
          }
        } 
        return res;
      }
    };



  • 相关阅读:
    算法竞赛入门经典习题2-3 韩信点兵
    ios入门之c语言篇——基本函数——5——素数判断
    ios入门之c语言篇——基本函数——4——数值交换函数
    144. Binary Tree Preorder Traversal
    143. Reorder List
    142. Linked List Cycle II
    139. Word Break
    138. Copy List with Random Pointer
    137. Single Number II
    135. Candy
  • 原文地址:https://www.cnblogs.com/yfceshi/p/6938240.html
Copyright © 2011-2022 走看看