面試題11:旋轉數字的最小數字
# -*- coding:utf-8 -*-
'''
把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。
輸入一個遞增排序的數組的一個旋轉,輸出旋轉數組的最小元素。
例如數組{3,4,5,1,2}爲{1,2,3,4,5}的一個旋轉,該數組的最小值爲1。
NOTE:給出的所有元素都大於0,若數組大小爲0,請返回0。
'''
#折半查找(Binary Search)技術,又稱爲二分查找。前提是順序存儲。時間複雜度爲O(logn),考慮到具有n個節點的完全二叉樹的深度爲logn +1
#在二分查找中,兩個指針分別指向第一個元素和最後一個元素。
#本題的思路就是用二分查找法的思路尋找這個最小的元素。
class Solution:
def minNumberInRotateArray(self,rotateArray):
if len(rotateArray)==0:
return 0
low=0
high=len(rotateArray)-1
mid=0
while rotateArray[low]>=rotateArray[high]:#前面的數組大於等於後面的數組
if high-low==1:
mid=high
break
mid=(low+high)/2
#考慮到三值相等的情況
if rotateArray[low] == rotateArray[high] and rotateArray[low] == rotateArray[mid]:
return self.MinInOrder(rotateArray, low, high)
if rotateArray[low]<=rotateArray[mid]:
low=mid
elif rotateArray[mid]<=rotateArray[high]:
high=mid
return rotateArray[mid]
def MinInOrder(self, array, front, end):
result = array[0]
for i in array[front:end+1]:
if i < result:
result = i
return result
s=Solution()
print(s.minNumberInRotateArray([1,1,1,0,1]))
面試題15:二進制中1的個數
# -*- coding:utf-8 -*-
#輸入一個整數,輸出該數二進制表示中1的個數。其中負數用補碼錶示。
#把一個整數減去1,再和原整數做與運算,會把該整數最右邊的1變成0.
class Solution:
def NumberOf1(self, n):
# write code here
count=0
if n<0:
n=n& 0xffffffff
while n:
n=(n-1)&n
count += 1
return count
s=Solution()
print(s.NumberOf1(-2))
2的整數次方
# -*- coding:utf-8 -*-
#輸入一個整數,輸出該數二進制表示中1的個數。其中負數用補碼錶示。
#把一個整數減去1,再和原整數做與運算,會把該整數最右邊的1變成0.
#判斷是不是2的整數次方。若是,只有有一個1,其餘皆爲0.所以只要判斷經過一次減一再與自己的與遠算之後是不是爲0.
class Solution:
def NumberOf2(self, n):
# write code here
count=0
if n<0:
return False
if (n-1)&n==0:
return True
else:
return False
s=Solution()
print(s.NumberOf2(3))
兩數不同的位數
# -*- coding:utf-8 -*-
#輸入一個整數,輸出該數二進制表示中1的個數。其中負數用補碼錶示。
#把一個整數減去1,再和原整數做與運算,會把該整數最右邊的1變成0.
#判斷是不是2的整數次方。若是,只有有一個1,其餘皆爲0.所以只要判斷經過一次減一再與自己的與遠算之後是不是爲0.
#判斷兩數不同的位數,只需要先異或,不同的則爲真“1”,再統計1的個數。
class Solution:
def NumberOf1(self, n):
# write code here
count=0
if n<0:
n=n& 0xffffffff
while n:
n=(n-1)&n
count += 1
return count
def NumberOf3(self, m,n):
# write code here
diff=m^n
count=0
while diff:
count+=1
diff=(diff-1)&diff
return count
s=Solution()
print(s.NumberOf3(10,13))
面試題16:數值的整數次方
# -*- coding:utf-8 -*-
#給定一個double類型的浮點數base和int類型的整數exponent。求base的exponent次方。
#注意指數爲負數的情況,底數是零且指數是負數的情況。
# 在判斷底數base是不是等於0的時候,不能直接寫base==0, 因爲計算機內表示小數時有誤差,只能判斷他們的差的絕對值是不是在一個很小的範圍內
#用右移運算代替除以2.用位與&運算代替求餘%判斷一個數是奇數還是偶數。
class Solution:
def Power(self, base, exponent):
if exponent == 0:
return 1
if exponent == 1:
return base
if exponent == -1:
return 1/base
if base==0.0 and exponent<0:
print"Invalid input"
result = self.Power(base, exponent >> 1)
result *= result
if (exponent & 0x1) == 1:
result *= base
return result
S = Solution()
print(S.Power(0, -3))
面試題21:調整數組順序使奇數位於偶數前面
# -*- coding:utf-8 -*-
#輸入一個整數數組,實現一個函數來調整該數組中數字的順序,使得所有的奇數位於數組的前半部分,
# 所有的偶數位於位於數組的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。
class Solution:
def reOrderArray(self, array):#此方法不能保證相對位置不變
if len(array)==0:
return
if len(array)==1:
return array
low=0
high=len(array)-1
while low < high:
while low < high and array[low] & 0x01 ==1:#前面的若是奇數,則往後移動指針,注意這邊用while循環,表示如果一直是奇數的話,那就一直往後移,直到不是奇數,而不是用if判斷。
low+=1
while low < high and array[high] & 0x01==0:#後面的若是偶數,則往前移動指針
high-=1
if low<high:
array[low],array[high]=array[high],array[low]
return array
def reOrderArray2(self,array):#列表解析,是奇數的就放在left裏,是偶數就放在right裏。
left=[x for x in array if x &0x1==1]
right=[x for x in array if not x&0x1==1]
return left+right
def reOrderArray3(self,array):
if len(array)==0:
return []
if len(array)==1:
return array
OddList=[]
EvenList=[]
for item in array:
if item & 0x01==1:
OddList.append(item)
if item & 0x01==0:
EvenList.append(item)
return OddList+EvenList
# 可擴展性的解法
# 注意在一個函數的輸入中, 輸入另一個函數的寫法func = self.fucName, funcName不需要加括號
def Reorder(self, pData, length, func):
if length == 0:
return
pBegin = 0
pEnd = length - 1
while pBegin < pEnd:
while pBegin < pEnd and not func(pData[pBegin]):
pBegin += 1
while pBegin < pEnd and func(pData[pEnd]):
pEnd -= 1
if pBegin < pEnd:
pData[pBegin], pData[pEnd] = pData[pEnd], pData[pBegin]
return pData
def isEven(self, n):
return not n & 0x1
def isNegtive(self, n):
return n >= 0
def ReorderOddEven(self, pData):
length = len(pData)
return self.Reorder(pData, length, func=self.isNegtive)
s=Solution()
print(s.reOrderArray([1,2,3,4,5,7,8]))
print(s.reOrderArray2([1,2,3,4,5,7,8]))
print(s.reOrderArray3([1,2,3,4,5,7,8]))
擴展解法
# -*- coding:utf-8 -*-
#把數組中的數按照大小分爲兩部分,所有負數都在非負數的前面
#能被三整除的數都在不能被3整除的數的前面
class Solution:
def ReOrder(self,pData,length,func):
if length==0:
return
pBegin=0
pEnd=length-1
while pBegin<pEnd:
while pBegin<pEnd and func(pData[pBegin]):
pBegin+=1
while pBegin<pEnd and not func(pData[pEnd]):
pEnd-=1
if pBegin<pEnd:
pData[pBegin],pData[pEnd]=pData[pEnd],pData[pBegin]
return pData
def isOdd(self,n):#判斷是不是奇數
return n &0x01
def isNegative(self,n):
return n>=0
def OddEven(self,pData):
length=len(pData)
return self.ReOrder(pData,length,func=self.isOdd)
s=Solution()
print s.OddEven([1,2,3,4,5,6])
面試題22:鏈表中倒數第k個節點
# -*- coding:utf-8 -*-
#輸入一個鏈表,輸出該鏈表中倒數第k個結點。
#從1開始計數,則尾節點就是倒數第一個節點
#魯棒性:輸入的頭節點的指針爲空指針。以head爲頭結點的鏈表的節點總數少於k。輸入參數k爲0.
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:
return
if k<=0:
return
pAhead=head
pBehind=None
for i in range(1,k):
if pAhead.next !=None:
pAhead=pAhead.next
else:
return
pBehind=head
while pAhead.next !=None:
pAhead=pAhead.next
pBehind=pBehind.next
return pBehind
node1=ListNode(10)
node2=ListNode(18)
node3=ListNode(2)
node1.next=node2
node2.next=node3
s=Solution()
print s.FindKthToTail(node1,2).val
面試題24:翻轉鏈表
# -*- coding:utf-8 -*-
#輸入一個鏈表,反轉鏈表後,輸出鏈表的所有元素。
#關鍵是要定義三個指針,當前的節點,它的前一個節點,後一個節點。
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
# 返回ListNode
def ReverseList(self, pHead):
pReversedHead=None
cur=pHead
pre=None
while cur !=None:
if cur.next==None:
pReversedHead=cur
tmp=cur.next
cur.next=pre
pre=cur
cur=tmp
return pReversedHead
def ReverseList2(self,pHead):
# if pHead==None:
# return None
# if pHead.next==None:
# return pHead
if not pHead or not pHead.next:
return pHead
else:
pReversedHead=self.ReverseList2(pHead.next)
pHead.next.next=pHead
pHead.next=None#去掉往後的指針
return pReversedHead
node1=ListNode(10)
node2=ListNode(11)
node3=ListNode(8)
node1.next=node2
node2.next=node3
s=Solution()
print(s.ReverseList2(node1).val)
面試題25:合併兩個排序的鏈表
# -*- coding:utf-8 -*-
#輸入兩個單調遞增的鏈表,輸出兩個鏈表合成後的鏈表,當然我們需要合成後的鏈表滿足單調不減規則。
#注意魯棒性。第一個鏈表爲空,返回第二個鏈表;第二個鏈表爲空,返回第一個鏈表;兩個都是空。得到空鏈表。
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
# 返回合併後列表
def Merge(self, pHead1, pHead2):
# write code here
if pHead1==None:
return pHead2
elif pHead2==None:
return pHead1
pMergeHead=None
if pHead1.val < pHead2.val:
pMergeHead=pHead1
pMergeHead.next=self.Merge(pHead1.next,pHead2)
else:
pMergeHead=pHead2
pMergeHead.next=self.Merge(pHead1,pHead2.next)
return pMergeHead
node1 = ListNode(1)
node2 = ListNode(3)
node3 = ListNode(5)
node1.next = node2
node2.next = node3
node4 = ListNode(2)
node5 = ListNode(4)
node6 = ListNode(6)
node4.next = node5
node5.next = node6
S = Solution()
head=S.Merge(node1, node4)
print(head.val)
未完待續。。。