《趣学算法-分治法》阅读笔记

简介: 《趣学算法-分治法》阅读笔记

14天阅读挑战赛

在这里插入图片描述

1.概念

分而治之是一种很古老但很实用的策略,简单的说就是将一个较大的力量打碎分成小的力量,这样每个小的力量都能够被轻易击破。在现实应用中,分而治之往往是阻止小力量联合起来的策略。在战国时期,秦国就使用了“连横”的策略来破坏“合纵”,本质上就是对“分而治之”这种策略的应用。

1.1 三个步骤

  • 分解:将原问题分解成若干个子问题。
  • 解决:递归求解各自子问题,如果子问题足够小,直接求解。
  • 合并:合并这些子问题的解,即可得到原问题的结果。

总结就是,分治法就是把一个难以解决的大问题,分解为若干的小问题,每个击破得出结果,然后把这些子问题的解合并,就是大问题的解。递归是彰显分治法优势的利器

2.分治法的实际使用场景

2.1 二分查找

问题场景举例:猜数字游戏,一个人在自己手心上写上一个1~10的数字,然后让另外一个人猜,她只能回答大了还是小了,另外一个人采用什么办法,可以尽快猜中?

二分查找算法的实现思想是:
它充分利用了元素间的次序关系,采用分治策略,可在最坏的情况下用O(log n)完成搜索任务。它的基本思想是:(这里假设数组元素呈升序排列)将n个元素分成个数大致相同的两半,取a[n/2]与欲查找的x作比较,如果x=a[n/2]则找到x,算法终止;如 果x<a[n/2],则我们只要在数组a的左半部继续搜索x;如果x>a[n/2],则我们只要在数组a的右 半部继续搜索x。

动画演示:
在这里插入图片描述

java代码实现

class Main {
    public static void main(String[] args) {
        int[] w = new int[] { 2, 6, 7, 4, 10, 3 };
        int index = binarySearch(w, 6);
        System.out.println("位置为:" + index);
    }

    /**
     * 二分查找
     * 
     * @Title: binarySearch
     * @Description:
     * @author: itbird
     * @date 2022年10月20日 下午5:06:52
     * @param w
     * @param i
     *            void 时间复杂度: O(logN) 空间复杂度: O(1)
     */
    private static int binarySearch(int[] w, int i) {
        if (w == null || w.length == 0) {
            return -1;
        }

        int low = 0, high = w.length - 1;
        while (low <= high) {
            int mid = (low + high) / 2;
            if (w[mid] == i) {
                return mid;
            } else if (w[mid] < i) {
                low = mid + 1;
            } else {
                high = mid - 1;
            }
        }
        return -1;
    }

}

2.2 归并排序

问题描述:对于数组排序。
归并排序的原理:归并排序是一种分治的思想,将大问题拆解成为小问题,将一个大的数组先拆分成几个小的数组,然后再一点点的合并。
归并排序的步骤:

  • 将无序的数组,分为两个规模相等的数组
  • 继续分组,这里明显要采用递归的做法,直到分成的数组大小为1,那么一个数字,我们知道不用排序了
  • 这时是将无序的数组,分为了若干的单数字的数组,接下来最重要的步骤,就是合并了
  • 如何将两个数组合并为一个有序数组?相信各位想到的办法肯定很多,这里介绍一种最简单的,就是逐个遍历这两个数组中的元素,对比过程中,逐渐然后加入新的数组中。

动画:
在这里插入图片描述

Java代码实现:

import java.util.Arrays;

class Main {
    public static void main(String[] args) {
        int[] w = new int[] { 2, 6, 7, 4, 10, 3 };
        mergeSort(w, 0, w.length - 1);
        System.out.println(Arrays.toString(w));
    }

    /**
     * 归并排序
     * 
     * @Title: mergeSort
     * @Description:
     * @author: itbird
     * @date 2022年10月20日 下午8:08:23
     * @param w
     *            void 时间复杂度: O(nlogn) 空间复杂度: O(N)
     * @param j
     * @param i
     */
    private static void mergeSort(int[] w, int i, int j) {
        if (i < j) {
            int mid = (i + j) / 2;
            mergeSort(w, i, mid);
            mergeSort(w, mid + 1, j);
            merge(w, i, mid, j);
        }

    }

    /**
     * 将两个数组合并
     * 
     * @Title: merge
     * @Description:
     * @author: itbird
     * @date 2022年10月20日 下午8:10:25
     * @param w
     * @param i
     * @param mid
     * @param j
     *            void 时间复杂度: O(N) 空间复杂度: O(N)
     */
    private static void merge(int[] w, int left, int mid, int right) {
        int[] res = new int[right - left + 1];
        int i = left;
        int j = mid + 1;
        int k = 0;
        while (i <= mid && j <= right) {
            if (w[i] < w[j]) {
                res[k++] = w[i++];
            } else {
                res[k++] = w[j++];
            }
        }
        while (i <= mid) {
            res[k++] = w[i++];
        }
        while (j <= right) {
            res[k++] = w[j++];
        }
        System.arraycopy(res, 0, w, left, res.length);
    }
}

2.3 快速排序

问题描述:对于数组排序。
快速排序的原理:快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。
快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。
快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。
快速排序的步骤:

  • 从数组中找到一个基准值
  • 以基准值对数组进行双指针遍历,一个指针从前往后,一个从后往前,左边找到比基准值大的,右边找到比基准值小的,然后交换他们,然后指针继续移动,直到指针相遇,指针相遇之后,将基准值赋值为当前指针位置
  • 以当前指针位置为中心,分为两个数组,进行上述步骤,直到所有遍历完成

动画:
在这里插入图片描述

Java代码实现:

import java.util.Arrays;

class Main {
    public static void main(String[] args) {
        int[] w = new int[] { 2, 6, 7, 4, 10, 3 };
        quickSort(w, 0, w.length - 1);
        System.out.println(Arrays.toString(w));
    }

    /**
     * 快速排序
     * 
     * @Title: quickSort
     * @Description:
     * @author: itbird
     * @date 2022年10月21日 下午2:25:02
     * @param w
     * @param l
     * @param r
     *            void 时间复杂度: O(nlogn) 空间复杂度: O(logn)
     */
    private static void quickSort(int[] w, int l, int r) {
        if (l > r) {
            return;
        }
        int i = l, j = r;
        int k = w[l];
        while (i < j) {
            while (i < j && w[j] > k) {
                j--;
            }
            if (i < j) {
                w[i++] = w[j];
            }
            while (i < j && w[i] < k) {
                i++;
            }
            if (i < j) {
                w[j--] = w[i];
            }
        }
        w[i] = k;
        quickSort(w, i + 1, r);
        quickSort(w, l, i - 1);
    }
}

2.4 归并排序与快速排序的区别

相同点:

  • 利用分治思想
  • 具体实现都用递归

不同点:

  • 先分解再合并:归并排序先递归分解到最小粒度,然后从小粒度开始合并排序,自下而上的合并排序;
  • 边分解边排序:快速排序每次分解都实现整体上有序,即参照值左侧的数都小于参照值,右侧的大于参照值;是自上而下的排序;
  • 归并排序不是原地排序,因为两个有序数组的合并一定需要额外的空间协助才能合并;
  • 快速排序是原地排序,原地排序指的是空间复杂度为O(1);
  • 归并排序每次将数组一分为二,快排每次将数组一分为三
目录
相关文章
|
2月前
|
自然语言处理 算法 安全
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-16
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-16
20 0
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-16
|
2月前
|
机器学习/深度学习 自然语言处理 算法
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-12(上)
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-12(上)
35 0
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-12(上)
|
2月前
|
算法 API 计算机视觉
人脸识别笔记(一):通过yuface调包(参数量54K更快更小更准的算法) 来实现人脸识别
本文介绍了YuNet系列人脸检测算法的优化和使用,包括YuNet-s和YuNet-n,以及通过yuface库和onnx在不同场景下实现人脸检测的方法。
61 1
|
2月前
|
JSON 算法 数据可视化
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
这篇文章是关于如何通过算法接口返回的目标检测结果来计算性能指标的笔记。它涵盖了任务描述、指标分析(包括TP、FP、FN、TN、精准率和召回率),接口处理,数据集处理,以及如何使用实用工具进行文件操作和数据可视化。文章还提供了一些Python代码示例,用于处理图像文件、转换数据格式以及计算目标检测的性能指标。
69 0
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
|
2月前
|
机器学习/深度学习 安全 算法
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-23(下)
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-23(下)
40 0
|
2月前
|
安全 搜索推荐 算法
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-23(上)
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-23(上)
34 0
|
2月前
|
自然语言处理 搜索推荐 算法
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-21(下)
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-21(下)
33 0
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-21(上)
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-21(上)
26 0
|
2月前
|
机器学习/深度学习 人工智能 算法
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-20(下)
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-20(下)
23 0
|
2月前
|
机器学习/深度学习 存储 人工智能
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-20(上)
计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-20(上)
25 0