赞
踩
简单LinkedList 的java代码实现:
- public class LinkedListNode {
- public int value;
- public LinkedListNode next;
-
- public LinkedListNode(int value) {
- this.value = value;
- this.next = null;
- }
- }
- public class LinkedList {
-
- public LinkedListNode head;
-
- /*add an element to the tail*/
- public void add(int v) {
- if (head == null) {
- this.head = new LinkedListNode(v);
- } else {
- LinkedListNode node = head;
- while (node.next != null) {
- node = node.next;
- }
- node.next = new LinkedListNode(v);
- }
- }
-
- /*remove the element that appear first*/
- public void removeFirst(int v) {
- /* if to be removed is head node */
- if (head.value == v) {
- head = head.next;
- return;
- }
-
- /* iterate to the end and remove target node */
- LinkedListNode node = head;
- while (node.next != null) {
- if (node.next.value == v) {
- node.next = node.next.next;
- return;
- }
- node = node.next;
- }
- }
-
- public void print() {
- LinkedListNode node = head;
- while (node != null) {
- System.out.print(node.value + " ");
- node = node.next;
- }
- System.out.println();
- }
- }
1. Write code to remove duplicated element from an unsorted linked list. 从无序链表中删除重复元素
来源 Cracking the Code Interview (2nd Edition) Ch2 Q1.
【解答】:题目已经明确说明是无序列表,对这类面试题,一般最差的复杂度是 O(NlogN),也就是需要一次排序过程,所以给出的答案最好要优于O(NlogN)。
方法一:除去重复元素,首先想到利用hash。将List迭代一遍,每拿出一个元素,放到hashtable里,并判断是否重复,如果重复则从List中删除该元素。这个算法的时间复杂度是O(N),但需要O(N)的空间建立hashtable去存放元素。
java代码:http://pastebin.com/UiqMVxdL 这里的linkedlist使用的是java.util.*中的LinkedList。实际面试中往往需要自己实现一个linkedlist。
方法二:利用runner pointer. 这个技巧也是解答LinkedList Problem的重要技巧之一。迭代当前链表,每次迭代利用一个runner去访问之后的元素,删除重复元素。算是naive approach,时间复杂度O(N^2),空间复杂度O(1)。面试中最先可能想到的应该是这种解答,然后可以优化到第一种方法。
2. Implement am algorithm to find the kth to last element of a singly linked list. 查找单项链表中,距最后一个元素距离为K的元素。
来源 Cracking the Code Interview (2nd Edition) Ch2 Q2.
【解答】:方法一:如果知道链表的长度N,答案就是从第(N-K)个元素。当然这题也就没有意义了。
方法二:利用chaser-runner。首先让runner先移动K位,这时候chaser从链表头部开始,和runner同时以相同的速度迭代链表,当runner到达链表尾部,chaser恰好距离最后一个元素K的距离。时间复杂度O(N), 空间复杂度O(1)。
java代码:http://pastebin.com/MQczDMvT 这里用到的LinkedList是本文开始时定义的data structure.
3. Given a circular linked list, implement an algorithm which returns the node at the beginning of the loop. 查找有环链表环的头部。
来源 Cracking the Code Interview (2nd Edition) Ch2 Q6.
【解答】: 这个题算是经典面试题之一,和Binary Tree的BFS遍历一样,都属于看上去满有水平,实际并没有太多难度的题目,如果遇到了不会做人品可是败成啥样了!?
首先第一问一般是判断该链表有没有环,接着问如果有环的话,找出环开始的节点。
如果判断是否有环?--Same technique as the last question. We can use runner pointer to detect if there is a loop. 记得以前在学校里跑1500米的时候,我经常被人套圈…类似的,如果一个链表有环,并且进入环以后,将一直在环里走下去,慢的总是会被快的赶上,套圈。所以我们用两个指针,一个slow runner,一个fast runner,每次slow走1个,fast走2个,如果在某个时刻slow == fast指针,则证明有环。
如何判断环的开始是哪个节点?-- 这个问题也很容易想通。当两个指针第一次相遇的时候,他们距离环的开始节点还有K个元素,而这K个元素是进入环之前那段链表元素的个数。怎么证明呢?设想两个runner同时从某个环的同一个点出发,快的runner以2倍于慢的runner速度前进,它们第一次重合一定还是在这个出发点的位置,以后每一次相遇也一定是在这个出发点的位置。So,设想现在进入环前的那一段K个节点,是环的一部分,离环真正的开始节点距离为K,那么两个runner同时出发,第一次碰撞必然还是在距离环开始节点K的位置。所以,第一次碰撞时,随便将任意一个runner回到链表头部,此时两个runner以同一速度前进,当他们再次相遇的节点,就是环的开始节点。
java代码:http://pastebin.com/p35Cwgzv
4. Implement a function to check if a linked list is a palindrome. 判断链表是不是回文链表。
来源 Cracking the Code Interview (2nd Edition) Ch2 Q7.
【解答】:经典面试题了。回文就是 0-->1-->2-->1-->0 奇数个节点, 或者 0-->1-->2-->2-->1-->0 偶数个节点。
方法一:很自然的想法就是把链表反转,然后对比反转以后的链表和原链表的节点值,并且只要比较反转链表和原链表一办的元素就可以。
方法二:利用runner pointer。很多的题目都可以利用这个方法来解决。Runner pointer和递归是解决链表问题最常用的两个方法。
定义两个指针,slow runner和fast runner,fast以2倍于slow的速度向链表尾部移动。如有奇数个节点:当fast到达链表尾部时,slow恰好到达链表中间。如有偶数个节点:fast第一次为null时,slow恰好完成了一半节点的访问。把slow访问过的节点元素值压入一个stack里。此后slow继续向链表尾部访问,同时stack里的元素开始出栈(奇数个元素的情况下要跳过中间元素),比较两个元素值,一旦出现不等,则不是回文,否则是。该解法的时间复杂度是O(N),因为需要一次迭代,同时需要O(N)的空间用作stack来存放链表元素。
java代码 http://pastebin.com/wZ54iSmq 这里的List是本文开始定义的数据结构。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。