zoukankan      html  css  js  c++  java
  • 234. Palindrome Linked List

    https://leetcode.com/problems/palindrome-linked-list/#/description

    Given a singly linked list, determine if it is a palindrome.

    Follow up:
    Could you do it in O(n) time and O(1) space?

    Hint: 

    Two pointer + reverse 

    Sol:

    Time complexity O(n), Space complexity O(n):

    Use the fast and slow pointers to find the mid point. Fast pointer moves two moves when slow pointer makes one move. Use stack to record every move the slow pointer moves. When the fast pointer reaches the end, the slow pointer is at the mid point and the first half of the linked list is already in the stack. Then the slow pointer moves on, and compares its value with stack top.

    Time complexity O(n), Space complexity O(1):

    Find the mid point first and reverse the second half, then compare the first half and the reversed sencond half.

    The following codes in space O(1). 

    # Definition for singly-linked list.
    # class ListNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution(object):
        def isPalindrome(self, head):
            """
            :type head: ListNode
            :rtype: bool
            """
            # two pointer technique
            fast = slow = head
            #find the mid node
            while fast and fast.next:
                fast = fast.next.next
                slow = slow.next
            # reverse the second half, i.e.reverse slow and node
            node = None
            while slow:
                # make a copy of slow.next before overwrite it
                # nxt = slow.next, in this prob we do not need to this
                # reverse slow and slow.next
                tmp = slow.next
                slow.next = node
                # go forward 
                node = slow
                slow = tmp
            # comapre the first and second half nodes
            while node:
                if node.val != head.val:
                    return False
                node = node.next
                head = head.next
            return True

    Note:

    1 The fast pointer moves two steps while the slow pointer moves one step at a step, and when the fast pointer stops, the slow pointer is at mid point. Bingo!

    2 Q: How to reverse a linked list ?

    A:

    Step 1: use a tmp varibale to store the next link of current node before overwrite it

    tmp = cur.next

    Step2 : reverse, let the next link of current node point to the previous node

    cur.next = pre

    Step 3: Advance

    pre = cur

    cur = tmp

    class ListNode:
        def __init__(self,x):
            self.val = x
            self.next = None
    
            
    def reverseLinkedList(head):
        if head is None or head.next is None:
            return head
        pre = None
        cur = head
        h = head
        while cur:
            h = cur
            tmp = cur.next
            cur.next = pre
            pre = cur
            cur = tmp
        return h
            

    http://blog.csdn.net/u011608357/article/details/36933337

    P.S. Do not dig too deep. ugh.

    Similar problem:

    https://github.com/Premiumlab/Python-for-Algorithms--Data-Structures--and-Interviews/blob/master/Linked%20Lists/Linked%20Lists%20Interview%20Problems/Linked%20List%20Interview%20Problems%20-%20SOLUTIONS/Singly%20Linked%20List%20Cycle%20Check%20-%20SOLUTION.ipynb

    Singly Linked List Cycle Check - SOLUTION

    Problem

    Given a singly linked list, write a function which takes in the first node in a singly linked list and returns a boolean indicating if the linked list contains a "cycle".

    A cycle is when a node's next point actually points back to a previous node in the list. This is also sometimes known as a circularly linked list.

    You've been given the Linked List Node class code:

    In [1]:
    class Node(object):
        
        def __init__(self,value):
            
            self.value = value
            self.nextnode = None
    
     

    Solution

    To solve this problem we will have two markers traversing through the list. marker1 and marker2. We will have both makers begin at the first node of the list and traverse through the linked list. However the second marker, marker2, will move two nodes ahead for every one node that marker1 moves.

    By this logic we can imagine that the markers are "racing" through the linked list, with marker2 moving faster. If the linked list has a cylce and is circularly connected we will have the analogy of a track, in this case the marker2 will eventually be "lapping" the marker1 and they will equal each other.

    If the linked list has no cycle, then marker2 should be able to continue on until the very end, never equaling the first marker.

    Let's see this logic coded out:

     
    def cycle_check(node):
    
        # Begin both markers at the first node
        marker1 = node
        marker2 = node
    
        # Go until end of list
        while marker2 != None and marker2.nextnode != None:
            
            # Note
            marker1 = marker1.nextnode
            marker2 = marker2.nextnode.nextnode
    
            # Check if the markers have matched
            if marker2 == marker1:
                return True
    
        # Case where marker ahead reaches the end of the list
        return False
     

    Test Your Solution

    In [9]:
    """
    RUN THIS CELL TO TEST YOUR SOLUTION
    """
    from nose.tools import assert_equal
    
    # CREATE CYCLE LIST
    a = Node(1)
    b = Node(2)
    c = Node(3)
    
    a.nextnode = b
    b.nextnode = c
    c.nextnode = a # Cycle Here!
    
    
    # CREATE NON CYCLE LIST
    x = Node(1)
    y = Node(2)
    z = Node(3)
    
    x.nextnode = y
    y.nextnode = z
    
    
    #############
    class TestCycleCheck(object):
        
        def test(self,sol):
            assert_equal(sol(a),True)
            assert_equal(sol(x),False)
            
            print "ALL TEST CASES PASSED"
            
    # Run Tests
    
    t = TestCycleCheck()
    t.test(cycle_check)
    
     
    ALL TEST CASES PASSED
    
     

    Good Job!

  • 相关阅读:
    各种插件
    如何在C#中选择正确的集合 转
    转载 hashtable和dictionary的区别
    堆和栈的区别 转载
    数据结构王道错题集2019版(上>一>四章)
    mongoDB连接数据库
    linuix没有网络
    rand函数
    mongodb学习(入门。。。。。)
    先随便写
  • 原文地址:https://www.cnblogs.com/prmlab/p/6957347.html
Copyright © 2011-2022 走看看