算法系列之遞歸算法5個簡單實例

4月1號的藍橋杯比賽快來了,報了名的小編日夜操勞的準備着~~~

只想默默地說一句,這個算法是真的難~

已經不想吐槽它折磨我的這20天了~

每當看到自己用很冗長的代碼完成題目,大佬們簡單的幾行代碼輕鬆解決,小編的心啊,拔涼拔涼的~生無可戀~~~

大神請繞道,我不想再看到你們~~~

希望本篇文章對您有所幫助,是我最開心的事情。(淚奔~好不容易寫好了~電腦崩了~只能粗糙的寫成這樣了~)

想哭~~~~~~~~~~~~~~~~對不起你們~~~~~ 下次一定打一個字存一次草稿~(寫了兩個小時直接沒了~)

作者:浪潮之巔的小蘿蔔頭(純手打,求支持)

閒話少敘,今天小編給大家介紹的是由簡單到稍微難一些的java遞歸算法的5道小題。

首先先簡介下遞歸算法:

遞歸算法(英語:recursion algorithm)在計算機科學中是指一種通過重複將問題分解爲同類的子問題而解決問題的方法。遞歸式方法可以被用於解決很多的計算機科學問題,因此它是計算機科學中十分重要的一個概念。絕大多數編程語言支持函數的自調用,在這些語言中函數可以通過調用自身來進行遞歸。計算理論可以證明遞歸的作用可以完全取代循環,因此在很多函數編程語言(如Scheme)中習慣用遞歸來實現循環。

簡潔的講就是:可以不斷的調用自身這個函數,直到滿足一定條件結束遞歸,(一般都是遞歸到最小的單位之後進行回溯的過程)下面小編通過這五個由淺至深的題目帶領大家更好的理解神奇的遞歸算法。

第一題:斐波那契數列

/* F(0)=1,F(1)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)*/

任意輸入一個正整數的,輸出斐波那契數列正整數對應的值。

思路:本題給出了兩個常量F(0)=1,F(1)=1和一個算式F(n)=F(n-1)+F(n-2),那麼就可以設計一個函數,調用這個函數,當輸入的值爲0或1的時候,返回1,當輸入n>2時,不斷的調用該函數,知道n=1爲止,之後進行返回,算出F(n)的值。例如:n=3 F(3)=F(2)+F(1),此時需要先調用函數計算F(2)的值,F(2)=F(1)+F(0)=2,之後再返回到F(3)上,則可計算出F(3)=3;

具體代碼實現如下:

package 遞歸算法;

import java.util.Scanner;

/* F(0)=1,F(1)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)*/
public class 斐波那契數列 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n=sc.nextInt();
System.out.println(f(n));
}
public static int f(int n){
if(n==0||n==1){
return 1;
}
else{
return f(n-1)+f(n-2);
}
}
}


第二題:階乘運算

解釋:/*
* 一個正整數的階乘(factorial)是所有小於及等於該數的正整數的積,
* 並且0的階乘爲1。自然數n的階乘寫作n!。1808年,基斯頓·卡曼引進這個表示法。
* 亦即n!=1×2×3×...×n。階乘亦可以遞歸方式定義:0!=1,n!=(n-1)!×n。
*/

直接看代碼吧,心累~

代碼如下:

package 遞歸算法;

import java.util.Scanner;
/*
* 一個正整數的階乘(factorial)是所有小於及等於該數的正整數的積,
* 並且0的階乘爲1。自然數n的階乘寫作n!。1808年,基斯頓·卡曼引進這個表示法。
* 亦即n!=1×2×3×...×n。階乘亦可以遞歸方式定義:0!=1,n!=(n-1)!×n。
*/
public class 階乘運算 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n=sc.nextInt();
System.out.println(f(n));
}
public static int f(int n){
if(n==0){
return 1;
}
else{
return n*f(n-1);
}
}
}
 


第三題:漢諾塔

概念:/*漢諾塔:漢諾塔(又稱河內塔)問題是源於印度一個古老傳說的益智玩具。
* 大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞着64片黃金圓盤。
* 大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,
* 在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤。*/

直接看代碼:(扎心~)

package 遞歸算法;

import java.util.Scanner;

public class 漢諾塔 {
public static int i=1;//記錄補數
public static void main(String[] args) {
Scanner sc= new Scanner(System.in);
int n=sc.nextInt();
sc.close();
char a='a',b='b',c='c';
f(n,a,b,c);
}
public static void f(int n,char a,char b,char c){
if(n==1){
move(1,a,c);
}
else{
f(n-1,a,c,b);
move(n,a,c);
f(n-1,b,a,c);
}
}
public static void move(int n,char a,char c){
System.out.println("第"+i+"步:將"+n+"號盤子從"+a+"移動到"+c);
i++;
}
}


第四題:全排列

概念:/*
* 從n個不同元素中任取m(m≤n)個元素,按照一定的順序排列起來,
* 叫做從n個不同元素中取出m個元素的一個排列。當m=n時所有的排列情況叫全排列。
*/

直接看代碼:

package 遞歸算法;

import java.util.Arrays;
/*註釋代碼針對的是排列中出現重複的情況*/
public class 全排列 {
public static void main(String[] args) {
int array[]={1,2,3};
fullArray(array,0,array.length-1);
}
private static void fullArray(int[] array, int cursor, int end) {
if (cursor == end) {
System.out.println(Arrays.toString(array));
} else {
for (int i = cursor; i <= end; i++) {
/*if(!panduan(array,cursor,end)){
continue;
}*/
swap(array, cursor, i);
fullArray(array, cursor + 1, end);
swap(array, cursor, i); // 用於對之前交換過的數據進行還原
}
}
}
private static void swap(int array[],int cursor,int i){
int temp = array[cursor];
array[cursor]=array[i];
array[i]=temp;
}
/*private static boolean panduan(int arr[],int start,int end){
for(int i=start;i<end;i++){
if(arr[i]==arr[end]){
return false;
}
}
return true;
}*/
}
 


最終的boss:整數劃分

概念:/*
正整數n表示成一系列正整數之和:n=n1+n2+…+nk,其中n1≥n2≥…≥nk≥1,k≥1。
正整數n的這種表示稱爲正整數n的劃分。整數劃分問題便是求正整數n的不同劃分個數。
例如正整數6有如下11種不同的劃分:
6;
5+1;
4+2,4+1+1;
3+3,3+2+1,3+1+1+1;
2+2+2,2+2+1+1,2+1+1+1+1;
1+1+1+1+1+1。*/

思路:

直接看代碼吧,真心抱歉~

package 遞歸算法;

public class 整數劃分 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n=sc.nextInt();
int m=sc.nextInt();
sc.close();
System.out.println(f(n,m));
}
public static int f(int n,int m){
if((n<1)||(m<1)){
return 0;
}
if((n==1)||(m==1))
return 1;

if(n<m){
return f(n,n);
}
if(n==m){
return f(n,n-1)+1;
}
return f(n,m-1)+f(n-m,m);
}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章