Java中令人惊艳的五大算法,你知道多少?

news2025/1/11 6:57:55

在这里插入图片描述

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。
🍎个人主页:Java Fans的博客
🍊个人信条:不迁怒,不贰过。小知识,大智慧。
💞当前专栏:前端案例分享专栏
✨特色专栏:国学周更-心性养成之路
🥭本文内容:Java中令人惊艳的五大算法,你知道多少?

文章目录

    • 1、快速排序算法
    • 2、哈希表算法
    • 3、动态规划算法
    • 4、KMP算法
    • 5、最小生成树算法

在这里插入图片描述

1、快速排序算法

  这是一种高效的排序算法,它的平均时间复杂度为O(nlogn)。它的基本思想是通过分治的方式将一个大问题分解成若干个小问题,然后递归地解决这些小问题。

具体来说,快速排序算法的实现过程如下:

  1. 选择一个基准元素,通常选择第一个元素或者最后一个元素。
  2. 将数组中小于基准元素的元素放在基准元素的左边,大于基准元素的元素放在基准元素的右边。
  3. 对左右两个子数组分别递归地进行快速排序。
  4. 合并左右两个子数组。

Java中实现快速排序算法的代码如下:

public static void quickSort(int[] arr, int left, int right) {
    if (left < right) {
        int pivot = partition(arr, left, right);
        quickSort(arr, left, pivot - 1);
        quickSort(arr, pivot + 1, right);
    }
}

public static int partition(int[] arr, int left, int right) {
    int pivot = arr[left];
    int i = left + 1;
    int j = right;
    while (i <= j) {
        while (i <= j && arr[i] < pivot) {
            i++;
        }
        while (i <= j && arr[j] > pivot) {
            j--;
        }
        if (i <= j) {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
            i++;
            j--;
        }
    }
    int temp = arr[left];
    arr[left] = arr[j];
    arr[j] = temp;
    return j;
}

  在这段代码中,partition方法用来将数组分成左右两个子数组,并返回基准元素的位置。quickSort方法则用来递归地进行快速排序。

2、哈希表算法

  哈希表是一种高效的数据结构,它可以在常数时间内完成插入、查找和删除操作。它的基本思想是将关键字映射到一个固定的位置,然后在该位置上存储相应的值。

具体来说,哈希表算法的实现过程如下:

  1. 定义一个哈希函数,将关键字映射到一个固定的位置。
  2. 在哈希表中查找或插入元素时,先通过哈希函数计算出关键字对应的位置。
  3. 如果该位置上已经有元素,则进行冲突处理,通常采用链表或开放地址法。
  4. 如果该位置上没有元素,则直接插入元素。

Java中实现哈希表算法的代码如下:

public class MyHashMap<K, V> {
    private static final int DEFAULT_CAPACITY = 16;
    private static final float DEFAULT_LOAD_FACTOR = 0.75f;

    private Entry<K, V>[] table;
    private int size;
    private int capacity;
    private float loadFactor;

    public MyHashMap() {
        this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR);
    }

    public MyHashMap(int capacity, float loadFactor) {
        this.capacity = capacity;
        this.loadFactor = loadFactor;
        this.table = new Entry[capacity];
    }

    public void put(K key, V value) {
        int index = hash(key);
        Entry<K, V> entry = table[index];
        while (entry != null) {
            if (entry.key.equals(key)) {
                entry.value = value;
                return;
            }
            entry = entry.next;
        }
        Entry<K, V> newEntry = new Entry<>(key, value);
        newEntry.next = table[index];
        table[index] = newEntry;
        size++;
        if (size > capacity * loadFactor) {
            resize();
        }
    }

    public V get(K key) {
        int index = hash(key);
        Entry<K, V> entry = table[index];
        while (entry != null) {
            if (entry.key.equals(key)) {
                return entry.value;
            }
            entry = entry.next;
        }
        return null;
    }

    private int hash(K key) {
        return key.hashCode() % capacity;
    }

    private void resize() {
        Entry<K, V>[] oldTable = table;
        capacity *= 2;
        table = new Entry[capacity];
        size = 0;
        for (Entry<K, V> entry : oldTable) {
            while (entry != null) {
                put(entry.key, entry.value);
                entry = entry.next;
            }
        }
    }

    private static class Entry<K, V> {
        K key;
        V value;
        Entry<K, V> next;

        public Entry(K key, V value) {
            this.key = key;
            this.value = value;
        }
    }
}

  在这段代码中,MyHashMap类实现了哈希表的基本操作,包括put、get、hash和resize方法。其中,put方法用来插入元素,get方法用来查找元素,hash方法用来计算哈希值,resize方法用来扩容哈希表。Entry类则用来表示哈希表中的一个键值对。

3、动态规划算法

  动态规划是一种高效的算法,它可以用来解决很多复杂的问题,如最长公共子序列、最短路径等。它的基本思想是将一个大问题分解成若干个小问题,然后递归地解决这些小问题,并将它们的解合并起来得到大问题的解。

具体来说,动态规划算法的实现过程如下:

  1. 定义状态:将原问题分解成若干个子问题,定义状态表示子问题的解。
  2. 定义状态转移方程:根据子问题之间的关系,定义状态转移方程,将子问题的解合并起来得到大问题的解。
  3. 初始化:将最简单的子问题的解初始化。
  4. 计算顺序:按照计算顺序递推计算出所有子问题的解。
  5. 求解原问题:根据子问题的解,计算出原问题的解。

Java中实现动态规划算法的代码如下:

public static int longestCommonSubsequence(String s1, String s2) {
    int m = s1.length();
    int n = s2.length();
    int[][] dp = new int[m + 1][n + 1];
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
                dp[i][j] = dp[i - 1][j - 1] + 1;
            } else {
                dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
            }
        }
    }
    return dp[m][n];
}

  在这段代码中,longestCommonSubsequence方法用来求解两个字符串的最长公共子序列。它使用了动态规划算法,定义了状态dp[i][j]表示s1的前i个字符和s2的前j个字符的最长公共子序列的长度。然后,根据子问题之间的关系,定义了状态转移方程,最后按照计算顺序递推计算出所有子问题的解,得到原问题的解。

4、KMP算法

  KMP算法是一种高效的字符串匹配算法,它的时间复杂度为O(n+m),其中n和m分别是文本串和模式串的长度。它的基本思想是利用已经匹配的信息来避免重复匹配。

具体来说,KMP算法的实现过程如下:

  1. 预处理模式串:计算出模式串的前缀函数,即next数组。
  2. 在文本串中匹配模式串:从文本串的第一个字符开始,依次比较文本串和模式串的每个字符,如果匹配成功,则继续比较下一个字符,否则根据next数组移动模式串的指针。
  3. 根据next数组移动模式串的指针:如果模式串的某个字符与文本串的某个字符不匹配,则根据next数组移动模式串的指针,使得模式串的前缀与文本串的后缀匹配。

Java中实现KMP算法的代码如下:

public static int kmp(String s, String p) {
    int n = s.length();
    int m = p.length();
    int[] next = getNext(p);
    int i = 0, j = 0;
    while (i < n && j < m) {
        if (j == -1 || s.charAt(i) == p.charAt(j)) {
            i++;
            j++;
        } else {
            j = next[j];
        }
    }
    if (j == m) {
        return i - j;
    } else {
        return -1;
    }
}

public static int[] getNext(String p) {
    int m = p.length();
    int[] next = new int[m];
    next[0] = -1;
    int i = 0, j = -1;
    while (i < m - 1) {
        if (j == -1 || p.charAt(i) == p.charAt(j)) {
            i++;
            j++;
            next[i] = j;
        } else {
            j = next[j];
        }
    }
    return next;
}

  在这段代码中,kmp方法用来在文本串s中匹配模式串p,getNext方法用来计算模式串的前缀函数next数组。在kmp方法中,i和j分别表示文本串和模式串的指针,如果匹配成功,则i和j都向后移动一位,否则根据next数组移动模式串的指针j。在getNext方法中,i和j分别表示前缀和后缀的指针,如果前缀和后缀匹配成功,则i和j都向后移动一位,否则根据next数组移动后缀的指针j。

5、最小生成树算法

  最小生成树算法是一种用来求解无向图的最小生成树的算法,它的时间复杂度为O(nlogn)。它的基本思想是通过贪心的方式选择边,使得生成树的权值最小。

具体来说,最小生成树算法的实现过程如下:

  1. 初始化:将所有边按照权值从小到大排序。
  2. 选择边:从权值最小的边开始,依次选择边,如果该边的两个端点不在同一个连通分量中,则将它们合并成一个连通分量,并将该边加入生成树中。
  3. 终止条件:当生成树中有n-1条边时,停止选择边。

Java中实现最小生成树算法的代码如下:

public static List<Edge> kruskal(int n, List<Edge> edges) {
    List<Edge> result = new ArrayList<>();
    UnionFind uf = new UnionFind(n);
    Collections.sort(edges);
    for (Edge edge : edges) {
        int u = edge.u;
        int v = edge.v;
        if (uf.find(u) != uf.find(v)) {
            uf.union(u, v);
            result.add(edge);
            if (result.size() == n - 1) {
                break;
            }
        }
    }
    return result;
}

public static class Edge implements Comparable<Edge> {
    int u;
    int v;
    int w;

    public Edge(int u, int v, int w) {
        this.u = u;
        this.v = v;
        this.w = w;
    }

    @Override
    public int compareTo(Edge o) {
        return Integer.compare(w, o.w);
    }
}

public static class UnionFind {
    int[] parent;
    int[] rank;

    public UnionFind(int n) {
        parent = new int[n];
        rank = new int[n];
        for (int i = 0; i < n; i++) {
            parent[i] = i;
            rank[i] = 1;
        }
    }

    public int find(int x) {
        if (parent[x] != x) {
            parent[x] = find(parent[x]);
        }
        return parent[x];
    }

    public void union(int x, int y) {
        int px = find(x);
        int py = find(y);
        if (px == py) {
            return;
        }
        if (rank[px] > rank[py]) {
            parent[py] = px;
        } else if (rank[px] < rank[py]) {
            parent[px] = py;
        } else {
            parent[py] = px;
            rank[px]++;
        }
    }
}

  在这段代码中,kruskal方法用来求解无向图的最小生成树,Edge类用来表示图中的一条边,UnionFind类用来实现并查集。在kruskal方法中,首先将所有边按照权值从小到大排序,然后依次选择边,如果该边的两个端点不在同一个连通分量中,则将它们合并成一个连通分量,并将该边加入生成树中。最后,当生成树中有n-1条边时,停止选择边。


  码文不易,本篇文章就介绍到这里,如果想要学习更多Java系列知识点击关注博主,博主带你零基础学习Java知识。与此同时,对于日常生活有困扰的朋友,欢迎阅读我的第四栏目:《国学周更—心性养成之路》,学习技术的同时,我们也注重了心性的养成。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/602339.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Golang - 选项模式 vs 构建器模式

在使用Golang创建复杂对象时&#xff0c;常用的两种模式是选项模式&#xff08;Options pattern&#xff09;和构建器模式&#xff08;Builder pattern&#xff09;。这两种模式各有优缺点&#xff0c;选择适合项目需求的模式取决于具体情况。 问题 假设我们想创建一个具有许…

【HTTP 协议】掌握 Web 的核心技术

哈喽&#xff0c;大家好~我是你们的老朋友&#xff1a;保护小周ღ 谈起 HTTP 协议&#xff08;超文本传输协议&#xff09;&#xff0c;不知道大家第一次是从什么地方了解到这个协议的呢&#xff1f;在真实的网络环境中网络协议的种类非常多&#xff0c;其中有一些耳熟能详的…

GBASE南大通用5月份公司动态一览

产品动态 5月初&#xff0c;GBASE南大通用两款新产品&#xff1a;GBase 8c V5.0和GBase 8s V8.8.5于鲲鹏开发者大会主论坛商业发行版联合发布仪式上正式发布。新版本与上一版本功能特性保持兼容&#xff0c;并在算子能力、用户级别审计、兼容性等方面全面增强&#xff0c;支持一…

最新版本 Stable Diffusion 开源 AI 绘画工具之微调模型篇

✨ 目录 &#x1f388; 模型种类&#x1f388; 变分自动编码器 / VAE&#x1f388; 美学梯度 / Aesthetic Gradients&#x1f388; 大型语言模型的低阶自适应 / LoRA&#x1f388; 超网络模型 / Hypernetwork&#x1f388; 微调模型 / LyCORIS &#x1f388; 模型种类 当你打开…

jacoco检测功能或自动化测试覆盖率

参考文档&#xff1a;http://t.csdn.cn/QqCSh http://t.csdn.cn/HonVL 目录 下载jacoco 启动jacocoagent监控被测项目 执行手工测试 生成exec文件 生成report报告 jacoco代码覆盖率报告分析 下载jacoco http://t.csdn.cn/HonVL 我下载的最新的 jacoco-0.8.10.zip 下…

虚拟化技术 — Cgroups 与 Namespaces 支撑实现的操作系统虚拟化

目录 文章目录 目录操作系统虚拟化&#xff08;容器技术&#xff09;的发展历程ChrootCgroupsCgroup SubsystemsCgroup FilesystemCgroup HierarchyCgroups 的操作规则Cgroups 的代码实现 NamespacesUTS namespacePID namespaceIPC namespaceMount namespaceNetwork namespaceU…

mysql order by 索引问题综合分析

一&#xff0c;文章1 Mysql-索引失效 order by优化_orderby索引失效_zyk1.的博客-CSDN博客 总结&#xff1a; 0&#xff0c;索引 与 查询条件 与 排序字段关系&#xff0c;Using filesort出现场景 1.联合索引&#xff0c;最左匹配原则&#xff0c;不仅查询条件需要遵循&…

vivado FIFO的Standard 和 FWFT模式

vivado FIFO的Standard 和 FWFT模式 Standard 模式读操作 对于标准 FIFO 读取操作&#xff0c;在断言读有效后&#xff0c;如果 FIFO 非空&#xff0c;存储在FIFO中的下一个数据被驱动到输出总线&#xff08;dout&#xff09;上和VALID标志有效。 下图显示标准模式下的读数据…

ChatGPT介绍与使用场景

ChatGPT是OpenAI开发的一款基于GPT-3和GPT-4的人工智能聊天机器人。“GPT"代表的是"Generative Pre-trained Transformer”&#xff0c;这是一种深度学习技术&#xff0c;使用人工神经网络来生成类似人类的文本。 ChatGPT能够处理各种对话任务&#xff0c;包括回答问…

教您如何快速自助搭建一个元宇宙场景

【导语】 在数字化时代&#xff0c;营销方式正经历着巨大的变革。而在这场变革的浪潮中&#xff0c;元宇宙编辑器凭借其独特的元宇宙展厅解决方案&#xff0c;为企业和个人提供了快速、简便的自助搭建元宇宙场景的机会。 今天&#xff0c;让我们一起走进元宇宙编辑器的世界&…

如何将Windows 7系统镜像部署到不同的硬件计算机?

案例&#xff1a;将Windows 7系统镜像恢复到另一台电脑 “我有一台运行 Windows 7 的电脑&#xff0c;我已经创建了一个系统镜像并希望将其加载到另一台电脑上。但是&#xff0c;当我运行恢复控制台时&#xff0c;我不断收到错误消息。这让我想知道是否可以创建 Windows 7 系…

前端面试技巧?第一手面试真题!

面试有哪些套路和技巧&#xff1f; 第一次去面试&#xff0c;该注意什么&#xff1f; 怎么说话能打动面试官&#xff0c;成功入职&#xff1f; 当你褪去青涩&#xff0c;将头发梳成大人模样走向面试之路时&#xff0c;你们的搜索记录和行为早已暴露了自己内心状态&#xff1a…

数据结构和算法的基本概念

数据结构概念 1.数据&#xff1a;所有能输入计算机且能被计算机处理的符号总称 2.数据元素&#xff1a;是数据的基本单位&#xff0c;表示数据集合中的一个个体。 3 .数据项&#xff1a;数据元素中有独立含义的最小单位。 数据结构&#xff1a;相互之间存在一定关系的数据元素的…

Layui时间选择设置只能选择整点半点,并隐藏秒钟部分

文章目录 1.整点半点选择2.隐藏秒选择部分3.默认值处理3.1 操作done函数3.2 操作ready函数 1.整点半点选择 处理思路&#xff1a;通过循环将使用不到的时间点去除掉&#xff0c;关键代码位于ready函数 //选择起止时间 layui.laydate.render({elem: .laydate-times,type: &quo…

第五章 Electron|Node 使用cheerio 爬虫

一、cheerio是什么可以做什么 &#x1f447; &#x1f447; &#x1f447; Cheerio是一个快速、灵活且精益的jQuery核心实现&#xff0c;用于在Node.js环境中解析HTML文档。它可以帮助您在服务器端轻松地从HTML文档中提取数据&#xff0c;比如从网页中提取文章标题、内容、图片…

【JVM】.class文件如何在JVM中运行的?

一、先认识JVM的组成 java虚拟机整体包括&#xff1a;类加载系统、运行时数据区、执行引擎、垃圾回收器。 &#xff08;1&#xff09;方法区&#xff1a;线程共享&#xff0c;存储Class信息、常量、静态变量等等&#xff1b; jdk1.6~1.7时称为永久代&#xff0c;存储常量、Cla…

js常见面试题整理

1&#xff1a;JavaScript 有哪些数据类型 答&#xff1a; JavaScript 的数据类型分为原始类型和对象类型。 原始类型有 7 种&#xff0c;分别是&#xff1a; BooleanNumberBigIntStringNullUndefinedSymbol 对象类型&#xff08;也称引用类型&#xff09;是一个泛称&#x…

vue3 中使用indexDb

1.indexDb.js const indexDB window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB; class IndexDBCache {// 构造函数constructor() {this._db null; //数据库this._transaction null; //事务this._request null;this._dbName "loginInfoDb"; …

API ‘variantOutput.getPackageLibrary()‘已过时的解决方法

一个发布到maven central的android库项目&#xff0c;为了方便管理&#xff0c;在build.gradle文件中加入了打包处理的一段脚本&#xff1a; //生成aarlibraryVariants.all { variant ->def name "library-${versionMajor}.${versionMinor}.${versionPatch}.aar"…

VUE 3.0 + NGINX + Hls.js + OBS -- 直播推拉流、流视频播放

&#x1f6f4;&#x1f6f4;前言&#xff1a; 该 Demo 基于 OBS推流 Nginx Vue 3.0 Nplayer.js hls.js &#xff0c;目的只是实现流媒体播放&#xff0c;以及简易推拉流直播。 文章目录 前端组件 NPlayer.js安装 nplayer.js 流视频播放页面元素初始化播放器清晰度控件样式…