算法开端

  编程语言有很多,但也只是一个工具而已,重要的是解决问题的方法清晰的出现在我们的脑子里,然后用一种编程语言把它描述出来
  算法的5个特性
  有穷性(Finiteness)
  算法的有穷性是指算法必须能在执行有限个步骤之后终止;
  确切性(Definitness)
  算法的每一步骤必须有确切的定义;
  输入项(Input)
  一个算法有0个或多个输入,以刻画运算对象的初始情况,所谓0个输入是指算法本身定出了初始条件;
  输出项(Output)
  一个算法有一个或多个输出,以反映对输入数据加工后的结果。没有输出的算法是毫无意义的。
  可行性(Effectiveness)
  算法中执行的任何计算步骤都是可以被分解为基本的可执行的操作步骤,即每个计算步骤都可以在有限时间内完成(也称之为有效性)。
  衡量算法的指标:时间复杂度和空间复杂度

计算机:
计算机的优势非常明显,速度、记忆、准确,但它也不是万能的。就算计算机速度快,也不能给它无限大的工作量,就算速度再快的计算机,在O(N^N)等复杂度的算法面前也是无能为力。
动态规划之斐波那契数列
数学上的斐波那契数列是一组特殊的数列,从第三项起每一项都是前两项的和,例如1 ,1 ,2,3,5,8,13,21,34,55
那么如何求这个数列呢
解法一:运用递归求

public int fei1(int n) {
		if(n==1||n==2)
			return 1;
		else 
			return fei1(n-1)+fei1(n-2);
	}

虽然递归的代码简单,但是在计算机上的效率是很低的,为什么说低呢,
想算出fei1(10),就要先算出fei1(9),

想算出fei1(9),就要先算出fei1(8),

想算出fei1(8),就要先算出fei1(7),

想算出fei1(7),就要先算出fei1(6)……
在这里插入图片描述
可以发现上面有很多重复,进行了不必要的运算,那么如何解决这个问题呢?那就把前面计算的结果保存下来,然后按照递推求出第n项。
解法二:

public long fei2(long n) {
		if(n==1||n==2)
			return 1;
		else {
		  long arr[]=new long[(int) n];
		  arr[0]=1;arr[1]=1;
		  for(int i=2;i<n;i++) {
			  arr[i]=arr[i-1]+arr[i-2];
		  }
		  return arr[(int) (n-1)];				  
		}
	}

可以看出,时间o(n),空间o(n)。所以运算效率要比解法一快很多,但是这样却浪费了很大的空间,因为斐波那契数列只需要前两项的值就行了。
解法三:

public long fei3(long n) {
		long a=1;
		long b=1;
		long c=0;
		for(int i=0;i<n;i++) {
			a=b;
			b=c;
			c=a+b;
		}
		return c;
	}

```java
public static void main(String[] args) {
		System.out.println(new test002().fei1(50));
		System.out.println(new test002().fei2(100));
		System.out.println(new test002().fei3(100));
	}

例2:**一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。**
依旧是找递推关系:

1)跳一阶,就一种方法

2)跳两阶,它可以一次跳两个,也可以一个一个跳,所以有两种

3)三个及三个以上,假设为n阶,青蛙可以是跳一阶来到这里,或者跳两阶来到这里,只有这两种方法。

它跳一阶来到这里,说明它上一次跳到n-1阶,

同理,它也可以从n-2跳过来

f(n)为跳到n 的方法数,所以,f(n)=f(n-1)+f(n-2)
同理很多问题都可以用这种思想优化,只不过是递推的关系不一样
例三:
我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?提示,大矩形看做是长度吧

请读者自己先思考一下吧。。。仔细看题。。仔细思考

如果n是1,只有一种,竖着放呗;n是2,两种:
题意应该理解了吧?

读到这里,你们应该能很快想到,依旧是斐波那契式递归啊。

对于n>=3:怎么能覆盖到三?只有两种办法,从n-1的地方竖着放了一块,或者从n-2的位置横着放了两块呗。

和问题二的代码都不用变。
例四:
**给定一个由0-9组成的字符串,1可以转化成A,2可以转化成B。依此类推。。25可以转化成Y,26可以转化成z,给一个字符串,返回能转化的字母串的有几种?

比如:123,可以转化成

1 2 3变成ABC,

12 3变成LC,

1 23变成AW,三种,返回三,

99999,就一种:iiiii,返回一。

分析:求i位置及之前字符能转化多少种。

两种转化方法,一,字符i自己转换成自己对应的字母,二,和前面那个数组成两位数,然后转换成对应的字母

假设遍历到i位置,判断i-1位置和i位置组成的两位数是否大于26,大于就没有第二种方法,f(i)=f(i-1),想反,等于f(i-1)+f(i-2)


发布了37 篇原创文章 · 获赞 19 · 访问量 849

猜你喜欢

转载自blog.csdn.net/qq_44867340/article/details/103246087