看着学长们最近找实习做的算法笔试题自己一道都不会,决定最近开始好好刷题...
先从最简单的开始刷起。权且在博客上做一些记录,以便后来回顾复习。
2017年3月28日 第一道
Linked List Cycle
Given a linked list, determine if it has a cycle in it.
Follow up:
Can you solve it without using extra space?
当时并没有什么思路,想着要不每个新的node和之前出现过的node一一比较?但需要额外空间。
想了一会还是看看别人的答案吧,就当入门教学。
一个快结点和慢结点的思路:
[code=JAVA]
public class Solution {public boolean hasCycle(ListNode head) {
if(head==null || head.next==null) return false;
ListNode fast=head,slow=head;
while(fast!=null&& fast.next!=null){
fast=fast.next.next;
slow=slow.next;
if(fast==slow) return true;
}
return false;
}
}
[/code]
若链表有环,则进入环之后一定出不去。那么快慢结点进入环之后,步长为2与步长为1的扫描方式一定会重合(还没有用数学方式 证明,但想了想做N mod 1和N mod 2运算应该是能重合的)。否则遍历结束返回false。
Python版本的代码更加简洁:
def hasCycle(self, head):
try:
slow = head
fast = head.next
while slow is not fast:
slow = slow.next
fast = fast.next.next
return True
except:
return False
2017年3月28日 第二道
Delete Node in a Linked List
Write a function to delete a node (except the tail) in a singly linked list, given only access to that node.
Supposed the linked list is 1 -> 2 -> 3 -> 4
and you are given the third node with value 3
, the linked list should become 1 -> 2 -> 4
after calling your function.
问题麻烦在:只知道当前结点的情况下,单向链表没有办法找到前一个结点。所以这道题的思路为:把下一的结点的值与指针赋给当前结点,并删除下一节点。
Java:
public void deleteNode(ListNode node) {
node.val = node.next.val;
node.next = node.next.next;
}
Java中无需手动释放内存,因此没有写delete
Python:
def deleteNode(self, node):
node.val = node.next.val
node.next = node.next.next
2017年3月28日 第三题
Reverse Linked List
Reverse a singly linked list.
我的解法就是判头判尾,中间使用前向结点、后向节点、临时结点循环,但不够简洁。
一个简洁的Python版本:
class Solution:
# @param {ListNode} head
# @return {ListNode}
def reverseList(self, head):
prev = None
while head:
curr = head
head = head.next
curr.next = prev
prev = curr
return prev
还有一个利用递归的Java版本:
public class Solution {
public ListNode reverseList(ListNode head) {
if(head==null || head.next==null)
return head;
ListNode nextNode=head.next;
ListNode newHead=reverseList(nextNode);
nextNode.next=head;
head.next=null;
return newHead;
}
}
想法也是不错
2017年3月29日 第四题
Remove Linked List Elements
Remove all elements from a linked list of integers that have value val.
Example
Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6
Return: 1 --> 2 --> 3 --> 4 --> 5
我的思路是,先找到一个满足条件的头结点,否则返回null,然后递归找到并连接所有满足条件的头结点。
public class Solution {
public ListNode removeElements(ListNode head, int val) {
if (head==null) return head;
while(head.val==val){
if(head.next!=null)
head = head.next;
else
return null;
}
head.next = removeElements(head.next,val);
return head;
}
}
通过。看看其他解法:
利用伪头结点
public class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode fakeHead = new ListNode(-1);
fakeHead.next = head;
ListNode curr = head, prev = fakeHead;
while (curr != null) {
if (curr.val == val) {
prev.next = curr.next;
} else {
prev = prev.next;
}
curr = curr.next;
}
return fakeHead.next;
}
}
public class Solution {
public ListNode removeElements(ListNode head, int val) {
while (head != null && head.val == val) head = head.next;
ListNode curr = head;
while (curr != null && curr.next != null)
if (curr.next.val == val) curr.next = curr.next.next;
else curr = curr.next;
return head;
}
}
2017年4月1日 第五题
Merge Two Sorted Lists
合并两个已排序的链表,要求合并后链表依旧有序。
思考了一下觉得可以用递归的方法,于是写了一个出来。看discussion的时候看到更简洁的一个版本,贴出来public ListNode mergeTwoLists(ListNode l1, ListNode l2){ if(l1 == null) return l2; if(l2 == null) return l1; if(l1.val < l2.val){ l1.next = mergeTwoLists(l1.next, l2); return l1; } else{ l2.next = mergeTwoLists(l1, l2.next); return l2; } }