劍指offer--python --數組

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

# -*- JluTiger  -*-
class Solution:
    # array 二維列表
    def Find(self, target, array):
        rows=len(array)
        cols=len(array[0])
        if rows>0 and cols>0:
            row=0
            col=cols-1
            while col>=0 and row<rows:
                if target==array[row][col]:
                    return True
                elif target<array[row][col]:
                    col-=1
                else:
                    row+=1
        return False
                   

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

方法1:直接使用replace函數
方法2:

# -*- coding:utf-8 -*-
class Solution:
    # s 源字符串
    def replaceSpace(self, s):
        return s.replace(' ','%20')

class Solution:
    # s 源字符串
    def replaceSpace(self, s):
        return "%20".join(list(s.split(" ")))
        # write code here

. join(): 連接字符串數組。將字符串、元組、列表中的元素以指定的字符(分隔符)連接生成一個新的字符串


# -*- coding:utf-8 -*-
class Solution:
    # s 源字符串
    def replaceSpace(self, s):
        # write code here
        new_s = ''
        for j in s:
            if j == ' ':
                new_s=new_s + '%20'
            else:
                new_s=new_s + j
        return new_s

3–旋轉數組的最小元素
把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。 輸入一個非減排序的數組的一個旋轉,輸出旋轉數組的最小元素。 例如數組{3,4,5,1,2}爲{1,2,3,4,5}的一個旋轉,該數組的最小值爲1。 NOTE:給出的所有元素都大於0,若數組大小爲0,請返回0。
思路1:對於數組中的元素,兩兩比較
思路2:二分查找法
思路3–sort排序
思路4–直接min函數

方法1--兩兩比較
class Solution:
    def minNumberInRotateArray(self, array):
        if len(array)==0:
            return 0
        i=0
        for i in range(len(array)):
            if (array[i]>array[i+1]):
                return array[i+1]
        return array[0]
        # write code here
class Solution:
    def minNumberInRotateArray(self, array):
        if len(array) ==0:
            return 0
        left=0
        right = len(array)-1
        mid=-1
        while(array[left]>array[right]):
            if(right-left==1):
                mid=right
                break
        mid=left+(right-left)/2
        if(array[mid]>=array[left]):
            left=mid
        if (array[mid]<array[right]):
            right=mid
        return array[mid]
循環太大
方法3:先sort排序
class Solution:
    def minNumberInRotateArray(self, rotateArray):
        # write code here
        if not rotateArray:
            return 0
        else:
            rotateArray.sort()
            return rotateArray[0]
方法4-min函數
class Solution:
    def minNumberInRotateArray(self, rotateArray):
        # write code here
        if not rotateArray:
            return 0
        else:
            return min(rotateArray)

題目5
大家都知道斐波那契數列,現在要求輸入一個整數n,請你輸出斐波那契數列的第n項(從0開始,第0項爲0)。
思路1:非遞歸實現—直接按照數列數學公式計算-滿足時間複雜度 先把n = 0,1,2,這三個項確定了再使用遞歸斐波那契數列數列從第3項開始,每一項都等於前兩項之和數列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 23。。。

方法1--非遞歸
class Solution:
    def Fibonacci(self, n):
        if n == 0:
            return 0
        if n == 1:
            return 1
        if n == 2:
            return 1
        if n > 39:
            return False
        if n >= 3:
            a = 1
            b = 1
            for i in range(n-1):
                a,b = b,a+b  #這個是重點 複雜賦值  這個都沒有用到i 是如何確定他會一直走下去的??
            return a

# -*- coding:utf-8 -*-
class Solution:
    def Fibonacci(self, n):
        result = [0,1]
        if n <= 1:
            return result[n]
        for i in range(2,n+1):
            result.append(result[i-1]+result[i-2])
        return result[n]

方法2–遞歸實現

class Solution:
    def Fibnacci(self, n):
        if n <= 0:
            return 0
        if n == 1:
            return 1
        return self.Fibnacci(n-1) + self.Fibnacci(n-2)
  1. 題目描述
    一隻青蛙一次可以跳上1級臺階,也可以跳上2級。求該青蛙跳上一個n級的臺階總共有多少種跳法(先後次序不同算不同的結果)。
    參考上一題做法
class Solution:
    def jumpFloor(self, n):
        if n <= 2:
            return n
        result = [0,1, 2]
        for i in range(3, n + 1):
            result.append(result[i - 1] + result[i - 2])
        return result[n]

若把條件修改成一次可以跳一級,也可以跳2級…也可以跳上n級呢?
直接是2**(n-1)

題目6
題目描述
我們可以用21的小矩形橫着或者豎着去覆蓋更大的矩形。請問用n個21的小矩形無重疊地覆蓋一個2*n的大矩形,總共有多少種方法?
和跳臺階的問題一樣的

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

class Solution:
    def reOrderArray(self, array):
        l1=[]
        l2=[]
        for i in range(len(array)):
            if array[i]%2==0:
                l2.append(array[i])
            else:
                l1.append(array[i])
        return l1+l2
            
        # write code here

題目8::
數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。例如輸入一個長度爲9的數組{1,2,3,2,2,2,5,4,2}。由於數字2在數組中出現了5次,超過數組長度的一半,因此輸出2。如果不存在則輸出0。
思路–這種類型的通過字典映射

# -*- coding:utf-8 -*-
class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        dict={}
        for num in numbers:
            if num not in dict:
                dict[num]=1
            else:
                dict[num]+=1
            if dict[num]>len(numbers)/2:
                return num
        return 0
            

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

思路:1、第一個不爲負數

2、如果前面數的累加值加上當前數後的值會比當前數小,說明累計值對整體和是有害的;如果前面數的累加值加上當前數後的值比當前數大或者等於,則說明累計值對整體和是有益的。
步驟:

1、定義兩個變量,一個用來存儲之前的累加值,一個用來存儲當前的最大和。遍歷數組中的每個元素,假設遍歷到第i個數時:

①如果前面的累加值爲負數或者等於0,那對累加值清0重新累加,把當前的第i個數的值賦給累加值。

②如果前面的累加值爲整數,那麼繼續累加,即之前的累加值加上當前第i個數的值作爲新的累加值。

2、判斷累加值是否大於最大值:如果大於最大值,則最大和更新;否則,繼續保留之前的最大和

class Solution:
    def FindGreatestSumOfSubArray(self, array):
        if len(array)<=0:
            return []
        temp=0
        linum=[]
        for i in array:
            temp=temp+i  注意這個是加i
            linum.append(temp)
            if temp>0:
                continue
            else:
                temp=0
        return max(linum)

題目10
輸入一個正整數數組,把數組裏所有數字拼接起來排成一個數,打印能拼接出的所有數字中最小的一個。例如輸入數組{3,32,321},則打印出這三個數字能排成的最小數字爲321323。
思路,轉化爲字符串進行比較,

# -*- coding:utf-8 -*-
  if not numbers: 
            return ""
        numbers = list(map(str, numbers))
        numbers.sort(cmp=lambda x, y: cmp(x + y, y + x)) #降序排列
        return "".join(numbers).lstrip('0') or'0'

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

思路1:
第一反應是順序掃描整個數組。每掃描到一個數組的時候,逐個比較該數字和它後面的數字的大小。如果後面的數字比它小,則這兩個數字就組成了一個逆序對。假設數組中含有n個數字。由於每個數字都要和O(n)這個數字比較,因此這個算法的時間複雜度爲O(n^2)。

def test(array):
    t=0
    for i in range(len(array)-1,0,-1):
        flag=False
        for j in range(i):
            if array[j]>array[j+1]:
                array[j],array[j+1]=array[j+1],array[j]
                t+=1
                flag=True
        if not flag:
            break
    return t%(2*(10**5))

但是這個時間複雜度太高,過不了

下面是歸併排序方法

from collections import deque 
class Solution:
    def __init__(self):
        self.count = 0
    def InversePairs(self, lis):
        self.mergeSort(lis)
        return self.count%1000000007
    def mergeSort(self, lis):
        if len(lis) <= 1:
            return lis
        middle = int(len(lis)//2)
        left = self.mergeSort(lis[:middle])
        right = self.mergeSort(lis[middle:])
        return self.merge(left, right)                      
    def merge(self, left,right):
        merged,left,right = deque(),deque(left),deque(right)
        while left and right:
            if left[0] > right[0]:
                self.count += len(left)
                merged.append(right.popleft())
            else:
                merged.append(left.popleft())
        if right:
            merged.extend(right)
        else:
            merged.extend(left)
        return merged
先將原序列排序,然後從排完序的數組中取出最小的,它在原數組中的位置表示有多少比它大的數在它前面,每取出一個在原數組中刪除該元素,保證後面取出的元素在原數組中是最小的,這樣其位置才能表示有多少比它大的數在它前面,即逆序對數。
class Solution:
    def InversePairs(self, data):
        count = 0
        copy = []
        for i in data:
            copy.append(i)
        copy.sort()
        for i in range(len(copy)):
            count += data.index(copy[i])
            data.remove(copy[i])
        return count%1000000007
a=[1,2,3,4,5,6,7,0]
Solution().InversePairs(a)

這個非常棒

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

class Solution:
    def GetNumberOfK(self, data, k):
        dict={}
        for num in data:
            if num not in dict:
                dict[num]=1
            else:
                dict[num]+=1
        if  k in dict:
            return dict[k]
        else:
            return 0

參考前面的例題,統計超過一半的數字,或者直接

return data.count(k)  #count() 方法用於統計某個元素在列表中出現的次數

題目13

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

# -*- coding:utf-8 -*-
class Solution:
    # 返回[a,b] 其中ab是出現一次的兩個數字
    def FindNumsAppearOnce(self, array):
        hashMap = {}
        for i in array:
            if str(i) in hashMap:
                hashMap[str(i)] += 1
            else:
                hashMap[str(i)] = 1
        res = []
        for k in hashMap.keys():
            if hashMap[k] == 1:
                res.append(int(k))
        return res
        # write code here

題目14-數組中重複的數字
在一個長度爲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):
        dict={}
        for num in numbers:
            if num not in dict:
                dict[num]=1
            else:
                dict[num]+=1
        for k in dict:
            if dict[k]>=2:
                duplication[0]=k
                return True
        return False
 # -*- coding:utf-8 -*-
class Solution:
    def swap(self,array,i,j):
        temp = array[i]
        array[i] = array[j] 
        array[j] = temp
    def duplicate(self, numbers, duplication):
        length = len(numbers)
        i=0
        while i < length:
            while numbers[i] != i:
                if numbers[i] == numbers[numbers[i]]:
                    duplication[0] = numbers[i]
                    return True
                self.swap(numbers,i,numbers[i])
                i += 1
        return False

題目15-構建乘積數組
給定一個數組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]。不能使用除法。
思路:

# -*- coding:utf-8 -*-
class Solution:
    def multiply(self, A):
        head = [1]
        tail = [1]
        for i in range(len(A)-1):
            head.append(A[i]*head[i])
            tail.append(A[-i-1]*tail[i])
        return [head[j]*tail[-j-1] for j in range(len(head))]
        # write code here
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章