Leetcode刷题记录之Linked List

看着学长们最近找实习做的算法笔试题自己一道都不会,决定最近开始好好刷题...

先从最简单的开始刷起。权且在博客上做一些记录,以便后来回顾复习。


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 -> 4after 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;
		}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值