面试题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)
未完待续。。。