劍指offer 完整python題庫大全,附加答案

# !/usr/bin/python
# -*- coding: UTF-8 -*-
# import sys
# 1.在一個二維數組中(每個一維數組的長度相同),每一行都按照從左到右遞增的順序排序
# ,每一列都按照從上到下遞增的順序排序。請完成一個函數,
# # 輸入這樣的一個二維數組和一個整數,判斷數組中是否含有該整數。
# class Solution:
#     def Find(self, target, array):
#         n = len(array)
#         flag = False
#         for i in range(n):
#             if target in array[i]:
#                 flag = True
#                 break
#         return flag
#
# array = [9, 8, 7], [6, 5, 4], [3, 2, 1]
# target = 5
# s = Solution()
# print(s.Find(target,array))
#
#
# 2.請實現一個函數,將一個字符串中的每個空格替換成“%20”。例如,當字符串爲We Are Happy.則經過替換之後的字符串爲We%20Are%20Happy。
# class Solution:
#     def Replace(self, target):
#         target = target.replace(' ',"%20")
#         return target
#
# target = 'We Are Happy'
# s = Solution()
# print(s.Replace(target))
#
#
# 3.輸入一個鏈表,按鏈表從尾到頭的順序返回一個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):
#         l = []
#         for i in listNode:
#             l.insert(0,i)
#         return l
#
# a = [1,2,3]
# ss = Solution()
# print (ss.printListFromTailToHead(a))
#
#
# 4輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。
# 假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列 pre = {1,2,4,7,3,5,6,8}
# 和中序遍歷序列tin = {4,7,2,1,5,3,8,6},則重建二叉樹並返回。
# 二叉樹三種遍歷方式
# https://www.pianshen.com/article/7106254596/
#
# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#         #這裏踩坑 不要再None後面加,
# class Solution:
#     # 返回構造的TreeNode根節點
#     def reConstructBinaryTree(self, pre, tin):
#
#         if len(pre) == 0 or len(tin) == 0:
#             print "is over"
#             return None
#
#         root = TreeNode(pre[0])
#         print (pre[0])
#         for i in range(0, len(tin) ,1):
#             if pre[0] == tin[i]:
#                 root.left =  self.reConstructBinaryTree(pre[1:i+1],tin[0:i])
#                 root.right = self.reConstructBinaryTree(pre[i+1:len(pre)],tin[i+1:len(tin)])
#                 break
#         return root
#
# pre = [1,2,4,7,3,5,6,8]
# tin = [4,7,2,1,5,3,8,6]
# ss = Solution()
# root = ss.reConstructBinaryTree(pre,tin)
# print root
#
#
# 5.用兩個棧來實現一個隊列,完成隊列的Push和Pop操作。 隊列中的元素爲int類型
# 隊列先進先出的  棧是先進後出的
#
# -*- coding:utf-8 -*-
# class Solution:
#     def __init__(self):
#         self.s1 = []
#         self.s2 = []
#     def push(self, node): #插入直接往一個棧裏插入
#         self.s1.append(node)
#         print self.s1
#
#     def pop(self):
#
#         if len(self.s1) == 0:
#             return None
#         while len(self.s1) > 0:
#             self.s2.append(self.s1.pop())
#         node = self.s2.pop()
#
#         while len(self.s2) > 0:
#             self.s1.append(self.s2.pop())
#         return node
#
# ss = Solution()
# ss.push(1)
# ss.push(2)
# ss.push(3)
# ss.push(4)
# ss.push(5)
# print ss.pop()
# ss.push(6)
#
# 6把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。
# 輸入一個非遞減排序的數組的一個旋轉,輸出旋轉數組的最小元素。
# 例如數組{3,4,5,1,2}爲{1,2,3,4,5}的一個旋轉,該數組的最小值爲1。
# NOTE:給出的所有元素都大於0,若數組大小爲0,請返回0。
#
# 理解爲需要輸出該數組左邊他大的一個元素
#
# -*- coding:utf-8 -*-
# class Solution:
#     def minNumberInRotateArray(self, rotateArray):
#         if len(rotateArray) == 0:
#             return 0
#
#         res_min = rotateArray[0];
#         for i in range(len(rotateArray)-1):#這裏循環到從0開始倒數第二個元素
#             j = i + 1
#             if rotateArray[i] > rotateArray[j] and rotateArray[j] < res_min:
#                 res_min = rotateArray[j]
#         return res_min
#
# ss = Solution()
# rotateArray = [3,4,5,1,2]
# print  ss.minNumberInRotateArray(rotateArray)
#
# 7.大家都知道斐波那契數列,現在要求輸入一個整數n,請你輸出斐波那契數列的第n項(從0開始,第0項爲0)。
# n<=39
# -*- coding:utf-8 -*-
# class Solution:
#     def Fibonacci(self, n):
#         if n == 0:
#             return  0
#         if n == 1:
#             return 1
#         return self.Fibonacci(n - 1) + self.Fibonacci(n - 2)
#
# ss = Solution()
# for i in range(10):
#     print ss.Fibonacci(i)
#
# 8.一隻青蛙一次可以跳上1級臺階,也可以跳上2級。求該青蛙跳上一個n級的臺階總共有多少種跳法(先後次序不同算不同的結果)
# -*- coding:utf-8 -*-
# class Solution:
#     def jumpFloor(self, number):
#         if number == 1:
#             return 1
#
#         if number == 2:
#             return 2
#
#         return self.jumpFloor(number - 1) + self.jumpFloor(number - 2)
#
# ss = Solution()
# for i in range(1,10,1):
#     print ss.jumpFloor(i)
#
#
# -*- coding:utf-8 -*-
# 動態規劃
# class Solution:
#     def jumpFloor(self, n):
#         # write code here
#         res = [1, 1, 2]
#         while len(res) <= n:
#             # 負數是從後往前取數組
#             res.append(res[-1] + res[-2])
#         return res[n-1]
#
# ss = Solution()
# print ss.jumpFloor(4)
#
# 9.一隻青蛙一次可以跳上1級臺階,也可以跳上2級……它也可以跳上n級。求該青蛙跳上一個n級的臺階總共有多少種跳法。
# 相當於之前所有的出來的結果的和
# class Solution:
# #     def jumpFloorII(self, number):
# #         res = [1,1,2]
# #         while len(res) < number:
# #             t = 0
# #             for i in res:
# #                 t = t + res[i]
# #             res.append(t)
# #         return res[number-1]
# # ss = Solution()
# # print ss.jumpFloorII(4)
#
# class Solution:
#     def jumpFloorII(self, number):
#         if number == 1:
#             return 1
#
#         if number == 2:
#             return 2
#         return  2 * self.jumpFloorII(number - 1)
# ss = Solution()
# print ss.jumpFloorII(4)
#
#
# 10.我們可以用2*1的小矩形橫着或者豎着去覆蓋更大的矩形。請問用n個2*1的小矩形無重疊地覆蓋一個2*n的大矩形,總共有多少種方法?
# 比如n=3時,2*3的矩形塊有3種覆蓋方法
#
# 橫着放相當於青蛙走樓梯一樣的,下面只能也橫着放,就相當於走一步兩步了
#
#
# -*- coding:utf-8 -*-
# class Solution:
#     def rectCover(self, number):
#         if number == 1:
#             return 1
#         if number == 2:
#             return 2
#         if number >= 3:
#             return self.rectCover(number - 1) + self.rectCover(number - 2)
#
# ss = Solution()
# out = ss.rectCover(3)
# print out
#
# 11.輸入一個整數,輸出該數二進制表示中1的個數。其中負數用補碼錶示。
# 把一個整數減去1在與它本身做與運算,就會把該整數最右邊一個1變成0。那麼一個整數的二進制有多少個1,就可以進行多少次這樣的操作就可以了。
# 舉個例子:一個二進制數1100,從右邊數起第三位是處於最右邊的一個1。減去1後,第三位變成0,它後面的兩位0變成了1,而前面的1保持不變,
# 因此得到的結果是1011.我們發現減1的結果是把最右邊的一個1開始的所有位都取反了。這個時候如果我們再把原來的整數和減去1之後的結果做與運算,
# 從原來整數最右邊一個1那一位開始所有位都會變成0。如1100&1011=1000。
# & 運算 只有兩個1纔是1  否則都是0   1001 & 0111 = 0000
# -*- coding:utf-8 -*-
# class Solution:
#     def NumberOf1(self, n):
#         count = 0
#         while n > 0:
#             count = count + 1
#             n = n & (n-1)
#         return count
#
# ss =  Solution()
# print ss.NumberOf1(0)
#
# 12.給定一個double類型的浮點數base和int類型的整數exponent。求base的exponent次方。
# 保證base和exponent不同時爲0
# 這也相當於動態規劃
# -*- coding:utf-8 -*-
# class Solution:
#     def Power(self, base, exponent):
#         if base == 0 or exponent == 0:
#             return False
#         total = 1
#
#         while exponent > 0:
#             total = total * base
#             exponent = exponent - 1
#
#         return total
#
#
# ss =  Solution()
# print  ss.Power(2,1)
#
#
# 13.輸入一個整數數組,實現一個函數來調整該數組中數字的順序,使得所有的奇數位於數組的前半部分,
# 所有的偶數位於數組的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。
# -*- coding:utf-8 -*-
# class Solution:
#     def reOrderArray(self, array):
#         ji = []
#         ou = []
#         for i in array:
#             if i % 2 == 0:
#                 ou.append(i)
#             else:
#                 ji.append(i)
#
#
#         return ji + ou
#
#
# temp = [3,5,6,8,1,7]
#
# ss = Solution()
# print ss.reOrderArray(temp)
#
#
# 14,輸入一個鏈表,輸出該鏈表中倒數第k個結點。
# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# 說下解題思路,我們可以獲取到最後一個結點  那麼先讓一個指針走k-1可結點  在走一個指針
# 然後兩個指針同時往後走  當第一個指針走到最後的時候 那麼第二個指針正好走到k的地方
#
# class Solution:
#     def FindKthToTail(self, head, k):
#      firstNode = head
#      step = k
#      while step > 0:
#         firstNode = firstNode.next
#        step -= 1
#
#
#
#
# 15.輸入一個鏈表,反轉鏈表後,輸出新鏈表的表頭。
#
# 看了一下好像沒有python的非遞歸實現。思路很簡單:1->2->3->4->5,
# 遍歷鏈表,把1的next置爲None,2的next置爲1,以此類推,5的next置爲4。
# 得到反轉鏈表。需要考慮鏈表只有1個元素的情況。圖中有具體的每步迭代的思路,
# 最後輸出pre而不是cur是因爲最後一次迭代後cur已經指向None了,而pre是完整的反向鏈表。
#
# 用三個指針分別指向當前、前一個、後一個,每次循環使當前節點的next指針指向前一個(原指向後一個),然後依次向後平移三個指針(注意移動的先後次序)。
# 其實可以節省一個指向新鏈表頭的指針,循環體如下便可:
# 最終需要返回pre,因爲cur已經變成原鏈表中最後的那個空指針了。
#
# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
#
# 1  2  3
# 2  3  nil
# nil   1   2
# class Solution:
#     # 返回ListNode
#     def ReverseList(self, pHead):
#         if pHead.next == None:
#             return pHead
#
#         pre = None
#         cur = pHead
#         sec = pHead.next
#         while cur:
#             cur.next = pre
#             pre = cur
#             cur = sec
#             sec = cur.next
#         return sec
#
# 15.輸入兩個單調遞增的鏈表,輸出兩個鏈表合成後的鏈表,當然我們需要合成後的鏈表滿足單調不減規則。
# 1,3,5,7
# 2,4,6,8
#
# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
# class Solution:
#     # 返回合併後列表
#     def Merge(self, pHead1, pHead2):
#         head = []
#         while pHead1 or pHead2:
#             if pHead1 <= pHead2 or pHead2 == None:
#                 head.insert(pHead1)
#                 pHead1 = pHead1.next
#             else:
#                 head.insert(pHead2)
#                 pHead2 = pHead2.next
#         return head
#
# 16.輸入兩棵二叉樹A,B,判斷B是不是A的子結構。(ps:我們約定空樹不是任意一個樹的子結構)
#
# / *思路:參考劍指offer
# 1、首先設置標誌位result = false,因爲一旦匹配成功result就設爲true,
# 剩下的代碼不會執行,如果匹配不成功,默認返回false
# 2、遞歸思想,如果根節點相同則遞歸調用DoesTree1HaveTree2(),
# 如果根節點不相同,則判斷tree1的左子樹和tree2是否相同,
# 再判斷右子樹和tree2是否相同
# 3、注意null的條件,HasSubTree中,如果兩棵樹都不爲空才進行判斷,
# DoesTree1HasTree2中,如果Tree2爲空,則說明第二棵樹遍歷完了,即匹配成功,
# tree1爲空有兩種情況(1)如果tree1爲空 & & tree2不爲空說明不匹配,
# (2)如果tree1爲空,tree2爲空,說明匹配。
#
# * /
#
# -*- 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 not pRoot1 or not pRoot2:
#             return False
#         return self.is_subtree(pRoot1, pRoot2) or self.HasSubtree(pRoot1.left, pRoot2) or self.HasSubtree(pRoot1.right,
#                                                                                                           pRoot2)
#
#     def is_subtree(self, A, B):
#         if not B:
#             return True
#         if not A or A.val != B.val:
#             return False
#         return self.is_subtree(A.left, B.left) and self.is_subtree(A.right, B.right)
#
# 17.操作給定的二叉樹,將其變換爲源二叉樹的鏡像
# 個人認爲解題思路就是遞歸,將所有的子節點進行交換,然後繼續下層
#
# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
# class Solution:
#     # 返回鏡像樹的根節點
#     def Mirror(self, root):
#         if root != None:
#             root.left,root.right = root.right,root.left
#             self.Mirror(root.left)
#             self.Mirror(root.right)
#
# 18.輸入一個矩陣,按照從外向裏以順時針的順序依次打印出每一個數字,例如,如果輸入如下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.
#
# a='python'
# b=a[::-1] 取反
# print(b) #nohtyp
#
# matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]
#
# # -*- coding:utf-8 -*-
# class Solution:
#     # matrix類型爲二維列表,需要返回列表
#     def printMatrix(self, matrix):
#         # write code here
#         res = []
#         while matrix:
#             res += matrix.pop(0)  #pop爲取棧 默認是取出最後一個維度的數據 index=-1
#             matrix = list(map(list, zip(*matrix)))[::-1]      map(list, zip(*matrix)是將二維數組進行xy軸的逆轉  然後在外層上下翻轉[::-1]
#         return res
#
# ss = Solution()
# print ss.printMatrix(matrix)
#
#
# 19.定義棧的數據結構,請在該類型中實現一個能夠得到棧中所含最小元素的min函數(時間複雜度應爲O(1))。
# 注意:保證測試中不會當棧爲空的時候,對棧調用pop()或者min()或者top()方法。
#
# 看到這個問題, 我們最開始可能會想, 添加一個成員變量用於保存最小元素, 每次壓棧時如果壓棧元素比當前最小元素更小, 就更新最小元素.
# 但是這樣會有一個問題, 如果最小元素被彈出了呢, 如何獲得下一個最小元素呢? 分析到這裏可以發現, 僅僅添加一個成員變量存放最小元素是不夠的,
# 我們需要在最小元素彈出後還能得到次小元素, 次小的彈出後, 還要能得到次次小的.
# 因此, 用另一個棧來保存這些元素是再合適不過的了. 我們叫它最小元素棧.
# 每次壓棧操作時, 如果壓棧元素比當前最小元素更小, 就把這個元素壓入最小元素棧,
# 原本的最小元素就成了次小元素. 同理, 彈棧時, 如果彈出的元素和最小元素棧的棧頂元素相等, 就把最小元素的棧頂彈出.
#
# -*- coding:utf-8 -*-
# class Solution:
#     def __init__(self):
#         self.stack = []
#         self.minStack = []
#     def push(self, node):
#         self.zhan.append(node)
#         if not self.minStack or node < self.minStack[-1]:
#             self.minStack.append(node)
#     def pop(self):
#         if self.stack[-1] == self.minStack[-1]:
#             self.minStack.pop()
#         self.stack.pop()
#
#     def top(self):
#         return self.stack[-1]
#     def min(self):
#         return self.minStack[-1]
#
#
# 20.輸入兩個整數序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否可能爲該棧的彈出順序。假設壓入棧的所有數字均不相等。
# 例如序列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):
#         stack中存入pushV中取出的數據
#         stack=[]
#         while popV:
#             # 如果第一個元素相等,直接都彈出,根本不用壓入stack
#             if pushV and popV[0]==pushV[0]
#                 popV.pop(0)
#                 pushV.pop(0)
#             #如果stack的最後一個元素與popV中第一個元素相等,將
#             elif stack and stack[-1]==popV
#                 stack.pop()
#                 popV.pop(0)
#             # 如果pushV中有數據,壓入stack
#             elif pushV:
#                 stack.append(pushV.pop(0))
#             # 上面情況都不滿足,直接返回false。
#             else:
#                 return False
#         return True
#
#
# pushV = [5,4,3,2,1]
# popV = [4,5,3,2,1]
# pushV = pushV[::-1]
# print pushV
#
# 21.從上往下打印出二叉樹的每個節點,同層節點從左至右打印。
# -*- 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):
#         if  not root:
#             return []
#         # write code here
#         ls=[root]
#         result=[]
#         while len(ls)>0:
#             node=ls.pop(0)
#             result.append(node.val)
#             if node.left!=None:
#                 ls.append(node.left)
#             if node.right!=None:
#                 ls.append(node.right)
#         return result
#
# python:使用兩個數組,ls存儲數組,ls相對值,把每一層的變量都放進去,開始就是循環數組的左右子例程,然後放在後面,結果存儲數組的值用於最後返回打印
#
#
# 22.輸入一個非空整數數組,判斷該數組是不是某二叉搜索樹的後序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的數組的任意兩個數字都互不相同。(細分析)
# 二叉搜索樹的規則是左節點都比跟節點小  右節點都比根節點大
# -*- coding:utf-8 -*-
# python:後序遍歷 的序列中,最後一個數字是樹的根節點 ,數組中前面的數字可以分爲兩部分:
# 第一部分是左子樹節點 的值,都比根節點的值小;第二部分 是右子樹 節點的值,都比 根 節點 的值大,
# 後面用遞歸分別判斷前後兩部分 是否 符合以上原則
#
# class Solution:
#     def VerifySquenceOfBST(self, sequence):
#         # write code here
#         if sequence==None or len(sequence)==0:
#             return False
#         length=len(sequence)
#         root=sequence[length-1]
#         # 在二叉搜索 樹中 左子樹節點小於根節點
#         for i in range(length):
#             if sequence[i]>root:
#                 break
#         # 二叉搜索樹中右子樹的節點都大於根節點
#         for j  in range(i,length):
#             if sequence[j]<root:
#                 return False
#         # 判斷左子樹是否爲二叉樹
#         left=True
#         if  i>0:
#             left=self.VerifySquenceOfBST(sequence[0:i])
#         # 判斷右子樹是否爲二叉樹
#         right=True
#         if i<length-1:
#             right=self.VerifySquenceOfBST(sequence[i:-1])
#         return left and right
#
#
# 23.輸入一顆二叉樹的根節點和一個整數,打印出二叉樹中結點值的和爲輸入整數的所有路徑。
# 路徑定義爲從樹的根結點開始往下一直到葉結點所經過的結點形成一條路徑。
#
#
#
# 24.輸入一個複雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針random指向一個隨機節點)
# ,請對此鏈表進行深拷貝,並返回拷貝後的頭結點。(注意,輸出結果中請不要返回參數中的節點引用,否則判題程序會直接返回空)
#
# 思路  1.把複製的節點連接到相應節點的後面
#  2.把複製節點的隨機節點變成下一個節點來賦值
#  3.最後按照基數偶數拆分節點
# -*- 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):
#     if not pHead:
#        return None
#
#     dummy = pHead
#
#     # first step, N' to N next
#     while dummy:
#        dummynext = dummy.next
#        copynode = RandomListNode(dummy.label)
#        copynode.next = dummynext
#        dummy.next = copynode
#        dummy = dummynext
#
#     dummy = pHead
#
#     # second step, random' to random'
#     while dummy:
#        dummyrandom = dummy.random
#        copynode = dummy.next
#        if dummyrandom:
#           copynode.random = dummyrandom.next
#        dummy = copynode.next
#
#     # third step, split linked list
#     dummy = pHead
#     copyHead = pHead.next
#     while dummy:
#        copyNode = dummy.next
#        dummynext = copyNode.next
#        dummy.next = dummynext
#        if dummynext:
#           copyNode.next = dummynext.next
#        else:
#           copyNode.next = None
#        dummy = dummynext
#
#     return copyHead
#
# 25.輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能創建任何新的結點,只能調整樹中結點指針的指向。
#
# 26.題目描述
# 輸入一個字符串,按字典序打印出該字符串中字符的所有排列。例如輸入字符串abc,則打印出由字符a,b,c所能排列出來的所有字符串abc,acb,bac,bca,cab和cba。
# 輸入一個字符串,長度不超過9(可能有字符重複),字符只包括大小寫字母。
# -*- coding:utf-8 -*-
#
# 按字典順序
# 打印所有組合
# -*- coding:utf-8 -*-
# class Solution:
#     def Permutation(self, ss):
#         # write code here
#         if len(ss)==0: return []
#         lst = list(ss)
#         lst.sort()
#         res = []
#         for i in range(0, len(ss)):
#             if i > 0 and lst[i]==lst[i-1]:
#                 continue
#             temp = self.Permutation(''.join(lst[:i]) + ''.join(lst[i+1:]))
#             if len(temp)==0:
#                 res.append(lst[i])
#             for str in temp:
#                 res.append(lst[i]+str)
#         return res
#
# ss = 'aabbb'
# a = Solution()
# print a.Permutation(ss)
#
# 附加  全排列
# 將整組數中的所有的數分別與第一個數交換,這樣就總是在處理後n-1個數的全排列。
# import copy
# class Solution:
#     def Permutation(self, res, ss, idx):
#     if idx >= len(ss):
#        a = copy.deepcopy(ss)
#        res.append(a)
#        return
#     for i in range(idx, len(ss)):
#        ss[i],ss[idx] = ss[idx],ss[i]
#        self.Permutation(res,ss,idx+1)
#        ss[i],ss[idx] = ss[idx],ss[i]
# res = []
# ss = [1,2,3,4]
# a = Solution()
# a.Permutation(res,ss,0)
# print res
#
#
# 27.數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。例如輸入一個長度爲9的數組{1,2,3,2,2,2,5,4,2}
# 。由於數字2在數組中出現了5次,超過數組長度的一半,因此輸出2。如果不存在則輸出0。
# -*- coding:utf-8 -*-
# class Solution:
#     def MoreThanHalfNum_Solution(self, numbers):
#     halfNum = int(len(numbers)/2)
#     Calmap = {}
#     for i in range(len(numbers)):
#        if numbers[i] in Calmap.keys():
#           Calmap[numbers[i]] += 1
#
#           if Calmap[numbers[i]] > halfNum:
#              return numbers[i]
#        else:
#           Calmap[numbers[i]] = 1
#     return 0
#
#
# ss = Solution()
# num = [1,2,3,2,2,2,5,4,2]
# print ss.MoreThanHalfNum_Solution(num)
#
#
# 28.輸入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 tinput == [] or k > len(tinput):
#        return []
#     tinput.sort()
#     return tinput[: k]
#
#
# #方法二:快速排序
# # -*- coding:utf-8 -*-
# class Solution:
#  def GetLeastNumbers_Solution(self, tinput, k):
#     # write code here
#     def quick_sort(lst):
#        if not lst:
#           return []
#        pivot = lst[0]
#        left = quick_sort([x for x in lst[1:] if x < pivot])
#        right = quick_sort([x for x in lst[1:] if x >= pivot])
#        return left + [pivot] + right
#
#     if tinput == [] or k > len(tinput):
#        return []
#     tinput = quick_sort(tinput)
#     return tinput[: k]
#
#
# #方法三:歸併排序
# # -*- coding:utf-8 -*-
# class Solution:
#  def GetLeastNumbers_Solution(self, tinput, k):
#     # write code here
#     def merge_sort(lst):
#        if len(lst) <= 1:
#           return lst
#        mid = len(lst) // 2
#        left = merge_sort(lst[: mid])
#        right = merge_sort(lst[mid:])
#        return merge(left, right)
#
#     def merge(left, right):
#        l, r, res = 0, 0, []
#        while l < len(left) and r < len(right):
#           if left[l] <= right[r]:
#              res.append(left[l])
#              l += 1
#           else:
#              res.append(right[r])
#              r += 1
#        res += left[l:]
#        res += right[r:]
#        return res
#
#     if tinput == [] or k > len(tinput):
#        return []
#     tinput = merge_sort(tinput)
#     return tinput[: k]
#
#
# #方法四:堆排序
# # -*- coding:utf-8 -*-
# class Solution:
#  def GetLeastNumbers_Solution(self, tinput, k):
#     # write code here
#     def siftup(lst, temp, begin, end):
#        if lst == []:
#           return []
#        i, j = begin, begin * 2 + 1
#        while j < end:
#           if j + 1 < end and lst[j + 1] > lst[j]:
#              j += 1
#           elif temp > lst[j]:
#              break
#           else:
#              lst[i] = lst[j]
#              i, j = j, 2 * j + 1
#        lst[i] = temp
#
#     def heap_sort(lst):
#        if lst == []:
#           return []
#        end = len(lst)
#        for i in range((end // 2) - 1, -1, -1):
#           siftup(lst, lst[i], i, end)
#        for i in range(end - 1, 0, -1):
#           temp = lst[i]
#           lst[i] = lst[0]
#           siftup(lst, temp, 0, i)
#        return lst
#
#     if tinput == [] or k > len(tinput):
#        return []
#     tinput = heap_sort(tinput)
#     return tinput[: k]
#
#
# #方法五:冒泡排序
# # -*- coding:utf-8 -*-
# class Solution:
#  def GetLeastNumbers_Solution(self, tinput, k):
#     # write code here
#     def bubble_sort(lst):
#        if lst == []:
#           return []
#        for i in range(len(lst)):
#           for j in range(1, len(lst) - i):
#              if lst[j - 1] > lst[j]:
#                 lst[j - 1], lst[j] = lst[j], lst[j - 1]
#        return lst
#
#     if tinput == [] or k > len(tinput):
#        return []
#     tinput = bubble_sort(tinput)
#     return tinput[: k]
#
#
# #方法六:直接選擇排序
# # -*- coding:utf-8 -*-
# class Solution:
#  def GetLeastNumbers_Solution(self, tinput, k):
#     # write code here
#     def select_sort(lst):
#        if lst == []:
#           return []
#        for i in range(len(lst) - 1):
#           smallest = i
#           for j in range(i, len(lst)):
#              if lst[j] < lst[smallest]:
#                 smallest = j
#           lst[i], lst[smallest] = lst[smallest], lst[i]
#
#        return lst
#
#     if tinput == [] or k > len(tinput):
#        return []
#     tinput = select_sort(tinput)
#     return tinput[: k]
#
#
# #方法七:插入排序
# # -*- coding:utf-8 -*-
# class Solution:
#  def GetLeastNumbers_Solution(self, tinput, k):
#     # write code here
#     def Insert_sort(lst):
#        if lst == []:
#           return []
#        for i in range(1, len(lst)):
#           temp = lst[i]
#           j = i
#           while j > 0 and temp < lst[j - 1]:
#              lst[j] = lst[j - 1]
#              j -= 1
#           lst[j] = temp
#        return lst
#
#     if tinput == [] or k > len(tinput):
#        return []
#     tinput = Insert_sort(tinput)
#     return tinput[: k]
#
#
# 29.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
#         max_sum, cur_sum = -0xffffff, 0
#         for i in array:
#             if cur_sum <= 0:
#                 cur_sum = i
#             else:
#                 cur_sum += i
#             if cur_sum > max_sum:
#                 max_sum = cur_sum
#         return max_sum
#
#
# arr = [-6,-3,-2,-7,-15,-2,-2,-2]
# ss = Solution()
# print ss.FindGreatestSumOfSubArray(arr)
#
# 30.求出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):
#      def find1Count(n):
#         base_str = str(n)
#         count = 0
#         while base_str.find('1') != -1:
#            base_str = base_str[base_str.find('1') + 1:]
#            count += 1
#         return count
#
#      totalCount = 0
#      for i in range(0,n+1,1):
#         totalCount += find1Count(i)
#      return totalCount
#
#
# arr = 100000
# ss = Solution()
# print ss.NumberOf1Between1AndN_Solution(arr)
#
# 31.輸入一個正整數數組,把數組裏所有數字拼接起來排成一個數,
# 打印能拼接出的所有數字中最小的一個。例如輸入數組{3,32,321},
# 則打印出這三個數字能排成的最小數字爲321323。
#
# -*- coding:utf-8 -*-
# class Solution:
#     def PrintMinNumber(self, numbers):
#      if not numbers:
#         return ""
#      #這裏將兩個加起來做個排序,大於的取前者 小於的取後者
#      lmb = lambda n1, n2: int(str(n1) + str(n2)) - int(str(n2) + str(n1))
#      array = sorted(numbers, cmp=lmb)
#      return ''.join([str(i) for i in array])
#
#
# -*- coding:utf-8 -*-
# class Solution:
#  def PrintMinNumber(self, numbers):
#     # write code here
#     temp = [str(x) for x in sorted(numbers, cmp=self.f_cmp)]
#     return ''.join(temp)
#
#  def f_cmp(self, a, b):
#     if str(a) + str(b) < str(b) + str(a):
#        return -1
#     elif str(a) + str(b) > str(b) + str(a):
#        return 1
#     else:
#        return 0
#
# arr = [3,32,321]
# ss = Solution()
# print ss.PrintMinNumber(arr)
#
#
# 32.把只包含質因子2、3和5的數稱作醜數(Ugly Number)。
# 例如6、8都是醜數,但14不是,因爲它包含質因子7。
# 習慣上我們把1當做是第一個醜數。求按從小到大的順序的第N個醜數。
#
# 通俗易懂的解釋:
# 首先從醜數的定義我們知道,一個醜數的因子只有2,3,5,那麼醜數p = 2 ^ x * 3 ^ y * 5 ^ z,
# 換句話說一個醜數一定由另一個醜數乘以2或者乘以3或者乘以5得到,那麼我們從1開始乘以2,3,5,
# 就得到2,3,5三個醜數,在從這三個醜數出發乘以2,3,5就得到4,6,10,6,9,15,10,15,25九個醜數,
# 我們發現這種方***得到重複的醜數,而且我們題目要求第N個醜數,這樣的方法得到的醜數也是無序的。那麼我們可以維護三個隊列:
# 其實就是在他們三個隊列裏面找最小,找到了給他加1,繼續找最小輸出
# -*- coding:utf-8 -*-
# class Solution:
#     def GetUglyNumber_Solution(self, index):
#         # write code here
#         if index<1:
#             return 0
#         data=[1]
#         index2=0
#         index3=0
#         index5=0
#         indexitter=0
#         while indexitter<index:
#             indexitter+=1
#             d= min(data[index2]*2,data[index3]*3,data[index5]*5)
#             data.append(d)
#             if data[index2]*2==d:
#                 index2+=1
#             if data[index3]*3==d:
#                 index3+=1
#             if data[index5]*5==d:
#                 index5+=1
#         return data[index-1]
#
# idx = 5
# ss = Solution()
# print ss.GetUglyNumber_Solution(idx)
#
# 33.在一個字符串(0<=字符串長度<=10000,全部由字母組成)中找到第一個只出現一次的字符,
# 並返回它的位置, 如果沒有則返回 -1(需要區分大小寫).(從0開始計數)
# class Solution:
#  def getLocationAppareOnce(self,str):
# import collections
#
# def firstChar(ss):
#  #這裏使用的是排序的字典,根據傳入的順序進行輸出,到時候在遍歷一遍排序字典,找到count==1的
#  #就可以了
#  dicts = collections.OrderedDict()
#  if len(ss) <= 0:
#     return -1
#
#  if len(ss) == 1:
#     return ss
#
#  for key in ss:
#     if key in dicts:
#        dicts[key] += 1
#     else:
#        dicts[key] = 1
#
#  for key in dicts:
#     if dicts[key] == 1:
#        return key
#  return -1
# print firstChar("aabbccddeeff")
#
# 34.在數組中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。
# 輸入一個數組,求出這個數組中的逆序對的總數P。並將P對1000000007取模的結果輸出。 即輸出P%1000000007
# 輸入描述:
# 題目保證輸入的數組中沒有的相同的數字
#
# 數據範圍:
#
#  對於%50的數據,size<=10^4
#
#  對於%75的數據,size<=10^5
#
#  對於%100的數據,size<=2*10^5
#
# 歸併排序的改進,把數據分成前後兩個數組(遞歸分到每個數組僅有一個數據項),
# 合併數組,合併時,出現前面的數組值array[i]大於後面數組值array[j]時;則前面
# 數組array[i]~array[mid]都是大於array[j]的,count += mid+1 - i
# 參考劍指Offer,但是感覺劍指Offer歸併過程少了一步拷貝過程。
# 還有就是測試用例輸出結果比較大,對每次返回的count mod(1000000007)求餘
#
# data = [1,2,3,4,5,6,7,0]
# # -*- coding:utf-8 -*-
# count = 0
# class Solution:
#     def InversePairs(self, data):
#         global count
#         def MergeSort(lists):
#             global count
#             if len(lists) <= 1:
#                 return lists
#             num = int( len(lists)/2 )
#             left = MergeSort(lists[:num])
#             right = 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
#                     count += len(left)-l
#             result += right[r:]
#             result += left[l:]
#             return result
#         MergeSort(data)
#         return count%1000000007
#
# ss = Solution()
# print ss.InversePairs(data)
#
#
# 35.輸入兩個鏈表,找出它們的第一個公共結點。
# (注意因爲傳入數據是鏈表,所以錯誤測試數據的提示是用其他方式顯示的,保證傳入數據是正確的)
#   a   b   c       d    b   f
#
# 直接找或者用第一次遍歷來確定二者的長度,然後用短的從開頭開始往下遍歷,找到相同val證明取到相同元素了
#
# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# class Solution:
#  def FindFirstCommonNode(self, head1, head2):
#     # write code here
#     list1 = []
#     list2 = []
#     node1 = head1
#     node2 = head2
#     while node1:
#        list1.append(node1.val)
#        node1 = node1.next
#     while node2:
#        if node2.val in list1:
#           return node2
#        else:
#           node2 = node2.next
#
# 36. 統計一個數字在排序數組中出現的次數
# 這題太簡單了  感覺啥都沒問
# -*- coding:utf-8 -*-
# class Solution:
#     def GetNumberOfK(self, data, k):
#         # write code here
#         count = len(data)
#         i = 0
#         for j in range(count):
#             if data[j] == k:
#                 i += 1
#         return i
#
#
# 37.輸入一棵二叉樹,求該樹的深度。
# 從根結點到葉結點依次經過的結點(含根、葉結點)形成樹的一條路徑,最長路徑的長度爲樹的深度。
# class TreeNode:
#  def __init__(self, x):
#     self.val = x
#     self.left = None
#     self.right = None
#
#
# 使用遞歸方法
# class Solution:
#     def TreeDepth(self, pRoot):
#         # write code here
#         # 使用層次遍歷
#         # 當樹爲空直接返回0
#         if pRoot is None:
#             return 0
#         # 方法2:使用遞歸
#         # 如果該樹只有一個結點,它的深度爲1.如果根節點只有左子樹沒有右子樹,
#         # 那麼樹的深度爲左子樹的深度加1;同樣,如果只有右子樹沒有左子樹,
#         # 那麼樹的深度爲右子樹的深度加1。如果既有左子樹也有右子樹,
#         # 那該樹的深度就是左子樹和右子樹的最大值加1.
#         count = max(self.TreeDepth(pRoot.left), self.TreeDepth(pRoot.right)) + 1
#         return count
#
#
#
#
# 38.輸入一棵二叉樹,判斷該二叉樹是否是平衡二叉樹。
# 在這裏,我們只需要考慮其平衡性,不需要考慮其是不是排序二叉樹
# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 一看還是遞歸,平衡二叉樹的規則是左邊節點永遠小於根節點  右邊節點必須大於根節點
# 並且左右節點的高低差必須小於1
# class Solution:
#     def IsBalanced_Solution(self, pRoot):
#      # write code here
#      return self.balanceHeight(pRoot) >= 0
#
#     def balanceHeight(self, root):
#      #子節點不存在,給0
#      if root is None:
#         return 0
#      left = self.balanceHeight(root.left)
#      right = self.balanceHeight(root.right)
#
#     #不滿足條件,高低差大於1了,直接返回
#      if (left < 0 or right < 0 or abs(left - right) > 1):
#         return -1
#      return max(left, right) + 1
#
# 39.一個整型數組裏除了兩個數字之外,其他的數字都出現了兩次。
# 請寫程序找出這兩個只出現一次的數字。
# [1,2,3,4,5,3,2,1]
#
# 異或 相同爲0  不同爲1
# 首先:位運算中異或的性質:兩個相同數字異或=0,一個數和0異或還是它本身。
#
# 當只有一個數出現一次時,我們把數組中所有的數,依次異或運算,最後剩下的就是落單的數,因爲成對兒出現的都抵消了。
#
# 依照這個思路,我們來看兩個數(我們假設是AB)出現一次的數組。我們首先還是先異或,剩下的數字肯定是A、B異或的結果,
# 這個結果的二進制中的1,表現的是A和B的不同的位。我們就取第一個1所在的位數,假設是第3位,接着把原數組分成兩組,
# 分組標準是第3位是否爲1。如此,相同的數肯定在一個組,因爲相同數字所有位都相同,而不同的數,肯定不在一組。
# 然後把這兩個組按照最開始的思路,依次異或,剩餘的兩個結果就是這兩個只出現一次的數字。
#
#
# # -*- coding:utf-8 -*-
# from collections import Counter
#
#
# class Solution:
#  # 返回[a,b] 其中ab是出現一次的兩個數字
#  def FindNumsAppearOnce(self, array):
#     # write code here
#     return list(self.dc(array, 0, len(array) - 1))
#
#  def dc(self, array, start, end):
#     res = set()
#     if start > end:
#        return res
#     if start == end:
#        return set(array[start:end])
#
#     spl = (start + end) / 2
#
#     s1 = self.dc(array, start, spl)
#     s2 = self.dc(array, spl + 1, end)
#
#     return s1.union(s2).difference(s1.intersection(s2))
#
#
# #intersection 返回交集  s1 和s2的
#
# array = [1,2,3,4,5,3,2,1]
# ss = Solution()
# print ss.FindNumsAppearOnce(array)
#
#
# 40.小明很喜歡數學,有一天他在做數學作業時,要求計算出9~16的和,他馬上就寫出了正確答案是100。
# 但是他並不滿足於此,他在想究竟有多少種連續的正數序列的和爲100(至少包括兩個數)。
# 沒多久,他就得到另一組連續正數和爲100的序列:18,19,20,21,22。
# 現在把問題交給你,你能不能也很快的找出所有和爲S的連續正數序列? Good Luck!
# 輸出描述:
# 輸出所有和爲S的連續正數序列。序列內按照從小至大的順序,序列間按照開始數字從小到大的順序
# 滑動窗口技術,連續數字計算是 參考1到100的和怎麼算, 如果滿足條件把分母擴大  不滿足條件擴大分子,直到所有條件都滿足
#
# class Solution:
#     def FindContinuousSequence(self, tsum):
#     small = 1
#     big = 2
#     result = []
#
#     while small < big:
#        count = (small + big)* (big - small + 1 )/2
#        if count == tsum:
#           result.append(range(small,big+1))
#           small += 1
#        elif count < tsum:
#           big += 1
#        else:
#           small += 1
#     return     result
#
# ss = Solution()
# print ss.FindContinuousSequence(100)
#
#
# 40.輸入一個遞增排序的數組和一個數字S,在數組中查找兩個數,使得他們的和正好是S,如果有多對數字的和等於S,輸出兩個數的乘積最小的。
# 對應每個測試案例,輸出兩個數,小的先輸出。
# 還是用滑動窗口做
#
# tsum = 5
# array = [1,2,3,4,5,6,7]
#
# # -*- coding:utf-8 -*-
# #解決方案,利用滑動窗口技術
# class Solution:
#     def FindNumbersWithSum(self, array, tsum):
#  small = 0
#  big = 1
#  calX = 0
#  temp = []
#
#  while array[small] < array[big]:
#     if (array[small] + array[big]) == tsum:
#        if calX == 0:
#           temp = []
#           temp.append(array[small])
#           temp.append(array[big])
#           small += 1
#        elif calX > array[small] * array[big]:
#           temp = []
#           temp.append(array[small])
#           temp.append(array[big])
#           small += 1
#     elif array[small] + array[big] < tsum:
#        big += 1
#     else:
#        small += 1
#  return temp
#
# ss = Solution()
# print ss.FindNumbersWithSum(array,tsum)
#
#
# 41.彙編語言中有一種移位指令叫做循環左移(ROL),現在有個簡單的任務,
# 就是用字符串模擬這個指令的運算結果。對於一個給定的字符序列S,請你把其循環左移K位後的序列輸出
# 例如,字符序列S=”abcXYZdef”,要求輸出循環左移3位後的結果,即“XYZdefabc”。是不是很簡單?OK,搞定它!
# -*- coding:utf-8 -*-
#
# s = "abcXYZdef"
#
# class Solution:
#     def LeftRotateString(self, s, n):
#     ls = list(s)
#     for i in range(n):
#        ls.append(ls[0])
#        ls.pop(0)
#     return ''.join(ls)
#
# 或者直接return  s[n:]  + s[:n]
#
# ss = Solution()
# print ss.LeftRotateString(s,3)
#
#
# 42.牛客最近來了一個新員工Fish,每天早晨總是會拿着一本英文雜誌,
# 寫些句子在本子上。同事Cat對Fish寫的內容頗感興趣,有一天他向Fish借來翻看,
# 但卻讀不懂它的意思。例如,“student. a am I”。後來才意識到,這傢伙原來把句子單詞的順序翻轉了,
# 正確的句子應該是“I am a student.”。Cat對一一的翻轉這些單詞順序可不在行,你能幫助他麼?
#
#
# 先把字符串切割成一個數組 然後在倒序插入空格輸出
# 方數組裏,然後倒序輸出拼接
#
# s = 'student. a am I'
# # -*- coding:utf-8 -*-
# 方法1自實現
# class Solution:
#     def ReverseSentence(self, s):
#  ls = str.split(s,' ')
#  answer = ''
#  for idx in range(len(ls)-1,-1,-1):
#     answer = answer + ''.join(ls[idx]) + ' '
#  return answer
# ss = Solution()
# print ss.ReverseSentence(s)
#
# 方法2
# -*- coding:utf-8 -*-
# class Solution:
#     def ReverseSentence(self, s):
#         # write code here
#         l=s.split(' ')
#         return ' '.join(l[::-1])
#
# 43.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。
#
# 先找出癩子的量,然後在用排列後的兩個做差,肯定小於等於該順子最大減最小的值,否則不是順子
# import numpy as np
# numbers = [0,3,4,5,0]
# a = np.array(numbers)
# print np.sum(a == 0)
#
# # -*- coding:utf-8 -*-
# class Solution:
#     def IsContinuous(self, numbers):
#         # write code here
#         if not numbers:
#             return numbers
#         new_list = [i for i in numbers if i > 0]
#         new_list.sort()
#         if len(new_list)==1:
#             return True
#         n = 0
#         for j in range(len(new_list)-1):
#             if (new_list[j+1] - new_list[j]) > 0:
#                 n += (new_list[j+1] - new_list[j])
#             else:
#                 return False
#         if n <= 4:
#             return True
#         else:
#             return False
#
#
# 44.每年六一兒童節,牛客都會準備一些小禮物去看望孤兒院的小朋友,今年亦是如此。
# 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 not m or not n:
#             return -1
#         #將小朋友列表化
#         res = range(n)
#         i = 0
#         #只要小朋友大於1,則一直循環,每次彈出的小朋友是 (m-1 加 當前小朋友的i)取模當前的小朋友
#         while len(res)>1:
#             i = (m+i-1)%len(res)
#             res.pop(i)
#         return res[0]
#
#
# 45.求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等關鍵字及條件判斷語句(A?B:C)
# 啥都不讓用  直接想遞歸
# 止損條件就是到n
# -*- coding:utf-8 -*-
# class Solution:
#  def __init__(self):
#     self.sum = 0
#
#  def Sum_Solution(self, n):
#     if n <= 0:
#        return self.sum
#     self.sum += n
#     n -=1
#     self.Sum_Solution(n)
#     return self.sum
#
# ss = Solution()
# print ss.Sum_Solution(5)
#
# 46.寫一個函數,求兩個整數之和,要求在函數體內不得使用+、-、*、/四則運算符號。
#
# 首先看十進制是如何做的: 5+7=12,三步走
# 第一步:相加各位的值,不算進位,得到2。
# 第二步:計算進位值,得到10. 如果這一步的進位值爲0,那麼第一步得到的值就是最終結果。
#
# 第三步:重複上述兩步,只是相加的值變成上述兩步的得到的結果2和10,得到12。
#
# 同樣我們可以用三步走的方式計算二進制值相加: 5-101,7-111 第一步:相加各位的值,不算進位,得到010,二進制每位相加就相當於各位做異或操作,101^111。
#
# 第二步:計算進位值,得到1010,相當於各位做與操作得到101,再向左移一位得到1010,(101&111)<<1。
#
# 第三步重複上述兩步, 各位相加 010^1010=1000,進位值爲100=(010&1010)<<1。
#      繼續重複上述兩步:1000^100 = 1100,進位值爲0,跳出循環,1100爲最終結果。
#
# -*- coding:utf-8 -*-
# class Solution:
#     def Add(self, num1, num2):
#     #簡單方法
#     return sum([num1,num2])
#
#
# 47.將一個字符串轉換成一個整數,要求不能使用字符串轉換整數的庫函數。 數值爲0或者字符串不是一個合法的數值則返回0
# 輸入描述:
# 輸入一個字符串,包括數字字母符號,可以爲空
# 輸出描述:
# 如果是合法的數值表達則返回該數字,否則返回0
# 示例1
# 輸入
# +2147483647
# 1a33
# 輸出
# 2147483647
# 0
#
# 首先需要將字符串切割成數組,然後從最低位開始循環找,如果是數字那麼將原數組*10 並且加上該數字
# 如果遇到符號,則直接放到最前面,在循環的話,或者遇到特殊符號的話報錯
# -*- coding:utf-8 -*-
# s = '-12334'
# class Solution:
#     def StrToInt(self, s):
#     ls = list(s)
#     tNum = 0
#     for i in range(1, len(ls), 1):
#        if ls[i] < '0' or ls[i] > '9':
#           return 0
#        else:
#           if tNum == 0:
#              tNum = int(ls[i])
#           else:
#              tNum = tNum*10 + int(ls[i])
#
#     if ls[0] >= '0' and ls[0] <= '9':
#        tNum = tNum * 10 + int(ls[0])
#     elif ls[0] == '+':
#        tNum = tNum
#     elif ls[0] == '-':
#        tNum = -tNum
#     return tNum
# ss = Solution()
# print ss.StrToInt(s)
#
#
# 48.在一個長度爲n的數組裏的所有數字都在0到n-1的範圍內。 數組中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。
# 請找出數組中任意一個重複的數字。 例如,如果輸入長度爲7的數組{2,3,1,0,2,5,3},那麼對應的輸出是第一個重複的數字2。
# -*- coding:utf-8 -*-
# class Solution:
#     這裏要特別注意~找到任意重複的一個值並賦值到duplication[0]
#     函數返回True/False
#
#
# 思路,完全22比較(兩個for循環)可以比出來,但是方法比較笨
#     def duplicate(self, numbers, duplication):
#     for i in range(0,len(numbers)):
#        for j in range(0,len(numbers)):
#           if i == j:
#              continue
#           elif numbers[i] == numbers[j]:
#              duplication[0] = numbers[i]
#              return True
#     return False
#
#
# numbers = [2, 3, 1, 0, 2, 5, 3]
# duplication = []
# ss = Solution()
# print ss.duplicate(numbers,duplication)
#
# #python包實現,有點投機取巧
# # -*- coding:utf-8 -*-
# import collections
# class Solution:
#     def duplicate(self, numbers, duplication):
#         # write code here
#         flag=False
#         c=collections.Counter(numbers)
#         for k,v in c.items():
#             if v>1:
#                 duplication[0]=k
#                 flag=True
#                 break
#         return flag
#
# 49.給定一個數組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];)
# 再理解!!!!!!!
# https://www.nowcoder.com/profile/645151/codeBookDetail?submissionId=1516453
# 其實是一個矩陣
#
# B[i] = A[0] * A[1] * ... * A[i - 1] * A[i + 1] * ... *A[n - 1]
# B[n - 1] = A[0] * A[1] * ... * A[n - 2]
# B[0] = A[1] * A[2] * ... * A[n - 1]
#
# -*- coding:utf-8 -*-
# class Solution:
#     def multiply(self, A):
#         # write code here
#         if not A:
#             return []
#         # 計算前面一部分
#         num = len(A)
#         B = [None] * num
#         B[0] = 1
#         B[i] = A[0]* B[0]
#         for i in range(1, num):
#             B[i] = B[i-1] * A[i-1]
#         # 計算後面一部分
#         # 自下而上
#         # 保留上次的計算結果乘本輪新的數,因爲只是後半部分進行累加,所以設置一個tmp,能夠保留上次結果
#         tmp = 1
#         for i in range(num-2, -1, -1):
#             tmp *= A[i+1]
#             B[i] *= tmp
#         return B
#
#
# ss = Solution()
# print ss.multiply([1,2,3,4,5])
#
#
# 50.請實現一個函數用來匹配包括'.'和'*'的正則表達式。模式中的字符'.'
# 表示任意一個字符,而'*'表示它前面的字符可以出現任意次(包含0次)。
# 在本題中,匹配是指字符串的所有字符匹配整個模式。
# 例如,字符串"aaa"與模式"a.a"和"ab*ac*a"匹配,但是與"aa.a"和"ab*a"均不匹配
#
# 這裏要
#
# class Solution:
#     # s, pattern都是字符串
#     def match(self, s, pattern):
#         # 如果s與pattern都爲空,則True
#         if len(s) == 0 and len(pattern) == 0:
#             return True
#         # 如果s不爲空,而pattern爲空,則False
#         elif len(s) != 0 and len(pattern) == 0:
#             return False
#         # 如果s爲空,而pattern不爲空,則需要判斷
#         elif len(s) == 0 and len(pattern) != 0:
#             # pattern中的第二個字符爲*,則pattern後移兩位繼續比較
#             if len(pattern) > 1 and pattern[1] == '*':
#                 return self.match(s, pattern[2:])
#             else:
#                 return False
#         # s與pattern都不爲空的情況
#         else:
#             # pattern的第二個字符爲*的情況
#             if len(pattern) > 1 and pattern[1] == '*':
#                 # s與pattern的第一個元素不同,則s不變,pattern後移兩位,相當於pattern前兩位當成空
#                 if s[0] != pattern[0] and pattern[0] != '.':
#                     return self.match(s, pattern[2:])
#                 else:
#                     # 如果s[0]與pattern[0]相同,且pattern[1]爲*,這個時候有三種情況
#                     # pattern後移2個,s不變;相當於把pattern前兩位當成空,匹配後面的
#                     # pattern後移2個,s後移1個;相當於pattern前兩位與s[0]匹配
#                     # pattern不變,s後移1個;相當於pattern前兩位,與s中的多位進行匹配,因爲*可以匹配多位
#                     return self.match(s, pattern[2:]) or self.match(s[1:], pattern[2:]) or self.match(s[1:], pattern)
#             # pattern第二個字符不爲*的情況
#             else:
#                 if s[0] == pattern[0] or pattern[0] == '.':
#                     return self.match(s[1:], pattern[1:])
#                 else:
#                     return False
#
# 51.請實現一個函數用來判斷字符串是否表示數值(包括整數和小數)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示數值。
# 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。
# 萬能的
#
# -*- coding:utf-8 -*-
# class Solution:
#     # s字符串
#     def isNumeric(self, s):
#         try :
#             p = float(s)
#             return True
#         except:
#             return False
#
# ss = Solution()
# print ss.isNumeric("1.2.3")
#
# 52.請實現一個函數用來找出字符流中第一個只出現一次的字符。
# 例如,當從字符流中只讀出前兩個字符"go"時,第一個只出現一次的字符是"g"。
# 當從該字符流中讀出前六個字符“google"時,第一個只出現一次的字符是"l"。
# 輸出描述:
# 如果當前字符流沒有存在出現一次的字符,返回#字符。
#
# 利用一個字典記錄出現數量,然後獲取時候遍歷每個元素,得到第一個元素後比較就完了
#
# -*- coding:utf-8 -*-
# class Solution:
#     # 返回對應char
#     def __init__(self):
#         self.s=''
#         self.dict1={}
#     def FirstAppearingOnce(self):
#         # write code here
#         for i in self.s:
#             if self.dict1[i]==1:
#                 return i
#         return '#'
#     def Insert(self, char):
#         # write code here
#         self.s=self.s+char
#         if char in self.dict1:
#             self.dict1[char]=self.dict1[char]+1
#         else:
#             self.dict1[char]=1
#
#
# 53.給一個鏈表,若其中包含環,請找出該鏈表的環的入口結點,否則,輸出null。
# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# 聲明倆指針同時走,一個走一步一個走兩步,如果相遇證明有環,否則有人走沒了 那就是沒換
# class Solution:
#  def EntryNodeOfLoop(self, pHead):
#     if pHead == None or pHead.next == None or pHead.next.next == None:
#        return None
#     low = pHead.next
#     fast = pHead.next.next
#     while low != fast:
#        if fast.next == None or fast.next.next == None:
#           return None
#        low = low.next
#        fast = fast.next.next
#     #以上證明可以相遇了
#     #以下是爲了找環口
#     fast = pHead
#     while low != fast:
#        low = low.next
#        fast = fast.next
#     return fast
#
#
# 54.在一個排序的鏈表中,存在重複的結點,請刪除該鏈表中重複的結點,
# 重複的結點不保留,返回鏈表頭指針。
# 例如,鏈表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
#
# https://www.nowcoder.com/practice/fc533c45b73a41b0b44ccba763f866ef?
# tpId=13&tqId=11209&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
#
# 是可以刪除的,剛開始當pHead的值爲1時,
# 到達return deleteDuplication(pNode)這個地方繼續往下“遞”。
# 直到最後pNode指向了5那個節點,再次調用該方法,所以return了pNode,
# 也就是5這個節點本身。然後往前“歸”,直到“歸”到該開始調用那時,
# 到達return deleteDuplication(pNode),所以一路返回,
# 最後返回指向5的那個PNode。所以是可以刪除的
#
# class Solution:
#     def deleteDuplication(self, pHead):
#         # write code here
#         if pHead is None or pHead.next is None:
#             return pHead
#         head1 = pHead.next
#         #比較next和本身是否相同
#         if head1.val != pHead.val:
#             pHead.next = self.deleteDuplication(pHead.next)
#             return pHead
#         else:#當前節點是重複結點
#             while pHead.val == head1.val and head1.next is not None:
#                 head1 = head1.next
#             if head1.val != pHead.val:
#                 return self.deleteDuplication(head1)
#             else:#這裏是報錯
#                 return None
#
# 55.給定一個二叉樹和其中的一個結點,請找出中序遍歷順序的下一個結點並且返回。
# 注意,樹中的結點不僅包含左右子結點,同時包含指向父結點的指針。
# -*- 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 here
#         if not pNode:
#             return pNode
#         if pNode.right:
#             left1=pNode.right
#             while left1.left:
#                    left1=left1.left
#             return left1
#         p=pNode
#         while pNode.next:
#             tmp=pNode.next
#             if tmp.left==pNode:
#                 return tmp
#             pNode=tmp
#
#
# 56.請實現一個函數,用來判斷一顆二叉樹是不是對稱的。注意,如果一個二叉樹同此二叉樹的鏡像是同樣的,定義其爲對稱的。
# -*- 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
#         def is_same(p1,p2):
#             if not p1 and not p2:
#                 return True
#             if (p1 and p2) and p1.val==p2.val:
#                 return is_same(p1.left,p2.right) and is_same(p1.right,p2.left)
#             return False
#
#         if not pRoot:
#             return True
#         if pRoot.left and not pRoot.right:
#             return False
#         if not pRoot.left and pRoot.right:
#             return False
#         return is_same(pRoot.left,pRoot.right)
#
#
# 57.請實現一個函數按照之字形打印二叉樹,即第一行按照從左到右的順序打印,
# 第二層按照從右至左的順序打印,第三行按照從左到右的順序打印,其他行以此類推。
# -*- 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 []
#         from collections import deque
#         res,tmp=[],[]
#         last=pRoot
#         q=deque([pRoot])
#         left_to_right=True
#         while q:
#             t=q.popleft()
#             tmp.append(t.val)
#             if t.left:
#                 q.append(t.left)
#             if t.right:
#                 q.append(t.right)
#             if t == last:
#                 res.append(tmp if left_to_right else tmp[::-1])
#                 left_to_right= not left_to_right
#                 tmp=[]
#                 if q:last=q[-1]
#         return res
#
#
# 58.從上到下按層打印二叉樹,同一層結點從左至右輸出。每一層輸出一行
# -*- 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 []
#         res=[]
#         tmp=[pRoot]
#         while tmp:
#             size=len(tmp)
#             row=[]
#             for i in tmp:
#                 row.append(i.val)
#             res.append(row)
#             for i in range(size):
#                 node=tmp.pop(0)
#                 if node.left:
#                     tmp.append(node.left)
#                 if node.right:
#                     tmp.append(node.right)
#         return res
#
# 59.請實現兩個函數,分別用來序列化和反序列化二叉樹
# 二叉樹的序列化是指:把一棵二叉樹按照某種遍歷方式的結果以某種格式保存爲字符串,
# 從而使得內存中建立起來的二叉樹可以持久保存。序列化可以基於先序、中序、後序、
# 層序的二叉樹遍歷方式來進行修改,序列化的結果是一個字符串,序列化時通過
# 某種符號表示空節點(#),以 ! 表示一個結點值的結束(value!)。
# 二叉樹的反序列化是指:根據某種遍歷順序得到的序列化字符串結果str,重構二叉樹。
# 例如,我們可以把一個只有根節點爲1的二叉樹序列化爲"1,",然後通過自己的函數來解析回這個二叉樹
# 略
#
# 60.給定一棵二叉搜索樹,請找出其中的第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 KthNode(self, pRoot, k):
#     # write code here
#     # 第三個節點是4
#     # 前序遍歷5324768
#     # 中序遍歷2345678
#     # 後序遍歷2436875
#     # 所以是中序遍歷,左根右
#     global result
#     result = []
#     self.midnode(pRoot)
#     if k <= 0 or len(result) < k:
#        return None
#     else:
#        return result[k - 1]
#
#  def midnode(self, root):
#     if not root:
#        return None
#     self.midnode(root.left)
#     result.append(root)
#     self.midnode(root.right)
#
#
# 61.如何得到一個數據流中的中位數?如果從數據流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從數據流中讀出偶數個數值,
# 那麼中位數就是所有數值排序之後中間兩個數的平均值。我們使用Insert()方法讀取數據流,使用GetMedian()方法獲取當前讀取數據的中位數。
# //是整數除法  理解一下!
# -*- coding:utf-8 -*-
# class Solution:
#  def __init__(self):
#     self.data = []
#
#  def Insert(self, num):
#     # write code here
#     self.data.append(num)
#     self.data.sort()
#
#  def GetMedian(self, data):
#     # write code here
#     length = len(self.data)
#     if length % 2 == 0:
#        return (self.data[length // 2] + self.data[length // 2 - 1]) / 2.0
#     else:
#        return self.data[int(length // 2)]
#
#
#
# 62.給定一個數組和滑動窗口的大小,找出所有滑動窗口裏數值的最大值。例如,如果輸入數組{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, nums, size):
#     rs = []
#     ls =  len(nums)
#     for i in range(0,(ls - size)+1,1):
#        #rs.append(max(nums[i],nums[i+1],nums[i+2]))
#        rs.append(max[i:i+size])
#     return rs
#
# num = [2,3,4,2,6,2,5,1]
# size = 3
# ss = Solution()
# print ss.maxInWindows(num,size)
#
# # -*- coding:utf-8 -*-
# class Solution:
#     def maxInWindows(self, num, size):
#         # write code here
#         if size <= 0:
#             return []
#         res = []
#         for i in xrange(0, len(num)-size+1):
#             res.append(max(num[i:i+size]))
#         return res
#
# 63.請設計一個函數,用來判斷在一個矩陣中是否存在一條包含某字符串所有字符的路徑。
# 路徑可以從矩陣中的任意一個格子開始,每一步可以在矩陣中向左,向右,向上,向下移動一個格子。
# 如果一條路徑經過了矩陣中的某一個格子,則該路徑不能再進入該格子
# 矩陣中包含一條字符串"bcced"的路徑,但是矩陣中不包含"abcb"路徑,因爲字符串的第一個字符b佔據了矩陣中的第一行第二個格子之後,路徑不能再次進入該格子。
#
# 思考,回溯法
# -*- coding:utf-8 -*-
# class Solution:
#     def hasPath(self, matrix, rows, cols, path):
#         # write code here
#         for i in range(rows):
#             for j in range(cols):
#                 if matrix[i*cols+j] == path[0]:
#                     if self.find(list(matrix),rows,cols,path[1:],i,j):
#                         return True
#         return False
#     def find(self,matrix,rows,cols,path,i,j):
#         if not path:
#             return True
#         matrix[i*cols+j]='0'
#         if j+1<cols and matrix[i*cols+j+1]==path[0]:
#             return self.find(matrix,rows,cols,path[1:],i,j+1)
#         elif j-1>=0 and matrix[i*cols+j-1]==path[0]:
#             return self.find(matrix,rows,cols,path[1:],i,j-1)
#         elif i+1<rows and matrix[(i+1)*cols+j]==path[0]:
#             return self.find(matrix,rows,cols,path[1:],i+1,j)
#         elif i-1>=0 and matrix[(i-1)*cols+j]==path[0]:
#             return self.find(matrix,rows,cols,path[1:],i-1,j)
#         else:
#             return False
#
#
# 64.地上有一個m行和n列的方格。一個機器人從座標0,0的格子開始移動,每一次只能向左,右,上,
# 下四個方向移動一格,但是不能進入行座標和列座標的數位之和大於k的格子。 例如,當k爲18時,機器人能夠進入方格(35,37),
# 因爲3+5+3+7 = 18。但是,它不能進入方格(35,38),因爲3+5+3+8 = 19。請問該機器人能夠達到多少個格子?
#
# 思路:將地圖全部放置1,遍歷能夠到達的點,將遍歷的點置0並計數1。
# 這個思路在找前後左右相連的點很有用,例如leetcode中的海島個數問題/最大海島問題都可以用這種方法來改造。
#
#
# -*- coding:utf-8 -*-
# class Solution:
#     def movingCount(self, threshold, rows, cols):
#         # write code here
#         board = [[0 for _ in range(cols)] for _ in range(rows)]
#         def block(r,c):
#             s = sum(map(int,str(r)+str(c)))
#             return s>threshold
#         class Context:
#             acc = 0
#         def traverse(r,c):
#             if not (0<=r<rows and 0<=c<cols): return
#             if board[r][c]!=0: return
#             if board[r][c]==-1 or block(r,c):
#                 board[r][c]=-1
#                 return
#             board[r][c] = 1
#             Context.acc+=1
#             traverse(r+1,c)
#             traverse(r-1,c)
#             traverse(r,c+1)
#             traverse(r,c-1)
#         traverse(0,0)
#         return Context.acc
#
#
# 65.給你一根長度爲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)
#
# 遞歸
# 我們先定義函數f(n)
# 爲把繩子剪成若干段之後的各段長度乘積的最大值.在剪第一刀的時候, 我們會有n - 1
# 種可能的選擇, 也就是說剪出來的第一段繩子的長度可能爲1, 2, ......n - 1.
# 因此就有了遞歸公式
# f(n) = max(f(i) * f(n - i)), 其中0 < i < n.
# 代碼如下:
#
# 遞歸寫法
# class Solution:
#  def cutRope(self, number):
#     # write code here
#     if number < 2:
#        return 0
#     if number == 2:
#        return 1
#     if number == 3:
#        return 2
#     return self.cutRopeCore(number)
#
#  def cutRopeCore(self, number):
#     if number < 4:
#        return number
#     max_ = 0
#     for i in range(1, number / 2 + 1):
#        max_ = max(self.cutRopeCore(i) * self.cutRopeCore(number - i), max_)
#     return max_
#
#
# # 下面介紹動態規劃的解法, 接着上面的遞歸解法我們可以將其轉換成動態規劃的寫法.由於這是一個從上至下的遞歸公式, 遞歸會出現很多大量不必要的計算, 一個很好的方法就是按照從下而上的順序計算, 即:
# # 我們先得到f(2), f(3), 再得到f(4), f(5), 直到f(n).
# # 我們可以得知f(2) = 1, f(3) = 2
# # 下面就可以寫我們的代碼啦:
#
# # 動態規劃
# class Solution:
#  def cutRope(self, number):
#     # write code here
#     if number < 2:
#        return 0
#     if number == 2:
#        return 1
#     if number == 3:
#        return 2
#     # 申請輔助空間
#     products = [0] * (number + 1)
#     # 定義前幾個初始變量的值
#     products[0] = 0
#     products[1] = 1
#     products[2] = 2
#     products[3] = 3
#     # 進行動態規劃,也就是從下向上的進行求解
#     for i in range(4, number + 1):
#        max_ = 0
#        for j in range(1, i / 2 + 1):
#           max_ = max(products[j] * products[i - j], max_)
#        products[i] = max_
#
#     max_ = products[number]
#     return max_
#
#
# 3.下面介紹貪婪算法, 我目前對這個不是很瞭解, 需要一定的數學功底, 只能先貼出代碼, 望大家諒解:
#
# # 貪婪算法
# class Solution:
#  def cutRope(self, number):
#     # write code here
#     if number < 2:
#        return 0
#     if number == 2:
#        return 1
#     if number == 3:
#        return 2
#     # 申請輔助空間
#     timesOf3 = number / 3
#     if (number - timesOf3 * 3) == 1:
#        timesOf3 -= 1
#     timesOf2 = (number - timesOf3 * 3) / 2
#     return pow(3, timesOf3) * pow(2, timesOf2)
#
#
# 求數組中第二大元素的方法
# class Solution:
#  def getSecondNum(self,num):
#     maxN = -99999
#     secN = -99999
#
#     for i in range(len(num)):
#        if num[i] > maxN:
#           secN = maxN
#           maxN  = num[i]
#        elif num[i] > secN and num[i] < maxN:
#           secN = num[i]
#        elif secN == -99999:
#           secN = num[i]
#     return secN
#
# ss = Solution()
# print  ss.getSecondNum([3,3,3,3,3])

#
#66.來理解下相應裝飾器內容
# def a_decorator(a_func):
#     def wrap_the_func():
#         print("在裝飾器前我要做這些")
#         a_func()
#         print("裝飾器後做這些")
#
#     return wrap_the_func
#
# def func_foo():
#     print("運行func_foo")
#
# def func_bar():
#     print("運行func_bar")
#
# func_foo = a_decorator(func_foo)() # func1
# func_bar = a_decorator(func_bar)() # func2
#
# @a_decorator
# def func_foo():
#     print("運行func_foo")
#
# @a_decorator
# def func_bar():
#     print("運行func_bar")
# func_foo()
#

# 67.鏈表反轉
# class Solution:
#  def fanzhuan(self,head):
#     reverseHead = None #記錄最後一個結點
#     pNode = pHead;  #開始結點
#     pPreNode = None #他的前一個結點
#     while pNode != None: #當前結點
#        pNext = pNode.next #獲取他下一個結點
#        if pNext == None: #下一個結點如果是空,證明到頭了
#           reverseHead = pNode
#        pNode.next = pPreNode #把當前結點的next置爲上一個結點
#        pPreNode = pNode     #賦值上一個結點爲當前結點
#        pNode = pNext       #當前結點的下一個結點是當前結點
#     return reverseHead
#

# 68.快速排序
# # -*- coding:utf-8 -*-
# class Solution:
#  def GetLeastNumbers_Solution(self, tinput, k):
#     # write code here
#     def quick_sort(lst):
#        if not lst:
#           return []
#        pivot = lst[0]
#        left = quick_sort([x for x in lst[1:] if x < pivot])
#        right = quick_sort([x for x in lst[1:] if x >= pivot])
#        return left + [pivot] + right
#
#     if tinput == [] or k > len(tinput):
#        return []
#     tinput = quick_sort(tinput)
#     return tinput[: k]





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