Python算法實戰-牛客刷題-劍指offer通關

目錄

 

二維數組中的查找

替換空格

從尾到頭打印鏈表

重建二叉樹

用兩個棧實現隊列

旋轉數組的最小數字

斐波那契數列

跳臺階

變態跳臺階

矩陣覆蓋

二進制中1的個數

數值的整數次方

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

鏈表中倒數第k個節點

反轉鏈表

合併兩個排序的鏈表

樹的子結構

二叉樹的鏡像

順時針打印矩陣

包含min函數的棧

棧的壓入彈出序列

從上往下打印二叉樹

二叉搜索樹的後序遍歷序列

二叉樹中和爲某一值的路徑

複雜鏈表的複製

二叉搜索樹與雙向鏈表

字符串的排列

數組中出現次數超過一半的數字

最小的k個數

連續子數組的最大和

整數中1出現的次數

把數組排成最小的數

醜數

第一次只出現1次的字符

數組中的逆序對

兩個鏈表的第一個公共節點

數字在排序數組中出現的次數

二叉樹的深度

平衡二叉樹

數組中只出現1次的數字

和爲S的連續正數序列

和爲S的兩個數字

左旋轉字符串

翻轉單詞順序列

撲克牌順子

孩子們的遊戲

求1+2+。。。n

不用加減乘除做加法

把字符串轉換成整數

數組中重複的數字

構建乘積數組

正則表達匹配

表示數值的字符串

字符流中第一個不重複的字符

鏈表中環的入口節點

刪除鏈表中重複的節點

二叉樹的下一個節點

對稱的二叉樹

按之字形順序打印二叉樹

把二叉樹打印成多行

序列化二叉樹

二叉搜索樹的第K的節點

數據流中的中位數

滑動窗口的最大值

矩陣中的路徑

機器人的運動範圍

剪繩子


二維數組中的查找

題目描述

在一個二維數組中(每個一維數組的長度相同),每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷數組中是否含有該整數。

# -*- coding:utf-8 -*-
class Solution:
    # array 二維列表
    def Find(self, target, array):
        # write code here
        flag = 0
        for i in array:
            for j in i:
                if target ==j:
                    flag = 1
        if flag ==1:
            return True
        else:
            return False

替換空格

題目描述

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

# -*- coding:utf-8 -*-
class Solution:
    # s 源字符串
    def replaceSpace(self, s):
        # write code here
        list_s = list(s)
        for index,i in enumerate(list_s):
            if i == " ":
                list_s[index] = "%20"
        s = "".join(list_s)
        return s

從尾到頭打印鏈表

題目描述

輸入一個鏈表,按鏈表從尾到頭的順序返回一個ArrayList。

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    # 返回從尾部到頭部的列表值序列,例如[1,2,3]
    def printListFromTailToHead(self, listNode):
        # write code here
        arraylist = []
        head = listNode
        p = head
        if listNode == None:
            return []
        while p != None:
            arraylist.append(p.val)
            p = p.next
        arraylist.reverse()
        return arraylist

重建二叉樹

題目描述

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

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回構造的TreeNode根節點
    def reConstructBinaryTree(self, pre, tin):
        # write code here
        # TODO:檢查是否爲空,若只有1個值的時候直接返回
        if len(pre)==0:
            return None
        if len(pre)==1:
            return TreeNode(pre[0])
        for index,i in enumerate(tin):
            if i == pre[0]:
                root_index = index
                break
        root = TreeNode(pre[0])
        root_left_tin = tin[:root_index]
        root_right_tin = tin[root_index+1:]
        #這裏可以改寫成index用法,index輸出序號位置,可以替代length
        root_left_pre = pre[1:len(root_left_tin)+1]
        root_right_pre = pre[len(root_left_tin)+1:]
        root.left = self.reConstructBinaryTree(root_left_pre,root_left_tin)
        root.right = self.reConstructBinaryTree(root_right_pre,root_right_tin)
        return root

用兩個棧實現隊列

題目描述

用兩個棧來實現一個隊列,完成隊列的Push和Pop操作。 隊列中的元素爲int類型。

# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.stack1 = []
        self.stack2  = []
    def push(self, node):
        # write code here
        self.stack1.append(node)
        return self.stack1
    def pop(self):
        # return xx
        self.stack2.append(self.stack1[0])
        del self.stack1[0]
        return self.stack2[-1]
        

旋轉數組的最小數字

題目描述

把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。
輸入一個非遞減排序的數組的一個旋轉,輸出旋轉數組的最小元素。
例如數組{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 len(rotateArray)==0:
            return 0
        min = rotateArray[0]
        for i in rotateArray:
            if i<min:
                min = i
        return min
            

斐波那契數列

題目描述

大家都知道斐波那契數列,現在要求輸入一個整數n,請你輸出斐波那契數列的第n項(從0開始,第0項爲0,第1項是1)。

n<=39

# -*- coding:utf-8 -*-
class Solution:
    def Fibonacci(self, n):
        # write code here
        first = 0
        second = 1
        while(n>0): #累加避免遞歸
            second = first + second
            first = second - first 
            n = n-1
        return first #這裏之所以要返回first,是因爲n差兩個位置
            

跳臺階

題目描述

一隻青蛙一次可以跳上1級臺階,也可以跳上2級。求該青蛙跳上一個n級的臺階總共有多少種跳法(先後次序不同算不同的結果)。

# -*- coding:utf-8 -*-
class Solution:
    def jumpFloor(self, number):
        # write code here
        first=1
        second =2
        while number>1:
            second = first+second
            first = second - first
            number = number-1
        return first

變態跳臺階

題目描述

一隻青蛙一次可以跳上1級臺階,也可以跳上2級……它也可以跳上n級。求該青蛙跳上一個n級的臺階總共有多少種跳法。

# -*- coding:utf-8 -*-
class Solution:
    def jumpFloorII(self, number):
        # write code here
        #1 2 4 8
        return pow(2,number-1)

矩陣覆蓋

題目描述

我們可以用2*1的小矩形橫着或者豎着去覆蓋更大的矩形。請問用n個2*1的小矩形無重疊地覆蓋一個2*n的大矩形,總共有多少種方法?

比如n=3時,2*3的矩形塊有3種覆蓋方法:

# -*- coding:utf-8 -*-
class Solution:
    def rectCover(self, number):
        # write code here
        while number == 0:
            return number
        first = 1
        second = 2
        while number>=2:
            second = first + second
            first = second -first
            number = number-1
        return first
            
        #這裏的number也是width,height固定
        
        

二進制中1的個數

題目描述

輸入一個整數,輸出該數二進制表示中1的個數。其中負數用補碼錶示。

# -*- coding:utf-8 -*-
class Solution:
    def NumberOf1(self, n):
        # write code here
        number = 0
        for i in range(32):
            #整數具有32位,右移n位相當於除以2的n次方,&爲位運算,即比較2,3,4...32位是否爲1
            if (n>>i) & 1 != 0:
                number = number+1
        return number

數值的整數次方

題目描述

給定一個double類型的浮點數base和int類型的整數exponent。求base的exponent次方。

保證base和exponent不同時爲0

# -*- coding:utf-8 -*-
class Solution:
    def Power(self, base, exponent):
        # write code here
        return pow(base,exponent)

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

題目描述

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

# -*- coding:utf-8 -*-
class Solution:
    def reOrderArray(self, array):
        # write code here
        jishu = []
        oushu = []
        if len(array)==0:
            return []
        for i in array:
            if i%2==0:
                oushu.append(i)
            else :
                jishu.append(i)
        return jishu + oushu

鏈表中倒數第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 (head== None) or (k<=0):
            return None
        p1 = head
        p2 = head
        count = 0
        #因爲0本身就要運行一次,所以這裏設置爲k-1
        while count<k-1:
            if p2.next != None:
                p2 = p2.next
                count = count+1
            else:
                return None
        while p2.next != None:
            p1 = p1.next
            p2 = p2.next
        return p1

反轉鏈表

題目描述

輸入一個鏈表,反轉鏈表後,輸出新鏈表的表頭。

# -*- 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
        #本來需要考慮pHead.next的情況,但是檢查程序時發現下面包含了
        if pHead == None:
            return None
        pre = None
        cur = pHead
        while cur != None:
            temp = cur.next #先存起來準備遍歷,不然不好向下走
            cur.next = pre #翻轉鏈表
            pre = cur #總是標誌前一個
            cur = temp #這裏準備向下走
        return pre #最後的pre就是cur的所在地,curl在上一輪爲None了
        
            
            
            
        
            

合併兩個排序的鏈表

題目描述

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

# -*- 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
        mergeHead = ListNode(100) #設置一個足夠大的數,前面head設爲空節點,返回next即可
        cur = mergeHead
        while pHead1 and pHead2:
            #確定指針移到哪個鏈表上
            if pHead1.val <pHead2.val:
                mergeHead.next = pHead1
                pHead1 = pHead1.next
            else:
                mergeHead.next = pHead2
                pHead2 = pHead2.next
            mergeHead = mergeHead.next #指針要移動
        if pHead1 == None:
            mergeHead.next = pHead2
        else:
            mergeHead.next = pHead1
        # return mergeHead 如果這裏這麼返回mergeHead指向鏈表的部分,不行
        return cur.next
                
                    
            
            

樹的子結構

題目描述

輸入兩棵二叉樹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
        if pRoot1 == None or pRoot2 ==None:
            return False
        # 左右子樹是否存在其子結構,這裏已經不是空樹了
        return self.IsSubtree(pRoot1,pRoot2) or self.HasSubtree(pRoot1.left,pRoot2) or self.HasSubtree(pRoot1.right,pRoot2)
        
    def IsSubtree(self,A,B):
        if B==None:
            return True
        if A == None or A.val!=B.val:
            return False
        return self.IsSubtree(A.left,B.left) and self.IsSubtree(A.right,B.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
        root.left,root.right = root.right,root.left #python支持對象的交換
        self.Mirror(root.left) #因爲已經交換過了,直接在下一層進行交換
        self.Mirror(root.right)
        return root
    

順時針打印矩陣

題目描述

輸入一個矩陣,按照從外向裏以順時針的順序依次打印出每一個數字,例如,如果輸入如下4 X 4矩陣: 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.

# -*- coding:utf-8 -*-
class Solution:
    # matrix類型爲二維列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        res = []
        if matrix == None:
            return res
        low,high,left,right = 0,len(matrix)-1,0,len(matrix[0])-1 #進行方向標記
        
        while low<=high and left<=right:
            # 先向右
            for i in range(left,right+1):
                res.append(matrix[low][i])
            # 再向下
            for i in range(low+1,high+1):
                res.append(matrix[i][right])
            # 再向左(考慮只有1行的情況,避免重複訪問)
            if low<high:
                for i in range(right-1,left-1,-1):
                    res.append(matrix[high][i])
            #再向上(考慮只有1列)
            if left<right:
                for i in range(high-1,low,-1):
                    res.append(matrix[i][left])
            left = left+1
            right = right-1
            low = low+1
            high = high-1
        return res
                
        
        
        
            
            

包含min函數的棧

題目描述

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

注意:保證測試中不會當棧爲空的時候,對棧調用pop()或者min()或者top()方法。

# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.stack = []
        self.min_stack = []
    def push(self, node):
        # write code here
        self.stack.append(node)
        if self.min_stack ==[] or node<=self.min_stack[-1]:
            self.min_stack.append(node)
    def pop(self):
        # write code here
        if self.stack == []:
            return None
        #這裏一定不能忘記判斷
        if self.stack[-1]==self.min_stack[-1]:
            self.min_stack.pop()
        self.stack.pop()
    def top(self):
        # write code here
        if self.stack ==[]:
            return None
        return self.stack[-1]
    def min(self):
        # write code here
        return self.min_stack[-1]

棧的壓入彈出序列

題目描述

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

# -*- coding:utf-8 -*-
class Solution:
    def IsPopOrder(self, pushV, popV):
        # write code here
        if not pushV or len(popV) != len(pushV):
            return False
        new_stack = [] #用於模擬塞入數據
        #j=0
        for i in pushV:
            new_stack.append(i)
            #while new_stack[-1] == popV[0] and len(new_stack):
            while len(new_stack) and new_stack[-1] == popV[0]:
                new_stack.pop()
                popV.pop(0) #pop順序也要移動,傳入0代表從左邊出棧
        if len(new_stack):
            return False
        return True
                

從上往下打印二叉樹

題目描述

從上往下打印出二叉樹的每個節點,同層節點從左至右打印。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回從上到下每個節點值列表,例:[1,2,3]
    def PrintFromTopToBottom(self, root):
        # write code here
        #廣度遍歷
        if not root:
            return []
        val = [] #存入值
        node = [root] #存入節點
        while len(node):
            t = node.pop(0) #隊列的思想
            val.append(t.val)
            if t.left:
                node.append(t.left)
            if t.right:
                node.append(t.right)
        return val

二叉搜索樹的後序遍歷序列

題目描述

輸入一個整數數組,判斷該數組是不是某二叉搜索樹的後序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的數組的任意兩個數字都互不相同。

# -*- coding:utf-8 -*-
class Solution:
    def VerifySquenceOfBST(self, sequence):
        # write code here
        if not sequence:
            return False
        return self.IsBST(sequence,0,len(sequence)-1) #判斷是否是二叉搜索樹
    
    def IsBST(self,array,start,end):
        if start >= end:
            return True # 可以直接比較,就一個節點
        #下面應該尋找i分界線,分爲左右子樹,準備遞歸
        i = end -1
        #遍歷時候先遍歷右子樹,所以都比根節點小,從後往前找分界點
        while i>start and array[i]>array[end]:
            i = i-1
        #下面遍歷前半部分,即左子樹
        j = 0
        for j in range(i-1,start-1,-1):
            if array[j]>array[end]:
                return False
        return self.IsBST(array,start,i-1) and self.IsBST(array,i,end-1)
            
            
    
        
        

二叉樹中和爲某一值的路徑

題目描述

輸入一顆二叉樹的根節點和一個整數,打印出二叉樹中結點值的和爲輸入整數的所有路徑。路徑定義爲從樹的根結點開始往下一直到葉結點所經過的結點形成一條路徑。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回二維列表,內部每個列表表示找到的路徑
    def FindPath(self, root, expectNumber):
        # write code here
        #本質是個深度遍歷
        if not root:
            return []
        if not root.left and not root.right and  root.val == expectNumber:
            return [[root.val]]
        res = [] #這裏面存的對象應該是列表
        left = self.FindPath(root.left,expectNumber-root.val)
        right = self.FindPath(root.right,expectNumber-root.val)
        for i in left+right:
            res.append([root.val]+i)
        return res
            
        
        
        

複雜鏈表的複製

題目描述

輸入一個複雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針random指向一個隨機節點),請對此鏈表進行深拷貝,並返回拷貝後的頭結點。(注意,輸出結果中請不要返回參數中的節點引用,否則判題程序會直接返回空)

# -*- coding:utf-8 -*-
# class RandomListNode:
#     def __init__(self, x):
#         self.label = x
#         self.next = None
#         self.random = None
class Solution:
    # 返回 RandomListNode
    def Clone(self, pHead):
        # write code here
        if not pHead:
            return None
        cur = pHead
        # 進行節點的複製
        while cur!=None:#這裏不能使用not
            clone = RandomListNode(cur.label)
            nextnode = cur.next
            cur.next = clone
            clone.next = nextnode
            cur = nextnode #進行遍歷插入
        # 第二趟遍歷,進行random的複製,random存在原random的下一個節點
        cur = pHead
        while cur!= None:
            cur.next.random = cur.random.next if cur.random else None
            cur = cur.next.next
        # 進行拆分鏈表,通過斷開鏈接的方式
        cur = pHead
        cloneList = pHead.next
        while cur!=None:
            clone = cur.next
            cur.next = clone.next
            clone.next = clone.next.next if clone.next else None
            cur = cur.next
        return cloneList
            
            
        

二叉搜索樹與雙向鏈表

題目描述

輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。

要求不能創建任何新的結點,只能調整樹中結點指針的指向。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def Convert(self, root):
        # write code here
        # 下面是遞歸版本
        '''if not pRootOfTree:
            return None
        if not pRootOfTree.left and not pRootOfTree.right:
            return pRootOfTree
        # 先遍歷左子樹
        left = self.Convert(pRootOfTree.left)
        p = left
        while left and p.right:
            # 找到左子樹遍歷的最右節點,也就是對應鏈表的最右邊
            p = p.right
        # 加入根節點
        if left:
            p.right = pRootOfTree
            pRootOfTree.left = p
        right = self.Convert(pRootOfTree)
        # 加入右子樹
        if right:
            right.left = pRootOfTree
            pRootOfTree.right = right
        return left if left else root'''
        # 非遞歸要掌握
        if not root:
            return None
        stack= []
        resStack =[]
        p = root
        # 這個中序遍歷的非遞歸寫的太好; 
        while p or stack:
            if p:
                stack.append(p)
                p = p.left
            else:
                node = stack.pop()
                resStack.append(node)
                p = node.right
                
        resP = resStack[0]
        while resStack:
            top = resStack.pop(0) #從前向後pop()
            if resStack:
                top.right = resStack[0]
                resStack[0].left = top
        return resP
            
                

字符串的排列

題目描述

輸入一個字符串,按字典序打印出該字符串中字符的所有排列。例如輸入字符串abc,則打印出由字符a,b,c所能排列出來的所有字符串abc,acb,bac,bca,cab和cba。

輸入描述:

輸入一個字符串,長度不超過9(可能有字符重複),字符只包括大小寫字母。
# -*- coding:utf-8 -*-
class Solution:
    def Permutation(self, ss):
        # write code here
        if len(ss) <=1:
            return ss
        res = set() # 去重
        for i in range(len(ss)):
            for j in self.Permutation(ss[:i]+ss[i+1:]):
                res.add(ss[i]+j)
        return sorted(list(res))
            

數組中出現次數超過一半的數字

題目描述

數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。例如輸入一個長度爲9的數組{1,2,3,2,2,2,5,4,2}。由於數字2在數組中出現了5次,超過數組長度的一半,因此輸出2。如果不存在則輸出0。

# -*- coding:utf-8 -*-
class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        # write code here
        partlength = int(len(numbers)/2)
        # 使用一個字典存儲個數
        #dictnum = collections.defaultdict()
        dictnum = {}
        for i in numbers:
            #dictnum[numbers[i]].value +1 if value else 0
            if i not in dictnum.keys():
                dictnum[i] = 1
            else :
                dictnum[i] = dictnum[i] + 1
        # 遍歷檢查
        #for key , value in dictnum:
            #if value > partlength:
                #return key
        #return 0
        for key,value in dictnum.items():
            if value >= partlength+1:
                return key
        return 0
            
        

最小的k個數

題目描述

輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,。

# -*- coding:utf-8 -*-
class Solution:
    def GetLeastNumbers_Solution(self, tinput, k):
        # write code here
        if k > len(tinput):
            return []
        
        sortedTinput = sorted(tinput)
        return sortedTinput[:k]

連續子數組的最大和

題目描述

HZ偶爾會拿些專業問題來忽悠那些非計算機專業的同學。今天測試組開完會後,他又發話了:在古老的一維模式識別中,常常需要計算連續子向量的最大和,當向量全爲正數的時候,問題很好解決。但是,如果向量中包含負數,是否應該包含某個負數,並期望旁邊的正數會彌補它呢?例如:{6,-3,-2,7,-15,1,2,2},連續子向量的最大和爲8(從第0個開始,到第3個爲止)。給一個數組,返回它的最大連續子序列的和,你會不會被他忽悠住?(子向量的長度至少是1)

# -*- coding:utf-8 -*-
class Solution:
    def FindGreatestSumOfSubArray(self, array):
        # write code here
        arraysum = []
        if not array:
            return None
        if len(array)==1:
            return array[0]
        maxsum = float('-inf')
        for i in range(len(array)):
            # 都記錄下來即可
            if maxsum<array[i]:
                maxsum = array[i]
            temp = array[i]
            #maxsum都是與和作比較,但是沒有和數作比較,所以前面得加上判斷
            for j in array[i+1:]:
                temp = temp + j
                if temp > maxsum:
                    maxsum = temp
        return maxsum
            
            
            

整數中1出現的次數

題目描述

求出1~13的整數中1出現的次數,並算出100~1300的整數中1出現的次數?爲此他特別數了一下1~13中包含1的數字有1、10、11、12、13因此共出現6次,但是對於後面問題他就沒轍了。ACMer希望你們幫幫他,並把問題更加普遍化,可以很快的求出任意非負整數區間中1出現的次數(從1 到 n 中1出現的次數)。

# -*- coding:utf-8 -*-
class Solution:
    def NumberOf1Between1AndN_Solution(self, n):
        # write code here
        # 每次都是考慮一個數位上的1出現次數
        count = 0 #1的個數
        i = 1 # 切分位置
        cur,after,before = 0,0,0
        #這裏想百位就好理解,即i =100
        while n/i !=0:
            cur = (n/i) %10 #當前位
            before = n/(i*10) # 高位
            after = n-(n/i)*i # 低位
            if cur ==0:
                count +=before*i #百位上的1僅由高位決定
            elif cur ==1:
                count +=before*i + after+1 # 百位上的1由高位低位共同決定
            else:
                count+= (before+1)*i #僅由高位決定
                
            i = i*10
            
        return count

把數組排成最小的數

題目描述

輸入一個正整數數組,把數組裏所有數字拼接起來排成一個數,打印能拼接出的所有數字中最小的一個。例如輸入數組{3,32,321},則打印出這三個數字能排成的最小數字爲321323。

# -*- coding:utf-8 -*-
class Solution:
    def PrintMinNumber(self, numbers):
        # write code here
        # 不要想多,就是兩兩比較,最後串起來
        length = len(numbers)
        if length ==0:
            return ''
        # 最後一個不用比較
        for i in range(length-1):
            for j in range(length-i-1):
                if int(str(numbers[j])+str(numbers[j+1]))>int(str(numbers[j+1])+str(numbers[j])):
                    numbers[j+1],numbers[j] = numbers[j],numbers[j+1]
                    
        return int(''.join(str(i) for i in numbers))

醜數

題目描述

把只包含質因子2、3和5的數稱作醜數(Ugly Number)。例如6、8都是醜數,但14不是,因爲它包含質因子7。 習慣上我們把1當做是第一個醜數。求按從小到大的順序的第N個醜數。

# -*- coding:utf-8 -*-
class Solution:
    def GetUglyNumber_Solution(self, index):
        # write code here
        if index<=0:
            return False
        if index ==1:
            return 1
        ugly = [1]
        indextwo = 0
        indexthree = 0
        indexfive = 0
        for i in range(1,index):
            # 沒必要維護三個隊列,記錄位置即可
            ugly.append(min(ugly[indextwo]*2,ugly[indexthree]*3,ugly[indexfive]*5))
            if ugly[i] == ugly[indextwo]*2:
                # 如果是從某個隊列添加的,則該隊列+1,之所以可以這樣是因爲基礎數變了,以醜數隊列爲基準
                # 醜數隊列中總是最小的數*2,3,5得出的
                indextwo +=1
            if ugly[i] ==ugly[indexthree]*3:
                indexthree +=1
            if ugly[i] == ugly[indexfive]*5:    
                indexfive +=1
        return ugly[index-1]

第一次只出現1次的字符

題目描述

在一個字符串(0<=字符串長度<=10000,全部由字母組成)中找到第一個只出現一次的字符,並返回它的位置, 如果沒有則返回 -1(需要區分大小寫).(從0開始計數)

# -*- coding:utf-8 -*-
class Solution:
    def FirstNotRepeatingChar(self, s):
        # write code here
        if len(s)==0:
            return -1
        if len(s)==1:
            return 0
        dic = {}
        for i in s:
            if i not in dic.keys():
                dic[i] = 1
            else:
                dic[i] +=1
        # 這裏注意字典是無序的
        for index,i in enumerate(s):
            if dic[i] ==1:
                return index
        return -1
            

數組中的逆序對

題目描述

在數組中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個數組中的逆序對的總數P。並將P對1000000007取模的結果輸出。 即輸出P%1000000007

輸入:1,2,3,4,5,6,7,0 輸出 :7

# -*- coding:utf-8 -*-
count = 0
#class Solution:
    #def InversePairs(self, data):
        # write code here
        #if len(data)<=1:
            #return 0
        #count  = 0
        #for cur in range(len(data)-1,0,-1): # 當前數,從後向前
            #for j in range(len(data)-len(data[cur:])):
                #if data[j] > data[cur]:
                    #count +=1
        #return count % 1000000007
        #count = 0
class Solution:
    def InversePairs(self, data):
        global count
        self.MergeSort(data)
        return count%1000000007
    
    def MergeSort(self,lists):
        global count
        if len(lists) <= 1:
            return lists
        num = int(len(lists)/2)
        left = self.MergeSort(lists[:num])
        right = self.MergeSort(lists[num:])
        r, l=0, 0
        result=[]
        while l<len(left) and r<len(right):
            if left[l] < right[r]:
                result.append(left[l])
                l += 1
            else:
                result.append(right[r])
                r += 1
                # 剩餘的左邊的數都大於右邊的那個數 所以加len(left)-l
                count += len(left)-l
        result += right[r:] # 這裏是某個數組過長
        result += left[l:]
        return result

        
        
        

        

兩個鏈表的第一個公共節點

題目描述

輸入兩個鏈表,找出它們的第一個公共結點。(注意因爲傳入數據是鏈表,所以錯誤測試數據的提示是用其他方式顯示的,保證傳入數據是正確的)

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        # write code here
        cur1 = pHead1
        cur2 = pHead2
        if cur1==None or cur2==None:
            return None
        while cur1!=cur2:
            # ENTJ : 如果沒有公共點,兩個指針會同時到達null,然後跳出循環,不會死循環的
            # 比較下一個
            cur1 = cur1.next
            cur2 = cur2.next
            if cur1 != cur2:
                # 這裏有個特殊情況,即二者有一方爲None的時候,鏈接兩個鏈表使其等長
                # 這裏已經是next了,無需再寫cur.next
                if cur1 == None: cur1 = pHead2
                if cur2 == None: cur2 = pHead1
        return cur1

數字在排序數組中出現的次數

題目描述

統計一個數字在排序數組中出現的次數。

# -*- coding:utf-8 -*-
class Solution:
    def GetNumberOfK(self, data, k):
        # write code here
        if len(data)==0 or k>data[-1]:
            return 0
        mid = 0
        left =0
        right =len(data)-1
        count =0
        while left<=right:
            mid = int((left+right)/2)
            if data[mid]<k:
                # 中位數小於指定數字
                left = mid+1
            elif data[mid]>k:
                right = mid-1
            else:
                break
        # 找到了就向前向後找
        if left <=right:
            for i in range(mid,-1,-1):
                if data[i] ==k:
                    count+=1
                else:
                    # 找到第一個就別找了
                    break
            for i in range(mid+1,len(data)):
                if data[i]==k:
                    count +=1
                else:
                    break
                    
        return count
                
                
 

二叉樹的深度

題目描述

輸入一棵二叉樹,求該樹的深度。從根結點到葉結點依次經過的結點(含根、葉結點)形成樹的一條路徑,最長路徑的長度爲樹的深度。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def TreeDepth(self, pRoot):
        # write code here
        #if not pRoot:
         #   return 0
        #left = self.TreeDepth(pRoot.left)
        #right = self.TreeDepth(pRoot.right)
        #res = left + 1 if left>right else right+1
        #return res
        # 下面使用層序遍歷
        if not pRoot:
            return 0
        high = 0
        queue = [pRoot]
        while queue!= []:
            childqueue = []
            for node in queue:
                if node.left:
                    childqueue.append(node.left)
                if node.right:
                    childqueue.append(node.right)
            queue = childqueue
            high +=1
        return high
            
        
        
        

平衡二叉樹

題目描述

輸入一棵二叉樹,判斷該二叉樹是否是平衡二叉樹。

注意:

在這裏,我們只需要考慮其平衡性,不需要考慮其是不是排序二叉樹

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def IsBalanced_Solution(self, pRoot):
        # write code here
        if not pRoot:
            return True # 前提搞清楚空子樹是不是平衡二叉樹
        left = self.depth(pRoot.left)
        right = self.depth(pRoot.right)
        #if (left-right) != (-1) or (left-right)!=1:
        if abs(left - right) >1:
            return False
        return self.IsBalanced_Solution(pRoot.left) and self.IsBalanced_Solution(pRoot.right)
        
    
    
    def depth(self,root):
        if not root:
            return 0
        left = self.depth(root.right)
        right = self.depth(root.left)
        return max(left,right)+1

        
        
        
        

 

數組中只出現1次的數字

題目描述

一個整型數組裏除了兩個數字之外,其他的數字都出現了兩次。請寫程序找出這兩個只出現一次的數字。

# -*- coding:utf-8 -*-
class Solution:
    # 返回[a,b] 其中ab是出現一次的兩個數字
    def FindNumsAppearOnce(self, array):
        # write code here
        if len(array)<4:
            return False
        from collections import Counter
        array1 =Counter(array)
        res =[]
        for key,value in array1.items():
            if value ==1:
                res.append(key)
                
        return res

和爲S的連續正數序列

題目描述

小明很喜歡數學,有一天他在做數學作業時,要求計算出9~16的和,他馬上就寫出了正確答案是100。但是他並不滿足於此,他在想究竟有多少種連續的正數序列的和爲100(至少包括兩個數)。沒多久,他就得到另一組連續正數和爲100的序列:18,19,20,21,22。現在把問題交給你,你能不能也很快的找出所有和爲S的連續正數序列? Good Luck!

輸出描述:

輸出所有和爲S的連續正數序列。序列內按照從小至大的順序,序列間按照開始數字從小到大的順序
# -*- coding:utf-8 -*-
class Solution:
    def FindContinuousSequence(self, tsum):
        # write code here
        res = []
        # 最大的兩個數應該是二分之一
        for i in range(int(tsum/2)+1,0,-1):
            # 末尾數
            s = i
            sequence = [i] # 用於存放單個序列
            # 起始數從後向前
            for j in range(i-1,0,-1):
                # 向前遍歷
                sequence.append(j)
                s+=j
                if s==tsum:
                    sequence = sorted(sequence)# 序列內排序
                    res.append(sequence)
                    break
                if s>tsum:
                    break
         # 下面進行序列間排序
        res = sorted(res,key=lambda x:x[0])
        # res = [[],[]]
        return res

和爲S的兩個數字

題目描述

輸入一個遞增排序的數組和一個數字S,在數組中查找兩個數,使得他們的和正好是S,如果有多對數字的和等於S,輸出兩個數的乘積最小的。

輸出描述:

對應每個測試案例,輸出兩個數,小的先輸出。
# -*- coding:utf-8 -*-
class Solution:
    def FindNumbersWithSum(self, array, tsum):
        # write code here
        plow = 0
        phigh =len(array)-1
        res = []
        if not array:
            return []
        if array[phigh-1]+array[phigh]<tsum:
            return []
        # 下面使用雙指針思想
        while plow<phigh:
            sequence = []
            if array[plow]+array[phigh]==tsum:
                sequence.append(array[plow])
                sequence.append(array[phigh])
                res.append(sequence)
                plow +=1
                phigh-=1
            elif array[plow]+array[phigh]>tsum:
                phigh-=1 #一側指針動
            else:
                plow+=1
        # 輸出乘積最小的數
        res = sorted(res,key = lambda x:x[0]*x[1]) 
        # res=[[]]
        return res[0] if res else []

左旋轉字符串

題目描述

彙編語言中有一種移位指令叫做循環左移(ROL),現在有個簡單的任務,就是用字符串模擬這個指令的運算結果。對於一個給定的字符序列S,請你把其循環左移K位後的序列輸出。例如,字符序列S=”abcXYZdef”,要求輸出循環左移3位後的結果,即“XYZdefabc”。是不是很簡單?OK,搞定它!

# -*- coding:utf-8 -*-
class Solution:
    def LeftRotateString(self, s, n):
        # write code here
        if n >len(s):
            return ""
        if not s:
            return ""
        sp1,sp2 = s[:n],s[n:]
        res = sp2+sp1
        return res
        

翻轉單詞順序列

題目描述

牛客最近來了一個新員工Fish,每天早晨總是會拿着一本英文雜誌,寫些句子在本子上。同事Cat對Fish寫的內容頗感興趣,有一天他向Fish借來翻看,但卻讀不懂它的意思。例如,“student. a am I”。後來才意識到,這傢伙原來把句子單詞的順序翻轉了,正確的句子應該是“I am a student.”。Cat對一一的翻轉這些單詞順序可不在行,你能幫助他麼?

# -*- coding:utf-8 -*-
class Solution:
    def ReverseSentence(self, s):
        # write code here
        s_lis = s.split(' ')
        s_lis.reverse() #這裏注意返回的是一個None,是對原有序列的改變
        res = ' '.join(x for x in s_lis)
        return res
        

撲克牌順子

題目描述

LL今天心情特別好,因爲他去買了一副撲克牌,發現裏面居然有2個大王,2個小王(一副牌原本是54張^_^)...他隨機從中抽出了5張牌,想測測自己的手氣,看看能不能抽到順子,如果抽到的話,他決定去買體育彩票,嘿嘿!!“紅心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是順子.....LL不高興了,他想了想,決定大\小 王可以看成任何數字,並且A看作1,J爲11,Q爲12,K爲13。上面的5張牌就可以變成“1,2,3,4,5”(大小王分別看作2和4),“So Lucky!”。LL決定去買體育彩票啦。 現在,要求你使用這幅牌模擬上面的過程,然後告訴我們LL的運氣如何, 如果牌能組成順子就輸出true,否則就輸出false。爲了方便起見,你可以認爲大小王是0。

# -*- coding:utf-8 -*-
class Solution:
    def IsContinuous(self, numbers):
        # write code here
        if numbers ==[]:
            return False
        dic = {
            'J':11,
            'Q':12,
            'K':13,
            'A':1
        }
        # 進行異常值替換
        for number in numbers:
            if number in dic.keys():
                number = dic[number]
                
        # 下面檢查是不是順子
        count = 0 #統計爲王的數量
        cz = [] # 統計差值
        numbers.sort()
        for i in range(5):
            if numbers[i]==0:
                count +=1
        if count==4:
            return True
        # 存入差值
        for i in range(count,4):
            cz.append(numbers[i+1]-numbers[i])
        for i in cz:
            if i==0:
                return False
            if i ==1:
                continue
            if i >1:
                count =count -(i-1)
        if count !=0:
            return False
        return True
            
        

孩子們的遊戲

題目描述

每年六一兒童節,牛客都會準備一些小禮物去看望孤兒院的小朋友,今年亦是如此。HF作爲牛客的資深元老,自然也準備了一些小遊戲。其中,有個遊戲是這樣的:首先,讓小朋友們圍成一個大圈。然後,他隨機指定一個數m,讓編號爲0的小朋友開始報數。每次喊到m-1的那個小朋友要出列唱首歌,然後可以在禮品箱中任意的挑選禮物,並且不再回到圈中,從他的下一個小朋友開始,繼續0...m-1報數....這樣下去....直到剩下最後一個小朋友,可以不用表演,並且拿到牛客名貴的“名偵探柯南”典藏版(名額有限哦!!^_^)。請你試着想下,哪個小朋友會得到這份禮品呢?(注:小朋友的編號是從0到n-1)

注意:

如果沒有小朋友,請返回-1

# -*- coding:utf-8 -*-
class Solution:
    def LastRemaining_Solution(self, n, m):
        # write code here
        if n<1:
            return -1
        n_child = [i for i in range(n)]
        while len(n_child) >1:
            gift_child = (m-1)%len(n_child)
            # 取完禮物就走,根據索引刪除,這裏不對,不是從0重頭唱歌,而是下一位接着唱
            n_child.pop(gift_child)
            # 保證下一次唱歌的爲列表開頭
            n_child = n_child[gift_child:]+n_child[:gift_child]
        return n_child[0]

                
                
            

求1+2+。。。n

題目描述

求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等關鍵字及條件判斷語句(A?B:C)。

# -*- coding:utf-8 -*-
class Solution:
    def Sum_Solution(self, n):
        # write code here
        return sum(range(n+1))

不用加減乘除做加法

題目描述

寫一個函數,求兩個整數之和,要求在函數體內不得使用+、-、*、/四則運算符號。

# -*- coding:utf-8 -*-
class Solution:
    def Add(self, num1, num2):
        # write code here
        MAX = 0x7fffffff # 最大整數
        mask = 0xffffffff # 求補碼
        while num2 != 0: # 直到無進位
            num1, num2 = (num1 ^ num2), ((num1 & num2) << 1)
            num1 = num1 & mask #數
            num2 = num2 & mask # 進位
        return num1 if num1 <= MAX else ~(num1 ^ mask)

                    
            
        

把字符串轉換成整數

題目描述

將一個字符串轉換成一個整數,要求不能使用字符串轉換整數的庫函數。 數值爲0或者字符串不是一個合法的數值則返回0

輸入描述:

輸入一個字符串,包括數字字母符號,可以爲空
+2147483647
1a33

輸出描述:

如果是合法的數值表達則返回該數字,否則返回0
# -*- coding:utf-8 -*-
class Solution:
    def StrToInt(self, s):
        # write code here
        if s =='':
            return 0
        numList = ['0','1','2','3','4','5','6','7','8','9'] # 數字和index要相對應
        flag = 1
        if s[0] == '+' and len(s)>1: # 先解決符號問題
            flag = 1
            s = s[1:]
        if s[0] == '-' and len(s)>1:
            flag = -1
            s = s[1:]
        # 下面進行求和
        sum1 = 0
        for i in s:
            if i in numList:
                sum1 = sum1*10+ numList.index(i)
            else:
                return 0
        return flag*sum1
       

數組中重複的數字

題目描述

在一個長度爲n的數組裏的所有數字都在0到n-1的範圍內。 數組中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出數組中任意一個重複的數字。 例如,如果輸入長度爲7的數組{2,3,1,0,2,5,3},那麼對應的輸出是第一個重複的數字2。

# -*- coding:utf-8 -*-
class Solution:
    # 這裏要特別注意~找到任意重複的一個值並賦值到duplication[0]
    # 函數返回True/False
    def duplicate(self, numbers, duplication):
        # write code here
        from collections import Counter
        count = dict(Counter(numbers))
        for key ,value in count.items():
            if value > 1:
                duplication[0] =key
                return True
        return False

構建乘積數組

題目描述

給定一個數組A[0,1,...,n-1],請構建一個數組B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。不能使用除法。(注意:規定B[0] = A[1] * A[2] * ... * A[n-1],B[n-1] = A[0] * A[1] * ... * A[n-2];)

 

# -*- coding:utf-8 -*-
class Solution:
    def multiply(self, A):
        # write code here
        if not A:
            return []
        # 題目的意思是B[n] = B[n-1]*A[n-1]*A[i+1]...A[n-1],少了A[i]那一項的乘積
        # 不要看注意內容,太容易帶偏
        B = [1]*len(A)
        # 將B做切割,先看A[i-1]部分,記得i>=0
        for i in range(1,len(A)):
            B[i] = B[i-1]*A[i-1]
        # 下面看後面,當i = n-1時候,沒有後面,n-2時候*A[n-1],n-3時候*A[n-2]*A[n-1]
        tmp = 1 # 暫存乘積結果
        for i in range(len(A)-2,-1,-1):
            tmp = tmp*A[i+1]
            B[i] = B[i]*tmp
            
        return B
        
        # B[1]=A[0];B[2]=A[0]*A[1]

        #if len(A)<=0:
        #    return None
        #B = [1] *len(A)
        #if len(A)==1:
        #    B = A
        #    return B
        #for i in A:
        #    B[0] =B[0]*i
       # for i in range(1,len(B)):
        #    for j in range(i):
        #        B[i] = B[i]*A[j]
                
       # return B
         #這題和我想的不一樣啊,我覺得題目有問題
         
            
            


 

正則表達匹配

題目描述

請實現一個函數用來匹配包括'.'和'*'的正則表達式。模式中的字符'.'表示任意一個字符,而'*'表示它前面的字符可以出現任意次(包含0次)。 在本題中,匹配是指字符串的所有字符匹配整個模式。例如,字符串"aaa"與模式"a.a"和"ab*ac*a"匹配,但是與"aa.a"和"ab*a"均不匹配

# -*- coding:utf-8 -*-
class Solution:
    # s, pattern都是字符串
    def match(self, s, pattern):
        # write code here
        if len(s)==0 and len(pattern)==0:
            return True
        elif len(s)!=0 and len(pattern)==0:
            return False
        elif len(s)==0 and len(pattern)!=0:
            if len(pattern)>1 and pattern[1]=='*':
                # 因爲s爲空
                return self.match(s,pattern[2:])
            else:
                return False
        else:
            # pattern 第二個字符爲*
            if len(pattern)>1 and pattern[1] =='*':
                # s與pattern首位不同
                if s[0]!=pattern[0] and pattern[0]!='.':
                    return self.match(s,pattern[2:])
                else:
                    # pattern中*爲空;pattern中*爲1;【s後移1個,*可以多位匹配】
                    return self.match(s,pattern[2:]) or self.match(s[1:],pattern[2:]) or self.match(s[1:],pattern)
            else:
                if s[0]==pattern[0] or pattern[0]=='.':
                    return self.match(s[1:],pattern[1:])
                else:
                    return False
                    
        

表示數值的字符串

題目描述

請實現一個函數用來判斷字符串是否表示數值(包括整數和小數)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示數值。 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。

# -*- coding:utf-8 -*-
class Solution:
    def isNumeric(self, s):
        # write code here
        import re
        pattern = '[+-]?[0-9]*([.][0-9]*)?([eE][+-]?[0-9]+)?'
        return True if re.match(pattern,s).group() == s else False

字符流中第一個不重複的字符

題目描述

請實現一個函數用來找出字符流中第一個只出現一次的字符。例如,當從字符流中只讀出前兩個字符"go"時,第一個只出現一次的字符是"g"。當從該字符流中讀出前六個字符“google"時,第一個只出現一次的字符是"l"。

輸出描述:

如果當前字符流沒有存在出現一次的字符,返回#字符。
# -*- coding:utf-8 -*-
class Solution:
    # 返回對應char
    s = ''
    def FirstAppearingOnce(self):
        # write code here
        from collections import Counter
        count = Counter(self.s)
        for i in self.s:
            if count[i] ==1:
                return i
        return '#'
    def Insert(self, char):
        # write code here
        self.s += char

鏈表中環的入口節點

題目描述

給一個鏈表,若其中包含環,請找出該鏈表的環的入口結點,否則,輸出null。

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def EntryNodeOfLoop(self, pHead):
        # write code here
        fast = pHead
        low = pHead
        while(fast!=None and fast.next!=None):
            fast = fast.next.next
            low = low.next
            if fast ==low:
                break
        # 根據上面的退出條件寫一下!!!
        if fast==None or fast.next ==None:
            return None
        low = pHead
        while fast!=low:
            fast = fast.next
            low = low.next
            
        return low

刪除鏈表中重複的節點

題目描述

在一個排序的鏈表中,存在重複的結點,請刪除該鏈表中重複的結點,重複的結點不保留,返回鏈表頭指針。 例如,鏈表1->2->3->3->4->4->5 處理後爲 1->2->5

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def deleteDuplication(self, pHead):
        # write code here
        if not pHead:
            return None
        pPreNode = None #先前鏈接節點
        pNode = pHead #遍歷節點
        while pNode:
            pNext = pNode.next
            needDelete = False
            # 判斷是否相等
            if pNext and pNode.val ==pNext.val:
                needDelete = True
            if not needDelete:
                # 如果沒有重複
                pPreNode = pNode
                pNode = pNext
            else:
                #核心如果有重複
                deleteVal = pNode.val
                deleteNode = pNode #需要把源節點一起刪除
                # 刪除操作
                while deleteNode and deleteNode.val ==deleteVal:
                    pNext = deleteNode.next #保存後一個節點
                    del deleteNode # 刪除操作
                    deleteNode = pNext #刪除後移
                if not pPreNode:
                    #如果連頭結點都刪掉了
                    pHead = pNext # 就從下一個節點開始
                    
                else:
                    pPreNode.next = pNext
                pNode = pNext # 從該節點開始遍歷
        return pHead
                    

            
                
            

二叉樹的下一個節點

題目描述

給定一個二叉樹和其中的一個結點,請找出中序遍歷順序的下一個結點並且返回。注意,樹中的結點不僅包含左右子結點,同時包含指向父結點的指針。

# -*- coding:utf-8 -*-
# class TreeLinkNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#         self.next = None
class Solution:
    def GetNext(self, pNode):
        # write code her
        if not pNode:
            return None
        if pNode.right:
            # 存在右子樹
            pNode = pNode.right
            while pNode.left:
                pNode = pNode.left
            return pNode
        # 如果不存在右子樹,檢查其是否是父節點的左孩子
        while pNode.next:
            pRoot = pNode.next #指向父節點
            if pRoot.left == pNode:
                return pRoot
            else:
                pNode = pNode.next # 一直尋找父節點,直至當前節點爲父節點的左孩子
        return None # 沒找到的話

對稱的二叉樹

題目描述

請實現一個函數,用來判斷一顆二叉樹是不是對稱的。注意,如果一個二叉樹同此二叉樹的鏡像是同樣的,定義其爲對稱的。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def isSymmetrical(self, pRoot):
        # write code here
        # 這題使用遞歸
        if not pRoot:
            return True
        return self.issymmer(pRoot.left,pRoot.right)
    def issymmer(self,left,right):
        if not left and not right:
            return True
        if not left or not right:
            return False
        # 值相等且鏡像位置的子樹相等
        return left.val == right.val and self.issymmer(left.left,right.right) and self.issymmer(left.right,right.left)

按之字形順序打印二叉樹

題目描述

請實現一個函數按照之字形打印二叉樹,即第一行按照從左到右的順序打印,第二層按照從右至左的順序打印,第三行按照從左到右的順序打印,其他行以此類推。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def Print(self, pRoot):
        # write code here
        if not pRoot:
            return [] # 一般不要輕易返回None值
        queue = [pRoot]
        result = []
        # 先層序遍歷存進去再說,但稍微不同的是存列表
        while queue:
            res = []
            nextqueue = []
            for i in queue:
                res.append(i.val)
                if i.left:
                    nextqueue.append(i.left)
                if i.right:
                    nextqueue.append(i.right)
            queue = nextqueue
            result.append(res)
            
        for i in range(len(result)):
            if i %2!=0:
                # 逆序
                result[i].reverse() # 這個是對源數據進行反向,不會返回數據,注意reversed返回的是個迭代器
        return result

把二叉樹打印成多行

題目描述

從上到下按層打印二叉樹,同一層結點從左至右輸出。每一層輸出一行。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回二維列表[[1,2],[4,5]]
    def Print(self, pRoot):
        # write code here
        if not pRoot:
            return []
        
        result =[]
        queue = [pRoot]
        while queue:
            res = []
            nextqueue = []
            for i in queue:
                res.append(i.val)
                if i.left:
                    nextqueue.append(i.left)
                if i.right:
                    nextqueue.append(i.right)
            queue = nextqueue
            result.append(res)
        return result

序列化二叉樹

題目描述

請實現兩個函數,分別用來序列化和反序列化二叉樹

注意:

二叉樹的序列化是指:把一棵二叉樹按照某種遍歷方式的結果以某種格式保存爲字符串,從而使得內存中建立起來的二叉樹可以持久保存。序列化可以基於先序、中序、後序、層序的二叉樹遍歷方式來進行修改,序列化的結果是一個字符串,序列化時通過 某種符號表示空節點(#),以 ! 表示一個結點值的結束(value!)。

二叉樹的反序列化是指:根據某種遍歷順序得到的序列化字符串結果str,重構二叉樹。
舉例:例如,我們可以把一個只有根節點爲1的二叉樹序列化爲"1,",然後通過自己的函數來解析回這個二叉樹

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    flag = -1 # s標識位
    def Serialize(self, root):
        # write code here
        if not root:
            return '#'
        # 前序遍歷
        return str(root.val) + ','+ self.Serialize(root.left) +','+ self.Serialize(root.right)
    def Deserialize(self, s):
        # write code here
        self.flag +=1 #一定要加self
        lis = s.split(',')
        if self.flag >=len(s):
            # 當指針超過s時
            return None
        root = None # 設置一個節點
        if lis[self.flag]!= '#':
            root = TreeNode(int(lis[self.flag])) # 注意TreeNOde傳入的是一個值
            root.left = self.Deserialize(s)
            root.right = self.Deserialize(s)
        return root
            

 

二叉搜索樹的第K的節點

題目描述

給定一棵二叉搜索樹,請找出其中的第k小的結點。例如, (5,3,7,2,4,6,8)    中,按結點數值大小順序第三小結點的值爲4。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回對應節點TreeNode
    def __init__(self):
        self.result = []
    def KthNode(self, pRoot, k):
        # write code here
        # 中序遍歷會得到從小到大的順序
        #strr = self.KthNode(pRoot.left)+str(pRoot.val)+self.KthNode(pRoot.right)
        #global result
        #result = [] # 不能設在函數之外
        self.Zhongxu(pRoot)
        if k<=0 or len(self.result)<k: # 如果超過strr範圍,k<=0一般放前面
            return None
        return self.result[k-1]
    
    def Zhongxu(self,pRoot):
        if not pRoot:
            return None
        self.Zhongxu(pRoot.left)
        self.result.append(pRoot)
        self.Zhongxu(pRoot.right)
        
        

數據流中的中位數

題目描述

如何得到一個數據流中的中位數?如果從數據流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從數據流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。我們使用Insert()方法讀取數據流,使用GetMedian()方法獲取當前讀取數據的中位數。

# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.lis = []
        self.count = 0
    def Insert(self, num):
        # write code here
        self.lis.append(num)
        self.count +=1
    def GetMedian(self,n=None):
        # write code here
        self.lis = sorted(self.lis)
        if self.count == 0:
            return 0
        if self.count%2!=0:
            return self.lis[int(self.count/2)]
        else:
            return (self.lis[self.count/2]+self.lis[self.count/2 -1])/2.0

滑動窗口的最大值

題目描述

給定一個數組和滑動窗口的大小,找出所有滑動窗口裏數值的最大值。例如,如果輸入數組{2,3,4,2,6,2,5,1}及滑動窗口的大小3,那麼一共存在6個滑動窗口,他們的最大值分別爲{4,4,6,6,6,5}; 針對數組{2,3,4,2,6,2,5,1}的滑動窗口有以下6個: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。

# -*- coding:utf-8 -*-
class Solution:
    def maxInWindows(self, num, size):
        # write code here
        # 存在len(num)-size+1個滑動窗口
        if size>len(num):
            return []
        if size<=0:
            return []
        maxlis = []
        for i in range(len(num)-size+1):
            # 滑動窗口可以看做切片
            slic = num[i:i+size]
            maxlis.append(max(slic))
        return maxlis
            

矩陣中的路徑

題目描述

請設計一個函數,用來判斷在一個矩陣中是否存在一條包含某字符串所有字符的路徑。路徑可以從矩陣中的任意一個格子開始,每一步可以在矩陣中向左,向右,向上,向下移動一個格子。如果一條路徑經過了矩陣中的某一個格子,則該路徑不能再進入該格子。 例如

矩陣中包含一條字符串"bcced"的路徑,但是矩陣中不包含"abcb"路徑,因爲字符串的第一個字符b佔據了矩陣中的第一行第二個格子之後,路徑不能再次進入該格子。

# -*- coding:utf-8 -*-
class Solution:
    def hasPath(self, matrix, rows, cols, path):
        # write code here
        # 標誌位
        flag = [False]*rows*cols
        for i in range(rows):
            for j in range(cols):
                # 找起始點
                # 爲什麼不一樣??
                if self.judge(list(matrix),rows,cols,path,i,j,0,flag):
                    # 一維數組來判斷,k是path起始位
                    return True
        return False
    
    def judge(self,matrix,rows,cols,path,i,j,k,flag):
        index = i*cols+j #標誌位
        # 遞歸終止條件
        if i<0 or j<0 or i>=rows or j>=cols or matrix[index]!=path[k] or flag[index] ==True:
            return False
        if k == len(path)-1:
            return True
        # 首標誌位爲True
        flag[index] = True
        # 判斷是否能走
        if self.judge(matrix,rows,cols,path,i-1,j,k+1,flag) or self.judge(matrix,rows,cols,path,i+1,j,k+1,flag) or self.judge(matrix,rows,cols,path,i,j-1,k+1,flag) or self.judge(matrix,rows,cols,path,i,j+1,k+1,flag):
            return True
        flag[index] = False # 不通則還原標誌位
        return False

機器人的運動範圍

題目描述

地上有一個m行和n列的方格。一個機器人從座標0,0的格子開始移動,每一次只能向左,右,上,下四個方向移動一格,但是不能進入行座標和列座標的數位之和大於k的格子。 例如,當k爲18時,機器人能夠進入方格(35,37),因爲3+5+3+7 = 18。但是,它不能進入方格(35,38),因爲3+5+3+8 = 19。請問該機器人能夠達到多少個格子?

# -*- coding:utf-8 -*-
class Solution:
    #def movingCount(self, threshold, rows, cols):
        # write code here
       # count = rows*cols # 假設一開始全能到達
        #for i in range(rows):
           # for j in range(cols):
            #    if self.chai(i) + self.chai(j) > threshold:
             #       count -=1
       # return count
    
    #def chai(self,number):
      #  # 這個作用是對數字進行拆分,並返回其和
       # summ = 0
       # lis = map(int,list(str(number)))
       # summ = sum(lis)
       # return summ
    def __init__(self):
        self.count = 0
        
    def movingCount(self, threshold, rows, cols):
        arr = [[1 for _ in range(cols)] for _ in range(rows)]
        self.findway(0,0,threshold,arr) # 如果能到達則設爲1
        return self.count
    
    def findway(self,i,j,threshold,arr):
        # 遞歸停止條件
        if i<0 or j<0 or i>=len(arr) or j >=len(arr[0]):
            return 
        lis1 = list(map(int,list(str(i)))) # 字符串變數字的優化解法
        lis2 = list(map(int,list(str(j))))
        sum1 = sum(lis1)
        sum2 = sum(lis2)
        if sum1 +sum2>threshold or arr[i][j]!=1:
            return 
        # 如果可以走
        self.count +=1
        arr[i][j] = 0
        # 下面就是繼續走的遞歸了
        self.findway(i+1,j,threshold,arr)
        self.findway(i-1,j,threshold,arr)
        self.findway(i,j+1,threshold,arr)
        self.findway(i,j-1,threshold,arr)
        
        
        
        

剪繩子

題目描述

給你一根長度爲n的繩子,請把繩子剪成整數長的m段(m、n都是整數,n>1並且m>1),每段繩子的長度記爲k[0],k[1],...,k[m]。請問k[0]xk[1]x...xk[m]可能的最大乘積是多少?例如,當繩子的長度是8時,我們把它剪成長度分別爲2、3、3的三段,此時得到的最大乘積是18。

輸入描述:

輸入一個數n,意義見題面。(2 <= n <= 60) 8

輸出描述:

輸出答案。18
# -*- coding:utf-8 -*-
class Solution:
    def cutRope(self, number):
        # write code here
        # 這題可以用貪婪,但我選擇動態規劃
        if number <=1:
            return 0
        if number==2:
            return 1
        if number ==3:
            return 2
        # 下面是number>=4的情況
        space = [0]* (number+1) # 輔助空間需要包含0
        space[0] = 0
        space[1] = 1
        space[2] = 2
        space[3] = 3 #這裏f(x) = max(f(x-i)*f(i)),這裏兩個子部分可以不切,所以和上面值不同
        for i in range(4,number+1):
            maxx = 0 # 用於記錄每一個f(i)的最大值
            for j in range(i/2+1): # 這裏是對f(i)的切分,本質還是max(f(x-i)*f(i))
                maxx = max(maxx,space[j]*space[i-j])
            space[i] = maxx
        return space[number]
            
            
                

 

 

 

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