Android学习总结之算法篇七(图和矩阵)

有向图的深度优先搜索(DFS)和广度优先搜索(BFS)的示例,以此来模拟遍历 GC Root 引用链这种有向图结构:

一、深度优先搜索(DFS)

import java.util.*;public class GraphDFS {private final int V; // 顶点数量private final LinkedList<Integer>[] adj; // 邻接表// 构造函数GraphDFS(int v) {V = v;adj = new LinkedList[v];for (int i = 0; i < v; ++i)adj[i] = new LinkedList<>();}// 添加边void addEdge(int v, int w) {adj[v].add(w);}// 深度优先搜索辅助函数void DFSUtil(int v, boolean[] visited) {// 标记当前节点为已访问并打印visited[v] = true;System.out.print(v + " ");// 递归访问所有邻接节点Iterator<Integer> i = adj[v].listIterator();while (i.hasNext()) {int n = i.next();if (!visited[n])DFSUtil(n, visited);}}// 深度优先搜索void DFS(int v) {// 标记所有节点为未访问boolean[] visited = new boolean[V];DFSUtil(v, visited);}public static void main(String[] args) {GraphDFS g = new GraphDFS(4);g.addEdge(0, 1);g.addEdge(0, 2);g.addEdge(1, 2);g.addEdge(2, 0);g.addEdge(2, 3);g.addEdge(3, 3);System.out.println("从顶点 2 开始的深度优先搜索结果:");g.DFS(2);}
}

二、广度优先搜索(BFS)

import java.util.*;public class GraphBFS {private final int V; // 顶点数量private final LinkedList<Integer>[] adj; // 邻接表// 构造函数GraphBFS(int v) {V = v;adj = new LinkedList[v];for (int i = 0; i < v; ++i)adj[i] = new LinkedList<>();}// 添加边void addEdge(int v, int w) {adj[v].add(w);}// 广度优先搜索void BFS(int s) {// 标记所有节点为未访问boolean[] visited = new boolean[V];// 创建一个队列用于 BFSLinkedList<Integer> queue = new LinkedList<>();// 标记当前节点为已访问并加入队列visited[s] = true;queue.add(s);while (queue.size() != 0) {// 出队并打印s = queue.poll();System.out.print(s + " ");// 获取所有邻接节点Iterator<Integer> i = adj[s].listIterator();while (i.hasNext()) {int n = i.next();if (!visited[n]) {visited[n] = true;queue.add(n);}}}}public static void main(String[] args) {GraphBFS g = new GraphBFS(4);g.addEdge(0, 1);g.addEdge(0, 2);g.addEdge(1, 2);g.addEdge(2, 0);g.addEdge(2, 3);g.addEdge(3, 3);System.out.println("从顶点 2 开始的广度优先搜索结果:");g.BFS(2);}
}

代码解释

  • 深度优先搜索(DFS):通过递归的方式,尽可能深地访问图中的节点。在访问一个节点后,标记其为已访问,然后递归地访问其未被访问的邻接节点。
  • 广度优先搜索(BFS):使用队列来实现,从起始节点开始,将其标记为已访问并加入队列。然后不断从队列中取出节点,访问其未被访问的邻接节点,并将这些邻接节点加入队列。

三、蛇形打印矩阵 

import java.util.ArrayList;
import java.util.List;public class ZigzagMatrixPrinter {/*** 以蛇形顺序打印矩阵元素* @param matrix 输入的二维矩阵* @return 包含蛇形顺序元素的列表*/public static List<Integer> zigzagOrder(int[][] matrix) {// 用于存储最终蛇形打印结果的列表List<Integer> result = new ArrayList<>();// 检查输入的矩阵是否为空或无效// 如果矩阵为空,或者矩阵没有行,或者矩阵的第一行没有元素,直接返回空列表if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {return result;}// 获取矩阵的行数int rows = matrix.length;// 获取矩阵的列数int cols = matrix[0].length;// 遍历矩阵的每一行for (int i = 0; i < rows; i++) {// 判断当前行是否为偶数行(行索引从 0 开始,所以索引为偶数的行是偶数行)if (i % 2 == 0) {// 偶数行从左到右打印// 遍历当前行的每一列for (int j = 0; j < cols; j++) {// 将当前元素添加到结果列表中result.add(matrix[i][j]);}} else {// 奇数行从右到左打印// 从当前行的最后一列开始,逆序遍历到第一列for (int j = cols - 1; j >= 0; j--) {// 将当前元素添加到结果列表中result.add(matrix[i][j]);}}}// 返回存储蛇形打印结果的列表return result;}public static void main(String[] args) {// 定义一个示例矩阵int[][] matrix = {{1, 2, 3},{4, 5, 6},{7, 8, 9}};// 调用 zigzagOrder 方法进行蛇形打印,并将结果存储在 result 列表中List<Integer> result = zigzagOrder(matrix);// 打印蛇形打印的结果System.out.println(result);}
}

四、顺时针打印矩阵(螺旋打印) 

import java.util.ArrayList;
import java.util.List;public class SpiralPrintMatrix {public static void main(String[] args) {// 定义一个二维数组表示矩阵int[][] matrix = {{1, 2, 3},{4, 5, 6},{7, 8, 9}};// 调用螺旋打印矩阵的方法,得到打印结果列表List<Integer> result = spiralOrder(matrix);// 遍历结果列表,打印每个元素for (int num : result) {System.out.print(num + " ");}}/*** 以螺旋顺序(顺时针)遍历矩阵的方法* @param matrix 要遍历的矩阵* @return 包含螺旋遍历结果的列表*/public static List<Integer> spiralOrder(int[][] matrix) {// 用于存储螺旋遍历结果的列表List<Integer> result = new ArrayList<>();// 检查矩阵是否为空或无效,如果是则直接返回空列表if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {return result;}// 获取矩阵的行数int rows = matrix.length;// 获取矩阵的列数int cols = matrix[0].length;// 初始化左边界为 0int left = 0;// 初始化右边界为列数减 1int right = cols - 1;// 初始化上边界为 0int top = 0;// 初始化下边界为行数减 1int bottom = rows - 1;// 当左边界小于等于右边界且上边界小于等于下边界时,继续循环while (left <= right && top <= bottom) {// 从左到右打印上边界的元素for (int j = left; j <= right; j++) {result.add(matrix[top][j]);}// 上边界向下移动一行top++;// 从上到下打印右边界的元素for (int i = top; i <= bottom; i++) {result.add(matrix[i][right]);}// 右边界向左移动一列right--;// 检查上边界是否仍然小于等于下边界if (top <= bottom) {// 从右到左打印下边界的元素for (int j = right; j >= left; j--) {result.add(matrix[bottom][j]);}// 下边界向上移动一行bottom--;}// 检查左边界是否仍然小于等于右边界if (left <= right) {// 从下到上打印左边界的元素for (int i = bottom; i >= top; i--) {result.add(matrix[i][left]);}// 左边界向右移动一列left++;}}// 返回包含螺旋遍历结果的列表return result;}
}    

五、矩阵置零

/*** 将矩阵中值为 0 的元素所在的行和列的所有元素都置为 0* * @param matrix 输入的二维矩阵*/
public void setZeroes(int[][] matrix) {// 获取矩阵的行数int m = matrix.length;// 获取矩阵的列数int n = matrix[0].length;// 标记第一行是否原本就存在 0boolean firstRowHasZero = false;// 标记第一列是否原本就存在 0boolean firstColHasZero = false;// 检查第一行是否有 0for (int j = 0; j < n; j++) {if (matrix[0][j] == 0) {// 如果第一行存在 0,将标记置为 truefirstRowHasZero = true;// 一旦发现 0,无需继续检查该行其他元素,跳出循环break;}}// 检查第一列是否有 0for (int i = 0; i < m; i++) {if (matrix[i][0] == 0) {// 如果第一列存在 0,将标记置为 truefirstColHasZero = true;// 一旦发现 0,无需继续检查该列其他元素,跳出循环break;}}// 标记需要置为 0 的行和列// 从第二行第二列开始遍历矩阵(避开第一行和第一列,因为它们用于标记)for (int i = 1; i < m; i++) {for (int j = 1; j < n; j++) {if (matrix[i][j] == 0) {// 如果当前元素为 0,将该元素所在行的第一个元素置为 0,标记该行需要置 0matrix[i][0] = 0;// 如果当前元素为 0,将该元素所在列的第一个元素置为 0,标记该列需要置 0matrix[0][j] = 0;}}}// 根据标记置 0// 再次从第二行第二列开始遍历矩阵for (int i = 1; i < m; i++) {for (int j = 1; j < n; j++) {if (matrix[i][0] == 0 || matrix[0][j] == 0) {// 如果当前元素所在行的第一个元素为 0 或者所在列的第一个元素为 0,将该元素置为 0matrix[i][j] = 0;}}}// 处理第一行if (firstRowHasZero) {// 如果第一行原本就有 0,将第一行所有元素置为 0for (int j = 0; j < n; j++) {matrix[0][j] = 0;}}// 处理第一列if (firstColHasZero) {// 如果第一列原本就有 0,将第一列所有元素置为 0for (int i = 0; i < m; i++) {matrix[i][0] = 0;}}
}

六、拿两堆宝石,保证会赢

问题分析

这是一个典型的博弈论问题,目标是通过策略确保先手必胜。关键在于通过第一步操作使两堆宝石数量相等,之后采取对称策略(对方从某堆拿 k 个,自己从另一堆拿 k 个),最终自己拿完最后一个宝石。

必胜策略

  1. 初始状态:两堆宝石数量为 12 和 13,差值为 1
  2. 第一步操作:从数量为 13 的堆中拿走 1 个,使两堆均为 12 个,形成对称状态。
  3. 后续策略:对方从某一堆拿 k 个(1≤k≤3),自己从另一堆拿 k 个,始终保持两堆数量相等,最终自己拿完最后一个宝石。

Java 代码实现

public class StoneGameStrategy {public static void main(String[] args) {int pile1 = 12;int pile2 = 13;// 先手第一步操作:使两堆数量相等int firstMove = Math.abs(pile1 - pile2);if (pile1 < pile2) {pile2 -= firstMove;} else {pile1 -= firstMove;}System.out.println("第一步从数量为 " + (pile1 + firstMove) + " 的堆中拿 " + firstMove + " 个");System.out.println("剩余两堆数量:" + pile1 + " 和 " + pile2);System.out.println("之后对方拿k个,自己从另一堆拿k个,确保最终获胜");}
}

代码解释

  1. 计算初始差值:通过 Math.abs(pile1 - pile2) 计算两堆宝石数量的差值,初始差值为 1
  2. 调整数量:从数量多的堆中拿走差值个宝石(本例中从 13 个的堆拿 1 个),使两堆数量相等(均为 12 个)。
  3. 对称策略:后续对方每次从某一堆拿 k 个,自己从另一堆拿 k 个,始终保持两堆数量相等,最终自己拿完最后一个宝石,确保胜利。

结论

先手第一步从数量为 13 的堆中拿走 1 个宝石,之后采取对称策略,即可保证必胜。

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

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

相关文章

熟悉Linux下的编程

可能 目录 熟悉Linux下Python编程的含义及与非Linux环境编程的区别 一、核心含义解析 二、与非Linux环境的关键区别 三、典型应用场景对比 四、能力培养建议 openfoem的下载之路&#xff1a; 方法一&#xff1a;使用cd命令 方法二&#xff1a;使用快捷方式 方法三&am…

c++引入nacos,详细步骤

以下是将Nacos引入C项目的详细步骤&#xff0c;包括安装、配置和代码实现&#xff1a; 1. 安装Nacos服务器 下载Nacos服务器安装包&#xff0c;可以从Nacos官网获取最新版本。 解压安装包并启动Nacos服务器&#xff1a; cd nacos/bin sh startup.sh -m standalone 这将启动…

性能优化实践

4.1 大规模量子态处理的性能优化 背景与问题分析 量子计算中的大规模量子态处理(如量子模拟、量子态可视化)需要高效计算和实时渲染能力。传统图形API(如WebGL)在处理高维度量子态时可能面临性能瓶颈,甚至崩溃(如表格中14量子比特时WebGL的崩溃)。而现代API(如WebGPU…

课堂总结。

第三章第六节 Spark-SQL核心编程&#xff08;五&#xff09;自定义函数&#xff1a;UDF&#xff1a;val sparkConf new SparkConf().setMaster("local[*]").setAppName("SQLDemo")//创建SparkSession对象val spark :SparkSession SparkSession.builder()…

分库分表-除了hash分片还有别的吗?

在分库分表的设计中,除了常见的 Hash 分片,还有多种策略根据业务场景灵活选择。以下是几种主流的分库分表策略及其应用场景、技术实现和优缺点分析,结合项目经验(如标易行投标服务平台的高并发场景)进行说明: 一、常见分库分表策略 1. 范围分片(Range Sharding) 原理:…

AUTOSAR图解==>AUTOSAR_SWS_GPTDriver

AUTOSAR GPT驱动 (通用定时器驱动) 分析 AUTOSAR标准软件规范解析 目录 1. GPT驱动概述 1.1 GPT驱动在AUTOSAR架构中的位置1.2 GPT驱动主要功能 2. GPT驱动模块结构3. GPT驱动初始化流程4. GPT驱动状态机5. GPT驱动错误处理6. GPT预定义定时器7. 总结 1. GPT驱动概述 GPT驱动…

MyBatis持久层框架

MyBatis持久层框架 目录 一、Mybatis简介 1. 简介 2. 持久层框架对比 3. 快速入门&#xff08;基于Mybatis3方式&#xff09; 二、日志框架扩展 1. 用日志打印替代sout 2. Java日志体系演变 3. 最佳拍档用法 4. Lombok插件的使用 4.1 Lombok简介 4.2 Lombok安装 4.3 …

域控制器升级的先决条件验证失败,证书服务器已安装

出现“证书服务器已安装”导致域控制器升级失败时&#xff0c;核心解决方法是卸载已安装的证书服务‌。具体操作如下&#xff1a;‌ ‌卸载证书服务‌ 以管理员身份打开PowerShell&#xff0c;执行命令&#xff1a; Remove-WindowsFeature -Name AD-Certificate该命令会移除A…

VMware虚拟机常用Linux命令进阶指南(一)

摘要&#xff1a;本文涵盖多方面 Linux 命令的使用。包括用户与用户组管理&#xff0c;创建用户和组并设置权限&#xff1b;目录结构操作&#xff0c;涉及创建和更改目录结构&#xff1b;Vim 编辑器及文件归档&#xff0c;有文件创建、编译、合并、打包等任务。 更多优质文章 …

【AI News | 20250415】每日AI进展

AI News 1、字节跳动发布Seaweed-7B视频模型&#xff1a;70亿参数实现音视频同步生成与多镜头叙事 字节跳动推出新一代视频生成模型Seaweed-7B&#xff0c;该模型仅70亿参数却实现多项突破&#xff1a;支持音视频同步生成、多镜头叙事&#xff08;保持角色连贯性&#xff09;、…

如何实现动态请求地址(baseURL)

需求: 在项目中遇到了需要实时更换请求地址,后续使用修改后的请求地址(IP) 例如:原ip请求为http://192.168.1.1:80/xxx,现在需要你点击或其他操作将其修改为http://192.168.1.2:80/xxx,该如何操作 tips: 修改后需要跳转( 修改了IP之前的不可使用,需要访问修改后的地址来操作 …

Open AI 使用篇

一.function Calling 大模型中的 function calling 指的是在人工智能模型&#xff08;如 GPT-4&#xff09;中调用外部函数或API&#xff0c;以便模型能够执行更复杂的任务或获取外部数据。这种方式允许模型在生成回答时不仅仅依赖于内部的训练数据&#xff0c;还能够与外部系…

6.DJI-PSDK:psdk订阅无人机高度/速度/GPS/RTK/时间/经纬度等消息及问题解决

DJI-PSDK:psdk订阅无人机高度/速度/GPS/RTK/时间/经纬度等消息 消息订阅可以获取绝大多数无人机的动态信息,包括无人机的姿态、速度、加速度、角速度、高度、GPS 位置、云 台的角度和状态、飞行模式和飞行状态、电机和电池等各类关键信息。 这些信息并不会“一股脑儿地”全部…

100 个网络安全基础知识

1. 什么是网络安全&#xff1f; 网络安全是指采取必要措施&#xff0c;防范对网络的攻击、侵入、干扰、破坏和非法使用以及意外事故&#xff0c;使网络处于稳定可靠运行的状态&#xff0c;保障网络数据的完整性、保密性、可用性。&#xff08;参考《中华人民共和国网络安全法》…

第七届IEEE通信、信息系统与计算机工程国际会议(CISCE 2025)

重要信息 官网&#xff1a;www.iccisce.com 时间&#xff1a;2025年5月9-11日 地点&#xff1a;中国-广州 征稿主题 通信技术 信息系统 •5G/6G通信系统与网络 •无线通信与移动网络 •光纤通信与光网络 •卫星与空间通信 •通信信号处理与编码 •无线传感器网络 •物联网…

OpenCV 图像拼接

一、图像拼接的介绍 图像拼接是一种将多幅具有部分重叠内容的图像合并成一幅完整、无缝且具有更广阔视野或更高分辨率图像的技术。其目的是通过整合多个局部图像来获取更全面、更具信息价值的图像内容。 二、图像拼接的原理 图像拼接的核心目标是将多幅有重叠区域的图像进行准…

第十一章 网络编程

在TCP/IP协议中&#xff0c;“IP地址TCP或UDP端口号”唯一标识网络通讯中的一个进程。 因此可以用Socket来描述网络连接的一对一关系。 常用的Socket类型有两种&#xff1a;流式Socket&#xff08;SOCK_STREAM&#xff09;和数据报式Socket&#xff08;SOCK_DGRAM&#xff09…

ffmpeg实现视频流抽帧

ffmpeg 实现视频流抽帧 抽取实时视频帧 如果你的实时视频是通过 RTSP、UDP 或其他协议获取的&#xff0c;可以直接调用 FFmpeg 命令来抽取帧。 ffmpeg 命令 示例 1 ffmpeg -i rtsp://your_rtsp_stream_url -vf fps1 -update 1 output.jpg说明&#xff1a; -i rtsp://your…

【GIT】放弃”本地更改,恢复到远程仓库的状态git fetch origin git reset --hard origin/分支名

如果你想完全放弃本地更改&#xff0c;恢复到远程仓库的状态&#xff0c;可以按照以下步骤操作&#xff1a; 获取远程最新版本 首先执行&#xff1a; git fetch origin这条命令会把远程仓库的最新提交拉取到你的本地&#xff0c;但不会自动合并到你的当前分支。 硬重置你的当前…

flutter doctor 信号号超时

报错如下&#xff1a; :\Users\Administrator>flutter doctor Doctor summary (to see all details, run flutter doctor -v): [√] Flutter (Channel stable, 3.27.4, on Microsoft Windows [版本 10.0.22631.5189], locale zh-CN) [√] Windows Version (Installed versi…