USYD COMP2123 Linked List tutorial

这周的知识点

了解以下数据结构的实现, time and space constraint

  • array implementation of a list

  • singly and doubly linked list

  • doubly linked list Stack and Queue

  • adv singly linked list stack and queue

python里的run time和function call测试方法

Tutorial

Q3 : Given a singly linked list, traverse the elements of the list in reverse order.

  • Design an algorithm that uses O(1) extra space.

首先我们需要了解题意, 是否真的要把linked list反过来.

比如 1->2->3 经过处理后变成 3->2->1.

如果只能使用O(1)的空间, 那么我们除了已经给的list的空间没有更多的地方来存储信息, 那么免不了对原本linkedlist的改动, 也就是

改变node之间next的指向.

O(1)的方法 有iterative和recursive两种解法, 推荐了解iterasive的写法.

在这之前, 先写一个helper function print_linkedlist(head)来帮忙检验. 我们默认print_linkedlist是时间O(n)空间O(1)的.


def print_linkedlist(head):

    node = head

    while(node):

        print(node.value) #traversed

        node = node.next

Iterasive method


def reverseList(head):

    current = head

    prev = None

    while(current):



        curr_next = current.next #先存next, 下一步要走的点

        current.next = prev # **改变当前点的next位置. 反转的一步!**

        prev = current #更新prev称为当前点.

        current = curr_next #更新当前点为next, 下一步要走的点.

    #理解视频: https://www.youtube.com/watch?v=sYcOK51hl-A

    old_last_node = prev

    return old_last_node

print_linkedlist(reverseList(head))

Recursive method


def reverseList(head):

    """

    return the new head with the reversed linkedlist

    """

    if head==None or head.next==None:



        return head

    old_second = self.reverseList(head.next)

    head.next.next = head

    head.next=None



    return old_second

print_linkedlist(reverseList(head))

  • Design an algorithm that uses O(sqrt(n)) extra space.

因为题目要求仅仅是reversely traverse, 有多余位置存储信息的话, 我们就可以事实上不改变node之间的联系了.


def reverse_sqrt_n(head):

    # 为了方便描述 记 K = sqrt(n)

    # # -------第一步: 找到list的长度------

    # 假设我们不知道这个list有多长, 我们首先需要获取长度信息.

    n=0

    node=head

    while node:

        n+=1

        node=node.next

    #to know how long is our linked list, time O(n), space O(1)

    k=int(n**.5)+1  #确定sqrt(n)的大小

    # 到这一步为止 time用了n, space用了1

    # ---------第二步: 存储每第K个node位置-------

    # 存储每第sqrt(k)个node

    # 一共有 k/sqrt(k)=sqrt(k)次操作, 存好了以后会使用sqrt(k)space.

    i=0

    node=self

    lsa=[node]

    node_stored_position_sequence=[] #只是为了分析而用

    count = 0

    while node:

        i+=1

        count+=1

        if i==k:

            lsa.append(node)

            node_stored_position_sequence.append(count) #只是为了分析而用

            i=0

        last_node=node

        node=node.next

    if i>0:

        lsa.append(last_node)

    # print(node_stored_position_sequence)

    # 如果n=100的话,这里node_stored_position_sequence应该存了 [11, 22, 33, 44, 55, 66, 77, 88, 99]个node.

    # 到这一步为止 time用了2n, space用了K

    # -------第三步: 反向打印------

    # 我们已经存了每第sqrt(n)个node的位置, 那么要如何反过来呢?

    # 每一次我们pop一个node, 并且记录上一次被pop的那个.

    # 处理最后一个node就是:顺序 node = node.next地把结果存起来,存到之前存的那个为止

    # 比如我们存22号node, 就一路 node = node.next 的把结果保存到一个list里, 直到遇到33号为止

    # 存完[22, 23, 24... 32]之后, 我们反着打印. 反着打印花的时间是K.

    # 这样我们操作K次, 每次使用K的空间.

    # 一共space cost是K, time cost则是n+n + K*K = 3n =  O(n).

    start_node=lsa.pop()

    print(start_node.value)

    while lsa: # this happens K times. K = sqrt(K)

        last_printed_node=start_node

        start_node=lsa.pop()

        node=start_node

        ssa=[]

        while node!=last_printed_node:

            ssa.append(node)

            node=node.next

        # [print(v.value, end=" ") for v in ssa]

        # 如果打印的话, 这一步应该打印 sqrt(n) 次, 每一次打印一个 sqrt(n)长度的数组

        ssa.reverse()

        for node in ssa:

            print(node.value)

Q5 : Consider the problem of given an integer n, generating all possible permutations of {1,2,3...n}

  • 了解这道题里的复杂度分析是最重要的一点.

举个例子

permute(3) = [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]

显然 如果已经知道了permute(2), 那permute(3)则只需要在每一个permute(2)的任意一位置加入3这个数字 ,

[[1, 2], [2, 1]]

[[1,2,3], [1,3,2], [3,1,2]

[[2,1,3], [2,3,1], [3,2,1]].

所以, 时间复杂度由T(n) = n * T(n-1) + O(1) , 可以推出时间复杂度是 O(N!)

空间: O(N!) 因为要记录排列组合本身就需要O(N!)这么大的空间

  • recursive method(推荐)

def permute(n):

    '''

    :type n: int

    :rtype: List[List[int]]

    return the list contains each lists of permutation

    from {1,2,..n}

    '''

    l = []

    s = []

    v = [0 for i in range(n+1)]

    # 我们不用index 0的位置, 因为题目要求permute从1到n

    # 1 based index

    def dfs(l,s,v,index):

        #start is for the beginning position

        if index==n+1:

            l.append(s[:]) #记录当前组合

            return

        else:

            for i in range(1,n+1):

                if v[i]==0:

                    s.append(i)

                    v[i]=1

                    dfs(l,s,v,index+1)

                    v[i]=0

                    s.pop() #回溯操作

    dfs(l,s,v,1)

    return l

print(permute(3))

  • iterative method(Heap's algorithm)

def permute_iterative_heap_s_algorithm(n):

    """

    :type n: int

    :rtype: List[List[int]]

    """

    c = [0 for i in range(n)]

    A = [i+1 for i in range(n)]

    i = 0

    res= [A[:]]

    while i < n:

        if  c[i] < i:

            if i%2==0:

                A[0],A[i] = A[i], A[0]

            else:

                A[c[i]], A[i] = A[i],A[c[i]]

            res.append(A[:])

            c[i] += 1

            i = 0

        else:

            c[i] = 0

            i += 1



    return res

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,527评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,314评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,535评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,006评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,961评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,220评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,664评论 3 392
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,351评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,481评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,397评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,443评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,123评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,713评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,801评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,010评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,494评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,075评论 2 341

推荐阅读更多精彩内容