Cracking the Coding Interview Q2.1

Write code to remove duplicates from an unsorted linked list.

FOLLOW UP

How would you solve this problem if a temporary buffer is not allowed?

思路1:用hashset存储已经出现的节点,如果重复则删除。空间O(N),时间O(N)。

思路2:两个指针,对于每个当前节点,遍历后面的元素删除重复。 空间O(1),时间O(n^2)。

思路3:移动窗口法是否可行?

    public static void deleteDupsA(LinkedListNode n) {
        HashSet<Integer> set = new HashSet<Integer>();
        LinkedListNode previous = null;
        while (n != null) {
            if (set.contains(n.data)) {
                previous.next = n.next;
            } else {
                set.add(n.data);
                previous = n;
            }
            n = n.next;
        }
    }

    public static void deleteDupsC(LinkedListNode head) {
        if (head == null) return;
        LinkedListNode previous = head;
        LinkedListNode current = previous.next;
        while (current != null) {
            // Look backwards for dups, and remove any that you see.
            LinkedListNode runner = head;
            while (runner != current) {
                if (runner.data == current.data) {
                    LinkedListNode tmp = current.next;
                    previous.next = tmp;
                    current = tmp;
                    /* We know we can‘t have more than one dup preceding
                     * our element since it would have been removed
                     * earlier. */
                    break;
                }
                runner = runner.next;
            }

            /* If runner == current, then we didn‘t find any duplicate
             * elements in the previous for loop.  We then need to
             * increment current.
             * If runner != current, then we must have hit the ?break?
             * condition, in which case we found a dup and current has
             * already been incremented.*/
            if (runner == current) {
                previous = current;
                current = current.next;
            }
        }
    }

    public static void deleteDupsB(LinkedListNode head) {
        if (head == null) return;

        LinkedListNode current = head;
        while (current != null) {
            /* Remove all future nodes that have the same value */
            LinkedListNode runner = current;
            while (runner.next != null) {
                if (runner.next.data == current.data) {
                    runner.next = runner.next.next;
                } else {
                    runner = runner.next;
                }
            }
            current = current.next;
        }
    }

Cracking the Coding Interview Q2.1,布布扣,bubuko.com

时间: 2024-07-31 14:33:12

Cracking the Coding Interview Q2.1的相关文章

Cracking the Coding Interview Q2.5

You have two numbers represented by a linked list, where each node contains a single digit. The digits are stored in reverse order, such that the 1’s digit is at the head of the list. Write a function that adds the two numbers and returns the sum as

Cracking the Coding Interview Q2.7

检测链表是否是palindrome. 思路1:翻转并比较. 思路2:迭代. 思路3:递归. public static boolean isPalindrome(LinkedListNode head) { LinkedListNode fast = head; LinkedListNode slow = head; Stack<Integer> stack = new Stack<Integer>(); while (fast != null && fast.ne

Cracking the Coding Interview Q2.6

Given a circular linked list, implement an algorithm which returns node at the beginning of the loop. DEFINITION Circular linked list: A (corrupt) linked list in which a node’s next pointer points to an earlier node, so as to make a loop in the linke

Cracking the Coding Interview Q2.2

Implement an algorithm to find the kth to last element of a singly linked list. 思路:双指针 参考 http://www.cnblogs.com/jdflyfly/p/3810697.html Cracking the Coding Interview Q2.2,布布扣,bubuko.com

Cracking the Coding Interview Q2.3

Implement an algorithm to delete a node in the middle of a single linked list, given only access to that node. 思路:复制后面节点的值,然后删除后面的节点. 注意:如果给定的节点是最后一个,则无解.. public static boolean deleteNode(LinkedListNode n) { if (n == null || n.next == null) { return

《Cracking the Coding Interview》——第16章:线程与锁——题目5

2014-04-27 20:16 题目:假设一个类Foo有三个公有的成员方法first().second().third().请用锁的方法来控制调用行为,使得他们的执行循序总是遵从first.second.third的顺序. 解法:你应该想到了用lock的方法类阻塞,不过这里面有个概念问题使得直接用ReentrantLock不能通过编译(对于一个锁对象,不同在A线程中锁定,又在B线程中解锁,不允许这样的归属关系),可以用Semaphore来达到相同的目的.请看下面的代码. 代码: 1 // 16

《Cracking the Coding Interview》——第16章:线程与锁——题目3

2014-04-27 19:26 题目:哲学家吃饭问题,死锁问题经典模型(专门用来黑哲学家的?). 解法:死锁四条件:1. 资源互斥.2. 请求保持.3. 非抢占.4. 循环等待.所以,某砖家拿起一只筷子后如果发现没有另一只了,就必须把手里这只筷子放下,这应该是通过破坏"请求保持"原则来防止死锁产生,请求资源失败时,连自己的资源也进一步释放,然后在下一轮里继续请求,直到成功执行. 代码: 1 // This is the class for chopsticks. 2 import j

《Cracking the Coding Interview》——第16章:线程与锁——题目2

2014-04-27 19:14 题目:如何测量上下文切换的时间? 解法:首先,上下文切换是什么,一搜就知道.对于这么一个极短的时间,要测量的话,可以通过放大N倍的方法.比如:有A和B两件事,并且经常一起发生,每件只需要花几纳秒.如果你把A事件连续做几百万次,而B时间只做了几次,这样就能排除B事件对于测量的影响.如果总时间S = mA + nB.当m >> n 时,A≈S / m.下面的测量方法类似于打乒乓球,在主线程和副线程间互相传递一个令牌,这个令牌可以是变量.管道之类的用于通信的工具.与

《Cracking the Coding Interview》——第16章:线程与锁——题目1

2014-04-27 19:09 题目:线程和进程有什么区别? 解法:理论题,操作系统教材上应该有很详细的解释.我回忆了一下,写了如下几点. 代码: 1 // 16.1 What is the difference between process and thread? 2 Answer: 3 Process: 4 1. Basic element of resource allocation in the operating system. 5 2. Possesses independent