剑指offer-旋转数组,斐波那契数列,比特1的个数

旋转数组

描述

将有序数组的前n个数移到数组最后称为旋转数组。求数组中最小的元素。

思路

顺序查找时间复杂度为O(n),序列分为两段,两段都是有序的,且大多数情况下第一段的数大于第二段,这就可以用二分查找,如[3,4,5,1,2]
,当index1+1=index2时,nums[index2]为所要找的数。但是也有特殊情况,如[0,1,0,0,0],index1,index2和mid指向的数字大小相同,此时只能顺序查找。

代码:

def find_min_num(nums):
    if not nums:
        return None
    index1=0
    index2=len(nums)-1

    while nums[index1]>=nums[index2]:
        mid = int((index1 + index2) / 2)   #必须为整数
        if index1+1==index2:
            return nums[index2]

        if nums[index1]==nums[index2] and nums[index1]==nums[mid]:
            return find_in_order[nums]
        if nums[mid]>nums[index1]:
            index1=mid
        elif nums[mid]<nums[index2]:
            index2=mid

    return nums[0]
def find_in_order(nums):
    min=nums[0]
    for it in nums:
        if it<min:
            min=it
    return  min
nums=[3,4,5,6,0,1,2]
nums1=[1,0,0,1]
print(find_min_num(nums))

斐波那契数列

描述

F(1)=1,F(2)=1,F(n)=F(n-1)+F(n-2)

思路:

用递归的方法好理解,但存在时间和空间效率问题。用非递归的方式则情况更好。
青蛙跳台阶的题(青蛙可以跳一阶或二阶,问跳上n阶台阶的方法数目)也可以用斐波那契数列来理解。跳上第n阶台阶可以从第n-2阶往上跳或第n-1阶往上跳。就是F(n)=F(n-1)+F(n-2)

代码:

def fib_for(n):
    if n==0:
        return 0
    elif n==1:
        return 1
    elif n>=2:
        fibN=0
        f1=0
        f2=1
        for i in range(2,n+1):
            fibN=f1+f2
            f1=f2
            f2=fibN
        return fibN
#青蛙跳数
def fib(n):
    if n==1:
        return 1
    elif n==2:
        return 2
    else:
        return fib(n-1)+fib(n-2)

比特1的个数

描述:

输入一个整数,求它二进制表示中1的个数

思路:

一个整数减去1再和原数&一下就可以去掉最低位的1如 111000->110111,110111&111000=110000,最后可以去掉所以的1变为000000。而用数向右移动的做法,负数会在左边产生额外的1,陷入死循环。另外二进制向右移动一位,等价于/2,但是位操作的效率远大于/操作

代码:

def cnt_of_bit(n):
    cnt=0
    while n:
        cnt+=1
        n=(n-1)&n
    return cnt
print(cnt_of_bit(9))

原文地址:https://www.cnblogs.com/void-lambda/p/12330717.html

时间: 2024-08-29 20:49:03

剑指offer-旋转数组,斐波那契数列,比特1的个数的相关文章

【剑指Offer】07 - 斐波那契数列

斐波那契数列 时间限制:1秒 空间限制:32768K 本题知识点:递归 题目描述: 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0). n<=39 public class Solution { public int Fibonacci(int n) { } } 解法一: /** * 暴力递归法(性能超级差,谁试谁知道) */ public class Solution { public int Fibonacci(int n) { if(n

《剑指Offer》题目——斐波拉契数列

题目描述:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项.(n<=39) 题目分析:如果使用简单的递归,很容易造成栈溢出.采用递推的方式即可. 代码: public class Fibonacci { public static int fibonacci(int n){ int res[] = new int[2]; res[0]=1; res[1]=1; int temp = 0; if(n==0) return 0; if(n<=2) return res[

剑指offer系列——7.斐波拉契数列

Q:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0). n<=39 C:时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 32M,其他语言64M A:最简单的就是递归-- int Fibonacci(int n) { if (n == 1 || n == 2) return 1; else if (n == 0) return 0; else { return Fibonacci(n - 1) + Fibonacci(n - 2);

剑指offer-矩形覆盖-斐波那契数列(递归,递推)

class Solution { public: int rectCover(int number) { if(number==0 || number==1||number==2) return number; return rectCover(number-1)+rectCover(number-2); } }; *******************************************************************************************

求斐波那契数列的第n个数(递归、非递归)

用递归的方式求斐波那契数列的第n个数. 用非递归的方式求斐波那契数列的第n个数. 定义: 斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368 特别指出:第0项是0,第1项是第一个1. 这个数列从第2项开始,每一项都等于前两项之和. #include<stdio.h> #include<stdlib.

LintCode-查找斐波纳契数列中第 N 个数

题目: 查找斐波纳契数列中第 N 个数. 所谓的斐波纳契数列是指: 前2个数是 0 和 1 . 第 i 个数是第 i -1 个数和第 i -2 个数的和. 斐波纳契数列的前10个数字是: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ... 注意事项 The Nth fibonacci number won't exceed the max value of signed 32-bit integer in the test cases. 样例 给定 1,返回 0 给定 2,返

【c语言】求斐波那契数列的前40个数。特点,第1,2个数为1,从第三个数开始,该数是前面两个数之和

// 求斐波那契数列的前40个数.特点,第1,2个数为1,从第三个数开始,该数是前面两个数之和 #include <stdio.h> int main() { int a = 1; int b = 1; int c,i; printf("%d\t%d\t",a,b); for(i = 3; i <= 40; i++) { c = a + b; printf("%d\t",c); a = b; b = c; } printf("\n&quo

剑指offer 旋转数组

class Solution { public: int minNumberInRotateArray(vector<int> rotateArray) { //常规的遍历方法时间是O(N)的,需要使用二分法,这样对于不重复的数组,就能实现O(logN)的时间 int l=0,r=rotateArray.size()-1; if(r<0)return NULL;//空数组 int m=0; while(l<r){//当左指针小于右指针的时候,继续二分法 //下面分两种情况讨论:①数

剑指offer——旋转数组的最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. 建议读者自己思考以后再看答案 废话不多说,看代码: public class MinNumberInRotateArray { public static int minNumberInRotateArray(int [] arr) { int low = 0; int high = a

[剑指offer] 旋转数组的最小数字

题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个非递减序列的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. 输入描述 一个非递减序列的一个旋转数组 输出描述 输出旋转数组的最小元素 题目分析 原数组最小的值必然是第一个,旋转后数组是两个非递减数组的拼接,只要找到第二个非递减数组的第一个元素就是最小值. 遍历旋转数组,只要有array[i+1]小于array[i],那么array[i+1]