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
n = 2時,會有兩個跳得方式,一次1階或者2階,這回歸到了問題(1) ,f(2) = f(2-1) + f(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)
- 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)
- 由以上已經是一種結論,但是為了簡單,我們可以繼續簡化:
? 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)
- 得出最終結論,在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次方。
>>>
運算規則:按二進制形式把所有的數字向右移動對應巍峨位數,低位移出(舍棄),高位的空位補零。對于正數來說和帶符號右移相同,對于負數來說不同。
其他結構和>>相似。