剑指offer - 题5~11(栈&队列、旋转数组、斐波那契数列、跳台阶、矩形覆盖方法、二进制补码)

41 篇文章 0 订阅
25 篇文章 0 订阅

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        # 栈A存储新来的元素,栈B用作出队列操作,不为空时直接pop,为空时要将栈A中所有元素push到栈B中进行pop操作
        self.stackA=[]
        self.stackB=[]
    def push(self, node):
        # write code here
        self.stackA.append(node)
    def pop(self):
        # return xx
        # 栈B不为空时,直接pop
        if self.stackB:
            return self.stackB.pop()
        # 栈A和栈B都为空时,返回None
        elif not self.stackA:
            return None
        else:
            while self.stackA:
                self.stackB.append(self.stackA.pop())
            return self.stackB.pop()

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

# -*- coding:utf-8 -*-
class Solution:
    def minNumberInRotateArray(self, rotateArray):
        # write code here
        # python可直接使用min()函数
        # 也可以先排序,再输出第一个元素,rotateArray.sort()
        # 最小的元素一定是旋转前第一个元素,集旋转后子数组后的第一个元素,此方法代码如下:
        if not rotateArray:
            return 0
        i=0
        while i+1<=len(rotateArray)-1:
            # 注意此处要带“=”
            if rotateArray[i]<=rotateArray[i+1]:
                i+=1
            else:
                return rotateArray[i+1]
        return rotateArray[-1]
        
        # 二分法代码如下:
        if not rotateArray:
            return 0
        left=0
        right=len(rotateArray)-1
        while left+1<right:
            mid=(left+right)/2
            temp_value=rotateArray[mid]
            if temp_value<=rotateArray[right]:
                right=mid
            elif temp_value>=rotateArray[left]:
                left=mid
            
        return rotateArray[right]

大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0,第1项是1)。
n<=39

# -*- coding:utf-8 -*-
class Solution:
    def Fibonacci(self, n):
        # write code here
        # 递归做法,会导致栈溢出:
        if n>=2:
            return self.Fibonacci(n-1)+self.Fibonacci(n-2)
        else:
            return n
        
        # 迭代做法:
        a0=0
        a1=1
        if n<=1:
            return n
        pre=a0
        now=a1
        temp=pre
        i=2
        while i<=n:
            pre=now
            now=now+temp
            temp=pre
            i+=1
        return now

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。和上一题思路完全一致

# -*- coding:utf-8 -*-
class Solution:
    def jumpFloor(self, number):
        # write code here
        # 本质上是一个斐波那契数列问题,跳1阶+跳2阶,f(n)=f(n-1)+f(n-2),递归计算慢
        if number <=2:
            return number
        return self.jumpFloor(number-1)+self.jumpFloor(number-2)
        
        # 迭代:
        a0=1
        a1=2
        if number<=2:
            return number
        pre=a0
        now=a1
        temp=pre
        i=3
        while i<=number:
            pre=now
            now=now+temp
            temp=pre
            i+=1
        return now

一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。(变态做法!!)

# -*- coding:utf-8 -*-
class Solution:
    def jumpFloorII(self, number):
        # write code here
        # 推导可知:f(n) = 2*f(n-1)
        if number <=2:
            return number
        return self.jumpFloorII(number-1)*2

我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?

比如n=3时,2*3的矩形块有3种覆盖方法:
在这里插入图片描述
** 代码如上,不再重复

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

# -*- coding:utf-8 -*-
class Solution:
    def NumberOf1(self, n):
        # write code here
        count=0
        if n < 0:
        	# 思路参考@AlenZhang,首先判断n是不是负数,当n为负数的时候,直接用后面的while循环会导致死循环,因为负数向左移位的话最高位补1 ! 因此需要一点点特殊操作,可以将最高位的符号位1变成0,也就是n & 0x7FFFFFFF,这样就把负数转化成正数了,唯一差别就是最高位由1变成0。
            n = n & 0xffffffff
        while n!=0:
            # 思路参考牛客网@菩提旭光
            n=n&(n-1)
            count+=1
        return count
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值