劍指offer全集python(1/3)第一大部分

目錄

2.使用python實現單例模式

3.二維數組中數的搜索

4.替換空格

5.從尾到頭打印單鏈表值

6.根據前序,中序構造二叉樹

7.使用2個棧實現隊列

8.旋轉數組的最小數字

9.斐波那契數列

14.調整數組順序使奇數位於偶數前面

15.鏈表中倒數第k個結點

16.反轉單鏈表

17.合併兩個有序的鏈表

18.樹的子結構

19.二叉樹的鏡像

20.順時針打印矩陣

21.包含min函數的棧

22. 棧的壓入彈出序列


2.使用python實現單例模式

#使用python 實現單例模式
#單例模式(Singleton Pattern)是一種常用的軟件設計模式,該模式的主要目的是確保某一個類只有一個實例存在。

#1.__new__ 是什麼
# __new__方法接受的參數雖然也是和__init__一樣,但__init__是在類實例創建之後調用,而 __new__方法正是創建這個類實例的方法。
# __new__ 方法必須返回值,__init__方法不需要返回值。

class Human(object):
    def __new__(cls, *agrs, **kwargs):
        a = object.__new__(cls, *agrs, **kwargs)
        print('__new__')
        print(a)
        return a  # __new__ 方法必須返回值,__init__方法不需要返回值。

    def __init__(self, name='lisi'):
        print('__init__')
        print(self)
        self.name = name
        
    def getName(self):
        print(self.name)

hu = Human() #不能傳參數
hu.getName()
#可以發現: __new__方法的調用是發生在__init__之前的
# __new__
# <__main__.Human object at 0x00000000021FF5F8>
# __init__
# <__main__.Human object at 0x00000000021FF5F8>
# lisi

# 對於int這種 不可變的對象,我們只有重載它的__new__方法才能起到自定義的作用, 而 __init__ 方法是不起作用的。   
class PositiveInteger(int):
    def __new__(cls, value):
        return super(PositiveInteger, cls).__new__(cls, abs(value))
    
poi = PositiveInteger(-3)
print(poi) # 3

#使用__new__ 實現單例模式
class Singlton(object):
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singlton, cls).__new__(cls, *args, **kwargs)
        return cls._instance

class myClass(Singlton):
    pass
    
a = myClass()
b = myClass()
print(a is b )  #True
print(a == b) #True 
print(id(a), id(b)) # 40345672 40345672

# 裝飾器: 它可以讓其他函數或類在不需要做任何代碼修改的前提下增加額外功能,裝飾器的返回值也是一個函數/類對象。裝飾器的作用就是爲已經存在的對象添加額外的功能
#初始的函數
def myFunc(): #需要增加功能的函數
    print('myFunc call')
    
def deco(func): # 將函數作爲參數
    def wrapper():
        print('before func') #假設爲增加的功能 1
        func()
        print('afther func')# 增加的功能2 
    return wrapper 

myFunc = deco(myFunc)
myFunc() #直接調用原來的函數
# before func
# myFunc call
# afther func

@deco  # 語法糖
def myFunc2():  #對函數進行功能擴展
    print('this is my Function2')
myFunc2() #@ 相當於省略了myFunc2 = deco(myFunc2)

#-----對帶有參數的函數進行功能擴展-----
def deco2(func):
    def wrapper(a, b):
        print('before func ')
        res = func(a, b)
        print('afther func')
        return res
    return wrapper 

@deco2 
def func2(a, b):
    print('res is %d'%(a+b))
    return a+b 

res = func2(2, 5)
print(res)

#-----對參數不確定數的函數進行功能擴展-----
def deco3(func):
    def wrapper(*args, **kwargs):
        print('before func')
        res = func(*args, **kwargs)
        print('afther func ')
        return res 
    return wrapper 

@deco3 
def func3(a, b, c, d):
    res = a+b+c+d
    print('sum is %d'%(res))
    return res 
func3(1, 2, 3, 4)

@deco3
def func4(a, b, c):
    res = a + b + c 
    print('sum is %d'%(res))
    return res 
func4(1, 2, 3)

#-----使用裝飾器實現單例模式-----

def singleton(cls, *args, **kwargs):
    instance = {}
    def getInstance():
        if cls not in instance:
            instance[cls] = cls(*args, **kwargs)
        return instance[cls]
    return getInstance

@singleton 
class myClass2(object):
    a = 1 

a = myClass2()
b = myClass2()
print(a is b)
print(a == b)

3.二維數組中數的搜索

編寫一個高效的算法來搜索 m x n 矩陣 matrix 中的一個目標值 target。該矩陣具有以下特性:

  • 每行的元素從左到右升序排列。
  • 每列的元素從上到下升序排列。

示例:

現有矩陣 matrix 如下:

[
  [1,   4,  7, 11, 15],
  [2,   5,  8, 12, 19],
  [3,   6,  9, 16, 22],
  [10, 13, 14, 17, 24],
  [18, 21, 23, 26, 30]
]

給定 target = 5,返回 true

給定 target = 20,返回 false

思路:從左下角或者右上角開始比較

class Solution(object):
    def searchMatrix(self, matrix, target):
        """
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
        """
        
        if not matrix:
            return False
        
        rows, cols = len(matrix), len(matrix[0])
        #從左下角開始搜索
        row, col = rows - 1, 0
        while row >= 0 and col <= cols-1:
            if matrix[row][col] == target:
                return True 
            elif matrix[row][col] < target:
                col += 1
            else:
                row -= 1 # row一直減少
        return False

4.替換空格

請實現一個函數,將一個字符串中的空格替換成“%20”。
  例如,當字符串爲We Are Happy.則經過替換之後的字符串爲We%20Are%20Happy。

 # 下列的字符串是 不可變對象,使用 + 操作時,會產生許多的對象,所以最好使用第二種方法

class Solution():
    
    def replaceSpace(self, s):
        if type(s) != str:
            return 
        new_s = ''
        for sr in s:
            if sr == ' ':
                new_s += '%20'
            else:
                new_s += sr 
        return new_s 
so = Solution()
s = ' ab c d e '
print(so.replaceSpace(s))
# %20ab%20c%20d%20e%20
print(s.replace(' ', '%20'))

第二種方法:轉換成列表形式

class Solution:
    def replaceSpace(self, s):
        if type(s) != str:
            return
        li = list(s)
        for i in range(len(li)):
            if li[i] == ' ':
                li[i] = '%20'
        res = "".join(li)
        return res
so = Solution()
s = ' ab c d e '
print(so.replaceSpace(s))

5.從尾到頭打印單鏈表值

# 從尾到頭依次打印單鏈表的值
class ListNode:
    def __init__(self, x=None):
        self.val = x
        self.next = None

class Solution:
    def printListFromTailToHead(self, listNode):
        if not listNode: #如果頭部結點爲空
            return 
        stack = []
        while listNode:
            stack.append(listNode.val)
            listNode = listNode.next 
        while stack:
            print(stack.pop())
#         return sorted(stack, reverse=True)   
 
    def printListFromTailToHead2(self, listNode):
        if not listNode:
            return 
        li = []
        while listNode:
            li.insert(0, listNode.val)
            listNode = listNode.next 
        return li 

node1 = ListNode(10)
node2 = ListNode(11)
node3 = ListNode(13)
node1.next = node2
node2.next = node3

singleNode = ListNode(12)

test = ListNode()

S = Solution()
print(S.printListFromTailToHead2(node1))
print(S.printListFromTailToHead2(test))
print(S.printListFromTailToHead2(singleNode))    

6.根據前序,中序構造二叉樹

根據一棵樹的前序遍歷與中序遍歷構造二叉樹。

注意:
你可以假設樹中沒有重複的元素。

例如,給出

前序遍歷 preorder = [3,9,20,15,7]  中, 左, 右
中序遍歷 inorder = [9,3,15,20,7]   左, 中, 右

返回如下的二叉樹:

    3
   / \
  9  20
    /  \
   15   7

思路:前序的第一個元素是根結點的值,在中序中找到該值,中序中該值的左邊的元素是根結點的左子樹,右邊是右子樹,然後遞歸的處理左邊和右邊

利用二叉樹前序遍歷和中序遍歷的特性。前序遍歷的第一個值一定爲根節點,對應於中序遍歷中間的一個點。在中序遍歷序列中,這個點左側的均爲根的左子樹,這個點右側的均爲根的右子樹。這時可以利用遞歸,分別取前序遍歷[1:i+1]和中序遍歷的[:i]對應與左子樹繼續上一個過程,取前序遍歷[i+1:]和中序遍歷[i+1]對應於右子樹繼續上一個過程,最終得以重建二叉樹。

'''
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。
假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。
例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。
'''

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    # 返回構造的TreeNode根節點
    def reConstructBinaryTree(self, pre, tin):
        if not pre or not tin: #只要一個數組爲空,則退出函數
            return 
        if set(pre) != set(tin):#如果數組中有重複元素
            return 
        
        root = TreeNode(pre[0])
        i = tin.index(pre[0])
        
        root.left = self.reConstructBinaryTree(pre[1: i+1], tin[: i])
        root.right = self.reConstructBinaryTree(pre[i+1: ], tin[i+1: ])
        return root
    
pre = [1, 2, 3, 5, 6, 4]
tin = [5, 3, 6, 2, 4, 1]
test = Solution()
newTree = test.reConstructBinaryTree(pre, tin)
print(newTree)
#中序遍歷
def inorder(newTree):
    if newTree:
        inorder(newTree.left)
        print(newTree.val)
        inorder(newTree.right)
inorder(newTree)

7.使用2個棧實現隊列

需要兩個棧Stack1和Stack2,push的時候直接push進Stack1。pop需要判斷Stack1和Stack2中元素的情況,Stack1空的話,直接從Stack2 pop,Stack1不空的話,把Stack1的元素push進入Stack2,然後pop Stack2的值。

1.push: 直接push進stack1。需要pop全部stack2,纔開始將stack1元素放進stack2中

2.pop:if stack2 不爲空,直接pop stack2; if stack2 爲空,需要將stack1元素全部放入stack2中,然後pop

# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.stack1 = []
        self.stack2 = []
        
    def push(self, node):
        # write code here
        self.stack1.append(node)
        
    def pop(self):
        # return xx
        if not self.stack1 and not self.stack2: 
            return 
        
        if not self.stack2: #如果stack2爲空
            while self.stack1:
                self.stack2.append(self.stack1.pop())
        return self.stack2.pop() 

延伸:兩個隊列實現棧:

# 使用兩個隊列實現棧
class Solution:
    def __init__(self): # 隊列 不是這個爲空就是 另一個爲空
        self.queue1 = []
        self.queue2 = []
        
    def push(self, node):
        if not self.queue2: # 如果隊列 2 爲空的話
            self.queue1.append(node)
        else:
            self.queue2.append(node)
    
    def pop(self):
        if not self.queue1 and not self.queue2:
            return 
        
        if not self.queue2:
            length = len(self.queue1)
            for i in range(length-1):
                self.queue2.append(self.queue1.pop(0)) # 將數組的依次首個元素彈出,只留下最後一個元素
            return self.queue1.pop() # 此時queue1 爲空
            
        else:
            length = len(self.queue2)
            for i in range(length-1):
                self.queue1.append(self.queue2.pop(0))
            return self.queue2.pop()
            
P = Solution()
P.push(10)
P.push(11)
P.push(12)
print(P.pop())
P.push(13)
print(P.pop())
print(P.pop())
print(P.pop())
print(P.pop())    

8.旋轉數組的最小數字

把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。
  輸入一個遞增排序的數組的一個旋轉,輸出旋轉數組的最小元素。
  例如數組{3,4,5,1,2}爲{1,2,3,4,5}的一個旋轉,該數組的最小值爲1。
  NOTE:給出的所有元素都大於0,若數組大小爲0,請返回0。

二分查找的變形,注意到旋轉數組的首元素肯定不小於旋轉數組的尾元素,設置中間點。如果中間點大於首元素,說明最小數字在後面一半,如果中間點小於尾元素,說明最小數字在前一半。依次循環。同時,當一次循環中首元素小於尾元素,說明最小值就是首元素。但是當首元素等於尾元素等於中間值,只能在這個區域順序查找。

 -*- coding:utf-8 -*-
class Solution:
    def minNumberInRotateArray(self, rotateArray):
        # write code here
        if not rotateArray:
            return 0
        
        length = len(rotateArray)
        left, right = 0, length-1
        if rotateArray[left] < rotateArray[right]: #如果第一個數都比最後一個數小,則代表沒有旋轉
            return rotateArray[left]
        
        minVal = rotateArray[0]
        while (right - left) > 1:
            mid = (left + right) // 2
            if rotateArray[mid] >= rotateArray[left]:
                left = mid 
            elif rotateArray[mid] <= rotateArray[right]:
                right = mid 
            elif rotateArray[right] == rotateArray[left] == rotateArray[mid]:
                for i in range(length):
                    if minVal > rotateArray[i]:
                        minVal = rotateArray[i]
                        right = i 
        minVal = rotateArray[right]
        return minVal
# -*- coding:utf-8 -*-
class Solution:
    def minNumberInRotateArray(self, rotateArray):
        # write code here
        if not rotateArray:
            return 0
        
        minIndex = 0
        left, right = 0, len(rotateArray)-1
        while rotateArray[left] >= rotateArray[right]:
            if right - left == 1:
                minIndex = right 
                break  #退出循環
            mid = (left + right) // 2
            if rotateArray[mid] >= rotateArray[left]:
                left = mid 
            elif rotateArray[mid] <= rotateArray[right]:
                right = mid 
            #特殊情況[1, 1, 0, 1]
            elif rotateArray[mid] == rotateArray[left] == rotateArray[right]:
                for i in range(len(rotateArray)):
                    if rotateArray[minIndex] > rotateArray[i]:
                        minIndex = i 
                        
        return rotateArray[minIndex]

不使用二分法

# -*- coding:utf-8 -*-
class Solution:
    def minNumberInRotateArray(self, rotateArray):
        # write code here
        if not rotateArray:
            return 0
        
        minVal = rotateArray[0]
        for i in range(len(rotateArray)):
            if minVal > rotateArray[i]:
                minVal = rotateArray[i]
                res = i 
        return rotateArray[res]

9.斐波那契數列

遞歸的形式

# -*- coding:utf-8 -*-
class Solution:
    def Fibonacci(self, n):
        # write code here
        a, b = 0, 1
        if n == 0:
            return 0 
        if n == 1:
            return 1 
        return self.Fibonacci(n-1) + self.Fibonacci(n-2)

非遞歸形式

# -*- coding:utf-8 -*-
class Solution:
    def Fibonacci(self, n):
        # write code here
        a, b = 0, 1
        if n == 0:
            return 0
        for i in range(n):
            a, b = b, a+b 
        return a 

14.調整數組順序使奇數位於偶數前面

題目描述

輸入一個整數數組,實現一個函數來調整該數組中數字的順序,使得所有的奇數位於數組的前半部分,所有的偶數位於數組的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。

# -*- coding:utf-8 -*-
class Solution:
    def reOrderArray(self, array):
        # write code here
        li1, li2 = [], []
        for ar in array:
            if ar % 2 == 1:
                li1.append(ar)
            else:
                li2.append(ar)
        return li1 + li2 
# -*- coding:utf-8 -*-
class Solution:
    def reOrderArray(self, array):
        # write code here
        left = [ar for ar in array if ar % 2 ==1]
        right = [ar for ar in array if ar % 2 == 0]
        return left + right 

15.鏈表中倒數第k個結點

輸入一個鏈表,輸出該鏈表中倒數第k個結點。

如果在只希望一次遍歷的情況下, 尋找倒數第k個結點, 可以設置兩個指針
第一個指針先往前走k-1步, 然後從第k步開始第二個指針指向頭結點  
然後兩個指針一起遍歷
當地一個指針指向尾節點的時候, 第二個指針正好指向倒數第k個結點  
   
# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def FindKthToTail(self, head, k):
        # write code here
        if not head or k <= 0:
            return None 
        
        pBehind = head  
        for i in range(k-1): #找到第 k-1 個結點
            if pBehind.next != None:
                pBehind = pBehind.next 
            else:
                return None

        pHead = head
        while pBehind.next != None: # 然後一起往前走
            pBehind = pBehind.next 
            pHead = pHead.next 
            
        return pHead 

 

16.反轉單鏈表

輸入的鏈表頭指針爲None或者整個鏈表只有一個結點時,反轉後的鏈表出現斷裂,返回的翻轉之後的頭節點不是原始鏈表的尾結點。因此需要引入一個翻轉後的頭結點,以及一個指向當前結點的指針,一個指向當前結點前一個結點的指針,一個指向當前結點後一個結點的指針,防止出現斷裂。推廣:遞歸實現反轉鏈表

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def reverseList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if not head or not head.next: #如果頭結點爲空,或者只有一個結點的haul
            return head 
        #x需要使用3 個結點
        then = head.next 
        head.next = None  #將頭結點的next指向空
        last = then.next 
        
        while then:
            then.next = head  #將其指向頭結點
            head = then  # 更新頭結點
            then = last 
            if then:
                last = then.next 
        return head

一種更爲簡單的實現方法;

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
__title__ = ''
__author__ = 'mike_jun'
__mtime__ = '2019-5-24'
#目的: 反轉單鏈表

"""
def reverseLink(head):
    #pass
    if not head or not head.next:
        return head
    p = head
    newHead = None
    while p:
        temp = p.next
        p.next = newHead
        newHead = p
        p = temp
    return newHead

#創建一個單鏈表
class Node():
    def __init__(self, values):
        self.next = None
        self.values = values

node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node4 = Node(4)
node1.next = node2
node2.next = node3
node3.next = node4

def printNode(head):
    result = []
    while head:
        result.append(head.values)
        head = head.next
    print(result)
printNode(node1)
newNode = reverseLink(node1)
printNode(newNode)

遞歸方法實現:

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回ListNode
    def ReverseList(self, pHead):
        # write code here
        if not pHead or not pHead.next:
            return pHead 
        else:
            reverseHead = self.ReverseList(pHead.next)
            pHead.next.next = pHead 
            pHead.next = None 
        return reverseHead

17.合併兩個有序的鏈表

輸入兩個單調遞增的鏈表,輸出兩個鏈表合成後的鏈表,當然我們需要合成後的鏈表滿足單調不減規則。

使用遞歸方法

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回合併後列表
    def Merge(self, pHead1, pHead2):
        # write code here
        if not pHead1: #如果一個鏈表不存在的話,返回另外一個鏈表
            return pHead2
        if not pHead2:
            return pHead1
        
        if pHead1.val <= pHead2.val:
            ret = pHead1
            ret.next = self.Merge(pHead1.next, pHead2)
        else:
            ret = pHead2
            ret.next = self.Merge(pHead1, pHead2.next)
            
        return ret 

2.非遞歸實現合併兩個有序的鏈表

#非遞歸實現合併兩個有序的鏈表
class Solution1:
    # 返回合併後列表
    def Merge(self, pHead1, pHead2):    
        if not pHead1:
            return pHead2
        if not pHead2:
            return pHead1
        
        start = None 
        p = None 
        while pHead1 and pHead2:
            if pHead1.val <= pHead2.val:
                print(pHead1.val)
                if start is None:
                    start = p = pHead1
                else:
                    p.next = pHead1
                    p = p.next #更新p 結點
                pHead1 = pHead1.next # 更新有序鏈表的結點
            else:
                if start is None:
                    start = p = pHead2
                else:
                    p.next = pHead2
                    p = p.next 
                pHead2 = pHead2.next 
        #可能某個鏈表一直還剩值
        if not pHead1: #如果第一個鏈表都是空的話
            p.next = pHead2
        else:
            p.next = pHead1
        return start 

18.樹的子結構

輸入兩棵二叉樹A,B,判斷B是不是A的子結構。(ps:我們約定空樹不是任意一個樹的子結構)

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def HasSubtree(self, pRoot1, pRoot2):
        # write code here
        result = False 
        if pRoot1 and pRoot2: #如果兩顆樹結點都不爲空
            if pRoot1.val == pRoot2.val:# 如果結點的值相同的話
                result = self.DoseSubtree(pRoot1, pRoot2)
            if not result: # 不相同,則判斷tree1 左子樹結構
                result = self.HasSubtree(pRoot1.left, pRoot2)
            if not result:
                result = self.HasSubtree(pRoot1.right, pRoot2)
        return result
                
    def DoseSubtree(self, pRoot1, pRoot2):
        if not pRoot2: #如果tree2 樹爲空的話,說明就是子樹
            return True 
        if not pRoot1:
            return False
        if pRoot1.val != pRoot2.val:
            return False
        
# 繼續判斷1,2左子樹和1,2右子樹
        return self.DoseSubtree(pRoot1.left, pRoot2.left) and self.DoseSubtree(pRoot1.right, pRoot2.right)

19.二叉樹的鏡像

題目描述

操作給定的二叉樹,將其變換爲源二叉樹的鏡像。

輸入描述:

二叉樹的鏡像定義:源二叉樹 
    	    8
    	   /  \
    	  6   10
    	 / \  / \
    	5  7 9 11
    	鏡像二叉樹
    	    8
    	   /  \
    	  10   6
    	 / \  / \
    	11 9 7  5

遞歸實現:

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回鏡像樹的根節點
    def Mirror(self, root):
        # write code here
        if not root:
            return None 
        if not root.left and not root.right:
            return root 
        root.left, root.right = root.right, root.left 
        self.Mirror(root.left)
        self.Mirror(root.right)

非遞歸,隊列實現

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回鏡像樹的根節點
    def Mirror(self, root):
        # write code here
        if not root:
            return None 
        nodeQue = [root]
        while len(nodeQue) > 0:
            nodeNum, count = len(nodeQue), 0
            while nodeNum > count:
                count += 1
                node = nodeQue.pop(0)
                node.left, node.right = node.right, node.left 
                if node.left:
                    nodeQue.append(node.left)
                if node.right:
                    nodeQue.append(node.right)

20.順時針打印矩陣

題目描述

輸入一個矩陣,按照從外向裏以順時針的順序依次打印出每一個數字,例如,如果輸入如下4 X 4矩陣: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

[[ 1, 2, 3, 4],
  [ 5, 6, 7, 8],
  [ 9, 10, 11, 12],
  [13, 14, 15, 16]]

則依次打印出數字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.

matrix類型爲二維列表,需要返回列表

# -*- coding:utf-8 -*-
class Solution:
    # matrix類型爲二維列表,需要返回列表
    def printMatrix(self, matrix):
        if matrix == None:
            return
        rows = len(matrix)
        columns = len(matrix[0])
        start = 0
        while rows > start * 2 and columns > start * 2:
            self.PrintMatrixInCircle(matrix, columns, rows, start)
            start += 1
        print('')

    def PrintMatrixInCircle(self, matrix, columns, rows, start):
        endX = columns - 1 - start
        endY = rows - 1 - start

        # 從左到右打印一行
        for i in range(start, endX+1):
            number = matrix[start][i]
            print(number, ' ', end='')

        # 從上到下打印一行
        if start < endY:
            for i in range(start+1, endY+1):
                number = matrix[i][endX]
                print(number, ' ', end='')

        # 從右到左打印一行
        if start < endX and start < endY:
            for i in range(endX-1, start-1, -1):
                number = matrix[endY][i]
                print(number, ' ', end='')

        # 從下到上打印一行
        if start < endX and start < endY-1:
            for i in range(endY-1, start, -1):
                number = matrix[i][start]
                print(number, ' ', end='')

21.包含min函數的棧

題目描述

定義棧的數據結構,請在該類型中實現一個能夠得到棧中所含最小元素的min函數(時間複雜度應爲O(1))。

# -*- coding:utf-8 -*-
class Solution:
    def __init__(self): #使用兩個棧來實現,兩個棧的大小是相同的
        self.stack = []
        self.minStack = []
    
    def push(self, node):
        # write code here
        self.stack.append(node)
        if not self.minStack or self.min() > node: # 將最小值增加到minStack中
            self.minStack.append(node)
        else:
            self.minStack.append(self.min())
        
    def pop(self):
        # write code here
        if self.stack and self.minStack:
            self.stack.pop()
            self.minStack.pop()
        else:
            return None 
        
    def top(self):
        # write code here
        return self.stack[-1]
    def min(self):
        # write code here
        return self.minStack[-1]

22. 棧的壓入彈出序列

輸入兩個整數序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否可能爲該棧的彈出順序。假設壓入棧的所有數字均不相等。例如序列1,2,3,4,5是某棧的壓入順序,序列4,5,3,2,1是該壓棧序列對應的一個彈出序列,但4,3,5,1,2就不可能是該壓棧序列的彈出序列。(注意:這兩個序列的長度是相等的)

建立一個輔助棧,把push序列的數字依次壓入輔助棧,每次壓入後,比較輔助棧的棧頂元素和pop序列的首元素是否相等,相等的話就推出pop序列的首元素和輔助棧的棧頂元素,若最後輔助棧爲空,則push序列可以對應於pop序列。

# -*- coding:utf-8 -*-
class Solution:
    def IsPopOrder(self, pushV, popV):
        # write code here
        if not pushV or not popV:
            return False 
        
        stack = [] #建立一個輔助的棧
        for val in pushV:
            stack.append(val)
            while popV and stack[-1] == popV[0]:
                stack.pop()
                popV.pop(0)
        if not stack: #如果輔助棧爲空的話,則表示正確
            return True 
        else:
            return False

劍指offer(2/3)第二大部分

劍指offer(3/3)第三大部分

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章