劍指Offer編程題(2)變態跳臺階

1. 變態跳臺階

題目描述

一只青蛙一次可以跳上1級臺階,也可以跳上2級……它也可以跳上n級。求該青蛙跳上一個n級的臺階總共有多少種跳法。

分析

原文連接

關于本題,前提是n個臺階會有一次n階的跳法。分析如下:

f(1) = 1

f(2) = f(2-1) + f(2-2) //f(2-2) 表示2階一次跳2階的次數。

f(3) = f(3-1) + f(3-2) + f(3-3)

...

f(n) = f(n-1) + f(n-2) + f(n-3) + ... + f(n-(n-1)) + f(n-n)

說明:

1)這里的f(n) 代表的是n個臺階有一次1,2,...n階的 跳法數。

2)n = 1時,只有1種跳法,f(1) = 1

  1. n = 2時,會有兩個跳得方式,一次1階或者2階,這回歸到了問題(1) ,f(2) = f(2-1) + f(2-2)

  2. n = 3時,會有三種跳得方式,1階、2階、3階,

? 那么就是第一次跳出1階后面剩下:f(3-1);第一次跳出2階,剩下f(3-2);第一次3階,那么剩下f(3-3)

? 因此結論是f(3) = f(3-1)+f(3-2)+f(3-3)

  1. n = n時,會有n中跳的方式,1階、2階...n階,得出結論:

? f(n) = f(n-1)+f(n-2)+...+f(n-(n-1)) + f(n-n) => f(0) + f(1) + f(2) + f(3) + ... + f(n-1)

  1. 由以上已經是一種結論,但是為了簡單,我們可以繼續簡化:

? f(n-1) = f(0) + f(1)+f(2)+f(3) + ... + f((n-1)-1) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2)

? f(n) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2) + f(n-1) = f(n-1) + f(n-1)

? 可以得出:

? f(n) = 2*f(n-1)

  1. 得出最終結論,在n階臺階,一次有1、2、...n階的跳的方式時,總得跳法為:

? | 1 ,(n=0 )

f(n) = | 1 ,(n=1 )

? | 2*f(n-1),(n>=2)

代碼

public class Solution {
  public int JumpFloorII(int target) {
    if(target<=0){
      return -1;
    }else if(target==1){
      return 1;
    }else{
      return 2*JumpFloorII(target-1);
    } 
  }
}

2. 矩形覆蓋

題目描述

我們可以用21的小矩形橫著或者豎著去覆蓋更大的矩形。請問用n個21的小矩形無重疊地覆蓋一個2*n的大矩形,總共有多少種方法

分析

斐波那契數列遞歸

代碼

public class Solution {
  public int RectCover(int target) {
    if(target<=0){
      return 0;
    }else if(target==1||target==2){
      return target;
    }else{
      return RectCover(target-1)+RectCover(target-2);
    }
  }
}

3. 二進制中1的個數

題目描述

輸入一個整數,輸出該數二進制表示中1的個數。其中負數用補碼表示。

分析

定義一個變量count,記錄二進制中1的個數

(n & 1)把n與1按位與,因為1除了最低位,其他位都為0,所以按位與結果取決于n最后一位,如果n最后一位是1,則結果為1.反之結果為0。用count+=(n & 1)來記錄

每次按位于后把n向右移一位n>>>=1

代碼

public class Solution {
  public int NumberOf1(int n) {
    int count = 0;
    while(n!=0){
      count+=(n & 1);
      System.out.println(n);
      n>>>=1;
    }
    return count;
  }
}

4. 數值的整數次方

題目描述

給定一個double類型的浮點數base和int類型的整數exponent。求base的exponent次方。

保證base和exponent不同時為0

分析

  • 把exponent取絕對值進行*=保留結果
  • 如果exponent<0對結果取倒

代碼

public class Solution {
  public double Power(double base, int exponent) {
    double ss = 1;
    for (int i = 0; i < Math.abs(exponent); i++) {
      ss *= base;
    }
    if(exponent<0){
      ss = 1/ss;
    }
    return ss;
  }
}

5. 調整數組順序使奇數位于偶數前面

題目描述

輸入一個整數數組,實現一個函數來調整該數組中數字的順序,使得所有的奇數位于數組的前半部分,所有的偶數位于數組的后半部分,并保證奇數和奇數,偶數和偶數之間的相對位置不變。

分析

可以用冒泡排序的思路前一位是偶數后一位是奇數時進行交換

代碼

public class Solution {
  public void reOrderArray(int [] array) {
    int temp = 0;
    for (int i = 0; i < array.length; i++) {
      for (int j = 0; j < array.length-i-1; j++) {
        if(array[j]%2==0&&array[j+1]%2!=0){
          temp = array[j];
          array[j] = array[j+1];
          array[j+1] = temp;
        }
      }
    } 
  }
}

6. 鏈表中倒數第k個節點

題目描述

輸入一個鏈表,輸出該鏈表中倒數第k個結點。

分析

  • 遍歷得到鏈表的總長度count
  • 倒數第k個即為正數第count-k個
  • 當鏈表總長度小于k時返回null

代碼

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
  public ListNode FindKthToTail(ListNode head,int k) {
    int count = 0;
    ListNode temp = head;
    while(temp!=null){
      count++;
      temp = temp.next;
    }
    if(count<k){
      return null;
    }
    temp = head;
    for (int i = 0; i <count-k; i++) {
      temp = temp.next;
    }
    return temp;
  }
}

三種移位運算符的移動規則和使用如下所示:

<<運算規則:按二進制形式把所有的數字向左移動對應的位數,高位移出(舍棄),低位的空位補零。
  語法格式:
  需要移位的數字 << 移位的次數
  例如: 3 << 2,則是將數字3左移2位
  計算過程:
  3 << 2
  首先把3轉換為二進制數字0000 0000 0000 0000 0000 0000 0000 0011,然后把該數字高位(左側)的兩個零移出,其他的數字都朝左平移2位,最后在低位(右側)的兩個空位補零。則得到的最終結果是0000 0000 0000 0000 0000 0000 0000 1100,則轉換為十進制是12.數學意義:在數字沒有溢出的前提下,對于正數和負數,左移一位都相當于乘以2的1次方,左移n位就相當于乘以2的n次方

>>運算規則:按二進制形式把所有的數字向右移動對應巍峨位數,低位移出(舍棄),高位的空位補符號位,即正數補零,負數補1.

語法格式:
  需要移位的數字 >> 移位的次數
  例如11 >> 2,則是將數字11右移2位
  計算過程:11的二進制形式為:0000 0000 0000 0000 0000 0000 0000 1011,然后把低位的最后兩個數字移出,因為該數字是正數,所以在高位補零。則得到的最終結果是0000 0000 0000 0000 0000 0000 0000 0010.轉換為十進制是3.數學意義:右移一位相當于除2,右移n位相當于除以2的n次方

>>>運算規則:按二進制形式把所有的數字向右移動對應巍峨位數,低位移出(舍棄),高位的空位補零。對于正數來說和帶符號右移相同,對于負數來說不同。

其他結構和>>相似。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容