典型递归问题
程序员文章站
2022-05-08 22:54:22
...
文章目录
1 把一个数组里的数进行组合全部列出,比如1和2列出来为1,2,12,21
1.1 伪码
- 初始化input,visited,result
- 算法开始,从数组input的不同位置开始,执行下面伪码:
go(input,visited,result,i){
//先对visited进行深拷贝
visited[i]=true;
result.add(input[i]);
打印出result;
for循环,如果visited里面存在fasle项,就go(input,visited,result,false项的地址);
result.remove(result.size() - 1);
}
1.2 代码实现
public static void main(String args[]) {
// 获取输入
Scanner s = new Scanner(System.in);
String str = s.nextLine();
String[] temp = str.split("\\s+");
int[] input = new int[temp.length];
for (int i = 0; i < temp.length; ++i) {
input[i] = Integer.valueOf(temp[i]);
}
ArrayList<Integer> result = new ArrayList<Integer>();
// 算法
boolean[] visited = new boolean[input.length];// 用于标记元素是否被访问
for (int i = 0; i < input.length; ++i) {
go(input, visited, result, i);
result.remove(result.size() - 1);//第一个添加的数,只能这样删除
}
};
public static void go(int[] input, boolean[] visited, ArrayList<Integer> result, int i) {
boolean myVisited[] = new boolean[visited.length];// 用于实现深拷贝
System.arraycopy(visited, 0, myVisited, 0, visited.length);
myVisited[i] = true;
result.add(input[i]);
display(result);
// 继续递归
for (int k = 0; k < myVisited.length; ++k) {
// 看是否还有没被访问的元素(都是按地址从小到大访问的)
if (myVisited[k] == false) {
// result.add(input[i]);//没加一个数就打印一次
// display(result);
go(input, myVisited, result, k);
result.remove(result.size() - 1);
}
}
// 每个标记都被访问完
// result.remove(result.size()-1);
}
public static void display(ArrayList<Integer> result) {
for (int iterator : result) {
System.out.print(iterator);
}
System.out.println();
}
2 试用递归的方法编程计算非波那契数列的通项f(n),已知f1=1,f2=1,以后每项都是前两项的和。
2.1 伪码
简单,不写了。
2.2 代码实现
package temp;
import java.util.Scanner;
public class temp {
private static final int F1=1;
private static final int F2=1;
public static void main(String args[]) {
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
int result=f(n);
System.out.println(result);
};
public static int f(int n){
if(n==1){
return F1;
}else if(n==2){
return F2;
}
else{
return f(n-2)+f(n-1);
}
}
}
3 一个字符串中可能包含a~z中的多个字符,如有重复,如String data=“aadfasdfdfadflkfasf”,求出现次数最多的那个字母及次数,如有多个重复的则都求出。
这道题与递归毫无关系(不知道Jav程序员面试宝典那本书为什么要把这道题放在那个地方)。
3.1 思路
这道题,简单,我想到了用hashMap存储结果,因为放入重复的key时,后放的那个会覆盖已经有的那个key。
3.2 代码实现
注意:Map类型的遍历,先取出它的keySet,再根据keySet遍历Map。
public class temp2 {
public static void main(String args[]) throws IOException {
// 获取输入
Scanner s = new Scanner(System.in);
String str = s.nextLine();
LinkedHashMap<Character, Integer> resultMap = new LinkedHashMap<Character, Integer>();
for (int i = 0; i < str.length(); ++i) {
// 如果resultMap中没有当前字符的信息,就添加
Integer temp = resultMap.get(str.charAt(i));
if (temp == null) {
resultMap.put(str.charAt(i), 1);
} else {
resultMap.put(str.charAt(i), temp + 1);
}
}
// 查找最大值
LinkedHashMap<Character, Integer> realResult=findMax( resultMap);
//打印出结果
Set<Character> set=realResult.keySet();
for(Character temp:set){
System.out.println(temp+"出现的次数:"+realResult.get(temp));
}
}
public static LinkedHashMap<Character, Integer> findMax(LinkedHashMap<Character, Integer> resultMap){
Set<Character> set=resultMap.keySet();
LinkedHashMap<Character, Integer> realResult=new LinkedHashMap<Character, Integer>();
int max=0;
Character c=null;
for(Character temp:set){
if(resultMap.get(temp)>max){
max=resultMap.get(temp);
c=temp;
}
}
//将结果存入realResult
realResult.put(c, max);
//查找重复最大的
for(Character temp:set){
if(resultMap.get(temp)==max){
c=temp;
realResult.put(c, max);
}
}
return realResult;
}
}
4 利用1、2、2、3、4这5个数字,用java写一个main函数,打印出所有不同的排列,如12234,21234(不能存在重复,比如出现两个12234)
4.1 思路
- 将1,2,2,3,4看成5个不同的字符A,B,C,D,E进行排列
- 利用set集合不能放重复元素的特性,去掉相同的排列
4.2 代码实现
public class temp2 {
private static int size = 5;
public static int[] input = new int[size];// 放在这里是为了避免递归时,频繁传递参数input
private static HashSet<String> realSet = new HashSet<String>();// 用于去重,放在这里是为了避免递归时,频繁传递参数input
public static void main(String args[]) throws IOException {
// 初始化一些数据
Scanner scn = new Scanner(System.in);// 用于接受1 2 2 3 4
String str = scn.nextLine();
String[] temp = str.split("\\s+");
for (int i = 0; i < size; ++i) {
input[i] = Integer.valueOf(temp[i]);
}
boolean[] visited = new boolean[size];
for (int i = 0; i < size; i++) {
go(visited, i, "");
}
// 打印出结果
for (String iterator : realSet) {
System.out.println(iterator);
}
}
public static void go(boolean[] visited, int i, String resultStr) {
// 深拷贝visited与resultStr
boolean[] myVisited = new boolean[size];
char[] myResultChar = new char[resultStr.length()];
System.arraycopy(visited, 0, myVisited, 0, size);
System.arraycopy(resultStr.toCharArray(), 0, myResultChar, 0, resultStr.length());
String myResultStr = new String(myResultChar);
// 访问第i个元素
myVisited[i] = true;
myResultStr += input[i];
for (int k = 0; k < myVisited.length; ++k) {
if (myVisited[k] == false) {
go(myVisited, k, myResultStr);
}
}
//是否所有的元素都被访问了
boolean isAllVisited = true;
for (int k = 0; k < myVisited.length; ++k) {
if (myVisited[k] == false) {
isAllVisited = false;
break;
}
}
if (isAllVisited) {
realSet.add(myResultStr);
}
}
}
上一篇: 【二进制】17倍
推荐阅读
-
域名和cookie问题(域名后缀)
-
Bootstrap modal 多弹窗之叠加引起的滚动条遮罩阴影问题
-
解决eclipse中egit中的cannot open git-upload-pack问题
-
Adobe Dreamweaver CC完美破解补丁amtlib.dll 解决进程CPU占用高问题
-
illegal opcode 红屏报错(hp 360 G6安装win2003)问题解决方法
-
企业在做微博营销的过程中需要注意四大问题
-
在笔记本中Virtual PC 2007的问题及解决方案
-
自媒体营销企业微博运用应该注意的问题
-
Mysql数据库从5.6.28版本升到8.0.11版本部署项目时遇到的问题及解决方法
-
微信小程序之onLaunch与onload异步问题详解