程序员面试金典2.1:编写代码,移除未排序的链表中的重复节点
2015-08-30 10:22
519 查看
2.1编写代码,移除未排序的链表中的重复节点
解法一:如果不得使用临时缓冲区,该怎么解决?
要想移除链表中的重复节点,我们需要设法记录有哪些是重复的。这里只需要使用到一个简单的散列表。
在下面的解法中,我们会直接迭代访问整个链表,将每个节点加入到散列表。若发现有重复的元素,将该节点从链表中移除,然后继续迭代。这个题目使用了链表,因此只需要扫描一次就能搞定。
解法二:不使用缓冲区
如不借助额外的缓冲区,可以用两个指针来迭代:current迭代访问整个链表,runner用于检查后续的节点是否重复
上述代码中的deleteDups2()
该代码的空间复杂度为O(1),时间复杂度为O(N2)
解法一:如果不得使用临时缓冲区,该怎么解决?
要想移除链表中的重复节点,我们需要设法记录有哪些是重复的。这里只需要使用到一个简单的散列表。
在下面的解法中,我们会直接迭代访问整个链表,将每个节点加入到散列表。若发现有重复的元素,将该节点从链表中移除,然后继续迭代。这个题目使用了链表,因此只需要扫描一次就能搞定。
/** * */ package project02; import java.util.Hashtable; import util.LinkedListNode; /** * @author JInShuangQi * * 2015年8月30日 */ public class E01DeleteDupsNumber { private LinkedListNode<Integer> head; private LinkedListNode<Integer> tail; private int size; // 尾部插入 public boolean addTail(int data) { if (this.head == null) { this.head = new LinkedListNode<Integer>(null, data, null); this.tail = this.head; } else { LinkedListNode<Integer> newnode = new LinkedListNode<Integer>(this.tail, data, null); this.tail.next = newnode; this.tail = newnode; } this.size++; return true; } public String toString() { if (this.isEmpty()) return "[]"; else { StringBuffer st = new StringBuffer("["); for (LinkedListNode<Integer> curent = this.head; curent != null; curent = curent.next) st.append(curent.data.toString() + " ,"); st.append("]"); return st.toString(); } } public boolean isEmpty() { return this.size == 0; } public void deleteDups(LinkedListNode<Integer> n){ Hashtable<Integer, Boolean> table = new Hashtable<Integer, Boolean>(); LinkedListNode<Integer> previous = null; while(n != null){ if(table.containsKey(n.data)){ previous.next = n.next; }else{ table.put(n.data, true); previous = n; } n =n.next; } while(head!=null){ System.out.println(head.data.toString()); head= head.next; } } public void deleteDups2(LinkedListNode<Integer> head){ if(head == null) return; LinkedListNode<Integer> current = head; while(current != null){ //移除后续值相同的所有节点 LinkedListNode<Integer> runner = current; while(runner.next != null){ if(runner.next.data == current.data){ runner.next = runner.next.next; }else{ runner = runner.next; } } current= current.next; } while(head!=null){ System.out.println(head.data.toString()); head= head.next; } } public static void main(String[] args){ E01DeleteDupsNumber test = new E01DeleteDupsNumber(); test.addTail(1); test.addTail(2); test.addTail(3); test.addTail(3); test.addTail(4); test.addTail(1); test.deleteDups2(test.head); } }上述代码含有测试用例,deleteDups()的时间复杂度为O(N),其中N为链表节点数目。
解法二:不使用缓冲区
如不借助额外的缓冲区,可以用两个指针来迭代:current迭代访问整个链表,runner用于检查后续的节点是否重复
上述代码中的deleteDups2()
该代码的空间复杂度为O(1),时间复杂度为O(N2)
相关文章推荐
- 黑马程序员 设计模式
- 不懂职场潜规则:你将永世不得翻身
- 30多年程序员生涯经验总结【转】
- QQ聊天:终结编程语言和编程职业
- 每日5道面试题七(java线程)
- 【LeetCode-面试算法经典-Java实现】【226-Invert Binary Tree(反转二叉树)】
- 黑马程序员-JAVA基础之枚举
- 常见java面试题总结
- 程序员必备技能
- 什么叫程序员
- 写给想当程序员的朋友
- 黑马程序员——java基础——正则表达式
- 腾讯 程序员 Java 笔试题目
- 各大公司笔试面试题目
- Android程序员必备精品资源 工具类
- Java面试题笔试题:
- JSP面试问题集
- JAVA程序员面试题
- Servlet面试题
- 半路程序员