算法之递归学习

前言

最近要参加蓝桥杯,感觉虽然学过算法这门课,但是一旦真正做题就感觉力不从心,真的不会,在网上找了基础课程指导,正在一步步学习,希望可以对算法有一个新的理解。

整体思路

递归步骤:我做一部分,委托出去一部分
(1)找重复:找子问题
(2)找变化:看每次重复之间的变化,参数中要有变化的量
(3)找边界:找截止条件

题目

1、 切蛋糕思维

将蛋糕一分为二,然后逐步递推

1、字符串翻转

问题:
给一个字符串,利用递归的方式将其进行翻转
代码:

package com.lanqiao.vidio;

public class reverse {
	public static void main(String[] args) {
		System.out.println(reverse1("abcd",3));
	}
	public static String reverse1(String src,int end)
	{
		if(end==0)
		{
			return ""+src.charAt(0);
		}
		return src.charAt(end)+reverse1(src,end-1);
	}
}

思路:
每次从最后向前推进一个字符,即将字符串从最后一个不断向前切割
在这里插入图片描述
变化参数:end结束位置在不断变化

2、插入排序

1、代码:

public class insertSort {
	public static void main(String[] args) {
		int[] arr = {6,5,4,3,2,1};
		sort1(arr,arr.length-1);
		for(int a:arr)
		{
			System.out.print(a+" ");
		}
	}
	public static void sort1(int[] arr,int k)
	{
		if(k==0)
		{
			return ;
		}
		sort1(arr,k-1);
		int temp = arr[k];
		int index = k-1;
		while(index>-1&&arr[index]>temp)
		{
			arr[index+1]=arr[index];
			index--;
		}
		arr[index+1]=temp;
	}
}

2、思路
(1)将数组分成最后一个和前面k-1个元素,将前面k-1个元素顺序排好了,最后一个元素插入到前面即可
(2)每次变化的只有需要排序的元素的个数
(3)截止条件是推到第一个元素,不用排序,直接返回

3、注意点:
(1)while循环判断条件注意加上 index>-1条件,如果没有,当遇到排在第一个位置的元素会一直向前判断,数组下标异常
(2)因为在while循环中,先移动位置再对index–,所以最终指针落到的是arr[k]放的位置之前的位置,所以应放在index+1的位置

3、汉诺塔问题

1、代码:

public class hannuo {
	public static void main(String[] args) {
		Hannuo1(3,"A","B","C");
	}

	private static void Hannuo1(int i, String from, String to, String help) {
		if(i==1)
		{
			System.out.println("move "+i+"from "+from+"to "+to);
			return;
		}
		Hannuo1(i-1,from,help,to);
		System.out.println("move "+i+"from "+from+"to "+to);
		Hannuo1(i-1,help,to,from);
		
	}
}

2、思路
(1)从简单入手:当仅有三个圆盘时
1:from->help
2:from->to
1:to->help
3:from->help

在这里插入图片描述(2)N个圆盘时:
将N-1:from->help
最下面一个:from->to
N-1个:help->to
在进行了一次之后,
from空,to:1 help:i-1
from就变为的help,help就变成了from
(3)代码实现:
当仅有一个圆盘的时候,直接从form->to
当N个的时候,下面散步即为上述过程 输出相当于移动一个从from->to

4、字符串查找问题(二分法变形)

1、问题
在这里插入图片描述
2、代码

package com.lanqiao.vidio;

public class StringSearch {
	public static void main(String[] args) {
		String[] arr = {"a","","ab","","abc","b","ba"};
		System.out.println(search(arr,"aa"));
	}

	private static int search(String[] arr, String str) {
		int begin = 0;
		int end = arr.length-1;
		while(begin<=end)
		{
			int mid = begin + ((end-begin)/2);
			while(arr[mid].equals(""))//!!!
			{
				mid++;
				//注意!!
				if(mid>end) return -1;
			}
			if(str.compareTo(arr[mid])>0)
				begin=mid+1;
			else if(str.compareTo(arr[mid])<0)
				end=mid-1;
			else if(str.compareTo(arr[mid])==0)
				return mid;
		}
		return -1;
	}
}

3、思想
(1)直接套二分法代码,把比大小的地方换成compareTo即可
(2)在中点定位到空串的时候,加一,默认右边一个为中值

4、注意点
(1)在定位到空串+1的时候,不能使用if判断,因为判断之后只+1,后面还是需要判断一次空串,浪费了时间。不断向前判断,直到没有空串为止。
(2)验证的时候,使用aa进行检验的时候,判断到前面的空串+1,到”ab“,陷入死循环。因此加一步判断,mid与end,如果mid高于end直接返回-1.

2、递推公式/等价转换

1、斐波那契数列 f(n)=f(n-1)+f(n-2)
2、最大公约数 f(m,n)=f(n,m%n)

代码:

public class gcd {
	public static void main(String[] args) {
		int a=30;
		int b=50;
		System.out.println(gcd1(a,b));
	}
	public static int gcd1(int m,int n)
	{
		if(n==0)
			return m;
		return gcd1(n,m%n);
	}
}
3、二分查找

1、代码:

public class BinarySearch {
	public static void main(String[] args) {
		int[] arr = {1,3,5,7,9};
		System.out.println(search(arr,0,4,3));
	}
	public static int  search(int[] arr,int low,int high,int k)
	{
		if(low>high)
		{
			return -1;
		}
		int mid =low+(high-low)/2;
		int midVal = arr[mid];
		if(midVal<k)
			return search(arr,mid+1,high,k);
		else if(midVal>k)
			return search(arr,low,mid-1,k);
		else
			return mid;
		
	}
}

2、思路:
(1)找重复:都是从一组数中找到一个位置,即从中搜索
(2)找变化:每次high low值变化
(3)找边界:当low>high指针/找到值是结束
3、代码:
没啥好说的,注意return

4、台阶问题f(n)=f(n-3)+f(n-2)+f(n-1)

1、问题:
上台阶可以一次上3、2、1个,输入一个数字(表示距楼顶台阶数),输出一共可以有几种方式上到楼顶
2、代码

import java.util.Scanner;

public class jieti {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		System.out.println(f(n));
	}

	private static int f(int n) {
		if(n==0) return 1;
		if(n==1) return 1;
		if(n==2) return 2;
		return f(n-1)+f(n-2)+f(n-3);
	}
}

3、思路
(1)上台阶有三种方式:上一级:一种方式 上两级:两种方式(1+1、2) 上三级:四种方式(1+1+1、1+2、2+1、3)
(2)由上三级可以看出,三级=2级方式+1级方式+1(一次上三个台阶),因此可以把f(0)=1,这样既表示一次直接到达的方案

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值