剑指offer第二天

八、旋转数组的最小数字
二分查找的变形,注意到旋转数组的首元素肯定不小于旋转数组的尾元素,设置中间点。
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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值