一、 二分查找算法(非递归)

二分查找算法(非递归)介绍

QQ截图20200904193842.jpg

二分查找算法(非递归)代码实现

数组 {1,5,8,9,10,20}, 编程实现二分查找, 要求使用非递归的方式完成.

  1. package xyz.changlu.binarySearchAlgorithm;
  2. public class BinarySearch {
  3. public static void main(String[] args) {
  4. int[] arr = {1,5,8,9,10,20};
  5. int valueCur = binarySearch(arr, 30);
  6. if(valueCur != -1) {
  7. System.out.println("找到值为1的位置,位置为:"+valueCur);
  8. }else {
  9. System.out.println("未找到值为1的位置");
  10. }
  11. }
  12. //非递归进行查找
  13. public static int binarySearch(int[] arr,int findValue) {
  14. int left = 0;
  15. int right = arr.length-1;
  16. while(left<=right) {
  17. int mid = (left+right)/2;
  18. //如果找到了
  19. if(findValue == arr[mid]) {
  20. return mid;//返回下标
  21. }else if(findValue<arr[mid]) {//如果查找值比中间值小
  22. right = mid - 1;
  23. }else {//如果查找值比中间值大
  24. left = mid + 1;
  25. }
  26. }
  27. return -1;
  28. }
  29. }

运行结果:
QQ截图20200904194008.jpg
**


二、分治算法

1、分治算法介绍

QQ截图20200906091050.jpg

2、分治算法的基本步骤

分治法在每一层递归上都有三个步骤:
1) 分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题
2) 解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题
3) 合并:将各个子问题的解合并为原问题的解。

3、分治(Divide-and-Conquer(P))算法设计模式如下

QQ截图20200906091208.jpg

4、汉诺塔(分治)

汉诺塔的传说

QQ截图20200906095300.jpg

汉诺塔游戏的演示和思路分析

QQ截图20200906095324.jpg

代码实现

说明:采用了分治的算法,层层递归下去

  1. package xyz.changlu.dac;
  2. public class Hanoitower {
  3. public static void main(String[] args) {
  4. hanoitower(3, 'a', 'b', 'c');
  5. }
  6. public static void hanoitower(int n, char a, char b, char c) {
  7. if (n == 1) {
  8. System.out.println(a + "->" + c);
  9. } else {
  10. hanoitower(n - 1, a, c, b);
  11. System.out.println(a + "->" + c);
  12. hanoitower(n - 1, b, a, c);
  13. }
  14. }
  15. }

三、动态规划算法

1、应用场景-背包问题

QQ截图20200906111248.jpgQQ截图20200906111300.jpg

2、动态规划算法介绍

QQ截图20200906111334.jpg

3、动态规划算法最佳实践-01背包问题

题意分析

QQ截图20200906111459.jpg
注意这里的两个要求,物品不能重复以及背包总价值最大且重量不超出

思路分析和图解(包含示例)

QQ截图20200906153131.jpgQQ截图20200906153144.jpg

示例:
QQ截图20200906153225.jpg

代码实现

源代码:KnapsackProblem.java

(1)打印填充的对应表(未完善)

QQ截图20200906154812.jpg

  1. package dynamic;
  2. //背包问题
  3. public class KnapsackProblem {
  4. public static void main(String[] args) {
  5. //设置一维数组 分别是记录商品的价格(v表示value)以及商品的重量(w表示weight)
  6. //注意这里第一个位置留空为0 有用数据为下标0之后的
  7. int[] v = {0,1500,3000,2000};
  8. int[] w = {0,1,4,3};
  9. int n = 4;//表示背包中能够存放4磅物品
  10. int m = v.length-1;//用于表示有几件商品
  11. //定义一个二维数组 用来存放商品的总金额
  12. //行下标1 2 3对应着的v数组的下标1 2 3 行数为商品数量
  13. //列下标1 2 3 4代表着1磅 2磅 3磅 4磅等情况 列数为总磅数数量
  14. int[][] vs = new int[m+1][n+1];//行列都需要空出来一行一列为0
  15. //行列从第一行第一列开始计算
  16. for(int i = 1;i<vs.length;i++) {
  17. for(int j = 1;j<vs[i].length;j++) {
  18. //如果要添加的商品大于当前列对应磅数 来存取上一件物品(i-1)对应的金额
  19. if(w[i]>j) {
  20. vs[i][j] = vs[i-1][j];
  21. }else if(j>=w[i]) {
  22. //vs[i-1][j]与v[i]+vs[i-1][j-w[i]]作比较
  23. //vs[i-1][j]表示对应磅数上一件物品的存取金额
  24. //v[i]+vs[i-1][j-w[i]] 表示当前物品金额+上一件物品的(当前列磅数-当前物品磅数)位置的存放金额
  25. vs[i][j] = Math.max(vs[i-1][j], v[i]+vs[i-1][j-w[i]]);
  26. }
  27. }
  28. }
  29. //用于打印二维数组数据
  30. for (int i = 0; i < vs.length; i++) {
  31. for (int j = 0; j < vs[i].length; j++) {
  32. System.out.print(vs[i][j]+" ");
  33. }
  34. System.out.println();
  35. }
  36. }
  37. }

运行结果:
QQ截图20200906154924.jpg

(2)打印出对应背包的商品项(完善)

修改部分:
QQ截图20200906155507.jpgQQ截图20200906155543.jpgQQ截图20200906155601.jpg
对应path表的值:
QQ截图20200906160028.jpg

  1. package dynamic;
  2. //背包问题
  3. public class KnapsackProblem {
  4. public static void main(String[] args) {
  5. //设置一维数组 分别是记录商品的价格(v表示value)以及商品的重量(w表示weight)
  6. //注意这里第一个位置留空为0 有用数据为下标0之后的
  7. int[] v = {0,1500,3000,2000};
  8. int[] w = {0,1,4,3};
  9. int n = 4;//表示背包中能够存放4磅物品
  10. int m = v.length-1;//用于表示有几件商品
  11. //定义一个二维数组 用来存放商品的总金额
  12. //行下标1 2 3对应着的v数组的下标1 2 3 行数为商品数量
  13. //列下标1 2 3 4代表着1磅 2磅 3磅 4磅等情况 列数为总磅数数量
  14. int[][] vs = new int[m+1][n+1];//行列都需要空出来一行一列为0
  15. //为了记录商品的情况
  16. int[][] path = new int[m+1][n+1];
  17. //行列从第一行第一列开始计算
  18. for(int i = 1;i<vs.length;i++) {
  19. for(int j = 1;j<vs[i].length;j++) {
  20. //如果要添加的商品大于当前列对应磅数 来存取上一件物品(i-1)对应的金额
  21. if(w[i]>j) {
  22. vs[i][j] = vs[i-1][j];
  23. }else if(j>=w[i]) {
  24. //vs[i-1][j]与v[i]+vs[i-1][j-w[i]]作比较
  25. //vs[i-1][j]表示对应磅数上一件物品的存取金额
  26. //v[i]+vs[i-1][j-w[i]] 表示当前物品金额+上一件物品的(当前列磅数-当前物品磅数)位置的存放金额
  27. //vs[i][j] = Math.max(vs[i-1][j], v[i]+vs[i-1][j-w[i]]);
  28. //与上面相同
  29. if(vs[i-1][j]>v[i]+vs[i-1][j-w[i]]) {
  30. vs[i][j] = vs[i-1][j];
  31. }else {
  32. vs[i][j] = v[i]+vs[i-1][j-w[i]];
  33. //这里多出来步骤 将信息存入到path数组中
  34. path[i][j] = 1;
  35. }
  36. }
  37. }
  38. }
  39. //用于打印二维数组数据
  40. for (int i = 0; i < vs.length; i++) {
  41. for (int j = 0; j < vs[i].length; j++) {
  42. System.out.print(vs[i][j]+" ");
  43. }
  44. System.out.println();
  45. }
  46. System.out.println("============================");
  47. //获取到行数列数
  48. int i = path.length-1;
  49. int j = path[0].length-1;
  50. //从path的最后开始找
  51. while(i>0&&j>0) {
  52. if(path[i][j] == 1) {
  53. System.out.println("移入"+i+"到背包");
  54. j -= w[i];
  55. }
  56. i--;
  57. }
  58. }
  59. }

运行结果:
QQ截图20200906155643.jpg


四、kmp算法(解决两个字符串匹配)

应用场景-字符串匹配问题

QQ截图20200909145850.jpg

第一种解决方法(暴力匹配)

解决思路

QQ截图20200909145922.jpg

代码实现

  1. package kmp;
  2. public class ViolenceMatch {
  3. public static void main(String[] args) {
  4. String str1 = "硅硅谷 尚硅谷你尚硅 尚硅谷你尚硅谷你尚硅你好";
  5. String str2 = "尚硅谷你尚硅你";
  6. int index = violenceMatch(str1, str2);
  7. System.out.println("对应位置为:"+index);
  8. }
  9. //进行暴力匹配字符串
  10. public static int violenceMatch(String str1,String str2) {
  11. //将字符串转为char型数组
  12. char[] c1 = str1.toCharArray();
  13. char[] c2 = str2.toCharArray();
  14. //获取两个字符数组的长度
  15. int len1 = c1.length;
  16. int len2 = c2.length;
  17. //设置两个移标来指向两个字符数组 i指向c1 j指向c2
  18. int i = 0;
  19. int j = 0;
  20. //通过两个移标越界判断结束
  21. while(i<len1 && j<len2) {
  22. //判断两个移标指向位置是否相同
  23. if(c1[i] == c2[j]) {
  24. i++;
  25. j++;
  26. }else {
  27. //不相同的情况
  28. i = i-j+1;//这里从原本位置向后移一位
  29. j = 0;
  30. }
  31. }
  32. //如果while出来j对应下标为c2的长度那么就说明全部字段都匹配到了
  33. if(j == len2) {
  34. //从而获取c1中初始匹配到的位置
  35. return i-j;
  36. }else {
  37. //没有找到返回-1
  38. return -1;
  39. }
  40. }
  41. }

运行结果:
QQ截图20200909150024.jpg

第二种解决方法(kmp算法) 未懂


整理者:长路 时间:2020/9/4-2020/9/6