八、旋转数组的最小数字
二分查找的变形,注意到旋转数组的首元素肯定不小于旋转数组的尾元素,设置中间点。
1. 如果中间点大于首元素,说明最小数字在后面一半
2. 如果中间点小于尾元素,说明最小数字在前一半。依次循环。
3. 同时,当一次循环中首元素小于尾元素,说明最小值就是首元素。
4. 但是当首元素等于尾元素等于中间值,只能在这个区域顺序查找。
class solution:
def minNumberInRotateArray(self,rotatearray):
if len(rotatearray) == 0:
return 0
first = 0
end = len(rotatearray)-1
minnum=rotatearray[first]
if rotatearray[first]<rotatearray[end]:
return rotatearray[first]
else:
while end - first > 1:
mid = (end + first) // 2
if rotatearray[end] < rotatearray[mid]:
first = mid
elif rotatearray[first] > rotatearray[mid]:
end = mid
elif rotatearray[first] == rotatearray[mid] and rotatearray[mid]==rotatearray[end]:
for i in range(1,len(rotatearray)):
if rotatearray[i] < minnum:
end = i
minnum = rotatearray[end]
return minnum
九、斐波那契数列/青蛙跳台阶
# -*- coding: utf-8 -*-
class Solution:
#斐波那契数列:
def Fibonacci(self,n):
tempArray = [0,1]
if n>1:
for i in range(2,n+1):
tempArray[i%2] = tempArray[0] + tempArray[1]
return tempArray[n%2]
#青蛙跳台阶:
#两个迭代
def jumpFloor(self, number):
tempArray = [1, 2]
if number > 1:
for i in range(2, number + 1):
tempArray[i % 2] = tempArray[0] + tempArray[1]
return tempArray[(number+1) % 2]
def jumpFloor2(self,number):
tempArray = [1, 2]
result=0
if number==1 or number == 2:
result = number
else:
for i in range(2,number):
result=tempArray[0]+tempArray[1]
tempArray[0] = tempArray[1]
tempArray[1] = result
return result
#递归实现
def jumpFloor3(self,number):
if number == 1 or number == 2:
return number
else:
return self.jumpFloor3(number-1) + self.jumpFloor3(number-2)
十、二进制中1的个数
# -*- coding: utf-8 -*-
class Solution():
#python 不存在整数溢出问题。所以下面两个函数不会停止
#错误解法:当为负数时怎么办? 负数用补码表示。
def NumberOf11(self,n):
count =0
while n:
if n&1:
count +=1
n>>1
print n, count
return count
def NumberOf12(self, n):
count = 0
flag =1
while flag:
flag = 1
if n & flag :
count += 1
print flag,count
flag << 1
return count
#推荐解法: 负数用补码表示。
def NumberOf13(self, n):
count = 0
if n < 0:
n = n & 0xffffffff
while n:
count += 1
n = (n - 1) & n
return count
# 判断一个数是不是2得整数次幂。也就是二进制中只有一位是1
def powerOf2(self, n):
if n & (n - 1) == 0:
return True
else:
return False
# 判断两个数的二进制表示有多少位不一样, 直接比较两个数的二进制异或就可以
def andOr(self, m, n):
diff = m ^ n
count = 0
while diff:
count += 1
diff = diff & (diff - 1)
return count
十一、数值的整数次方
# -*- coding: utf-8 -*-
class Solution:
def Power(self, base, exponent):
#此处转换为float有必要!!不然就会运算出0
base=float(base)
#判断底数是否为0 .书上说因为计算机内表示小数是有误差的,只能判断差的绝对值是否在一个很小的范围内:
if (abs(base - 0.0 ) <0.000001) and exponent < 0:
return -1
if exponent == 0:
return 1
if exponent == 1:
return base
if exponent == -1:
return 1 / base
result = self.Power(base, exponent >> 1)
print exponent >> 1
result *= result
#若为奇数,再乘一次基数
if (exponent & 0x1) == 1:
result *= base
return result
打印1到最大的n位数
from __future__ import print_function
def PrintNumber(number):
isBeginning0 = True
nLength = len(number)
for i in range(nLength):
if isBeginning0 and number[i] != '0':
isBeginning0 = False
if not isBeginning0:
print('%c' % number[i],end='')
print('')
def Print1ToMaxOfNDigits2(n):
if n <= 0:
return
number = ['0'] * n
for i in range(10):
number[0] = str(i)
Print1ToMaxOfNDigitsRecursively(number, n, 0)
def Print1ToMaxOfNDigitsRecursively(number, length, index):
if index == length - 1:
PrintNumber(number)
return
for i in range(10):
number[index + 1] = str(i)
Print1ToMaxOfNDigitsRecursively(number, length, index+1)
在O(1)时间删除链表结点:
# -*- coding: utf-8 -*-
class ListNode:
def __init__(self,x=None):
self.val = x
self.next =None
def __del__(self):
self.val=None
self.next = None
class Solution:
def DeleteNode(self,pListHead,pToBeDeleted):
if pListHead == None or pToBeDeleted == None:
return None
#非尾节点
if pToBeDeleted.next != None:
pNext = pToBeDeleted.next
pToBeDeleted.val = pNext.val
pToBeDeleted.next = pNext.next
pNext.__del__()
#单节点
elif pListHead == pToBeDeleted:
pListHead.__del__()
pToBeDeleted.__del__()
#尾节点且非单节点,遍历
else:
pNode = pListHead
if pNode.next != pToBeDeleted:
pNode = pNode.next
pNode.next=None
pToBeDeleted.__del__()
调整数组顺序使奇数位于偶数前面
# -*- coding: utf-8 -*-
class Solution:
def reOrderArray1(self,array):
ji = [x for x in array if x%2==1]
ou = [ x for x in array if x%2 == 0]
return ji +ou
def reOrderArray2(self,array):
if len(array)<1:
return []
if len(array)==1:
return array
ji = []
ou = []
for i in array:
if i%2 == 1:
ji.append(i)
else:
ou.append(i)
return ji + ou
#类似于快速排序法的实现
def reOrderArray3(self,array):
if len(array)<1:
return []
if len(array)==1:
return array
indexou = 0
indexji = len(array)-1
while indexou < indexji:
while array[indexou] & 0x1 ==1:
indexou += 1 #找出前面的偶数
while array[indexji] & 0x1 ==0:
indexji -= 1 #找出后面的奇数
array[indexou], array[indexji] = array[indexji], array[indexou]
array[indexou], array[indexji] = array[indexji], array[indexou]
return array
# 可扩展性的解法
# 注意在一个函数的输入中, 输入另一个函数的写法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 isNegtive(self, n):
return n >= 0
def ReorderOddEven(self, pData):
length = len(pData)
return self.Reorder(pData, length, func=self.isNegtive)
调整数组顺序使奇数位于偶数前面
# -*- coding:utf-8 -*-
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
def FindKthToTail(self,head,K):
#链表为空和K小于0的情况
if head==None or K<=0:
return None
Onethindex = head
Thirdthindex = None
for i in range(K-1):
if Onethindex.next != None:
Onethindex = Onethindex.next
else:
return None
Thirdthindex=head
while Onethindex.next != None:
Onethindex = Onethindex.next
Thirdthindex = Thirdthindex.next
return Thirdthindex