ArrayList集合的两个实例应用,有趣的洗牌算法与杨辉三角

本节课的内容,就让我们来学习一下ArrayList集合的应用,ArrayList的本质就是一个顺序表,那下面一起来学习吧
目录
一、杨辉三角
1.题目详情及链接
2.剖析题目
3.思路及代码
二、洗牌算法
1.创造牌对象
2.创造一副牌
3.洗牌操作
4.发牌操作
一、杨辉三角
这不是普通的杨辉三角,这是力扣里面的杨辉三角
1.题目详情及链接
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

有同学说,这里的题目也看不出跟ArrayList集合有鸡毛关系呀?我说,你别急,继续往下看

看到这里,你急了没有,题目给的类型是什么狗屎?这不就与ArrayList扯上关系了嘛,这到底是什么意思呢?接着往下看
2.剖析题目
(1)题目的要求是根据参数,生成杨辉三角的前numRows行,并返回存放杨辉三角的空间
比如:numRows=3,就生成杨辉三角的前面3行;如果你用普通的二维数组存储,那就返回该二维数组的地址。
(2)剖析返回值
我们也应该可以猜到,List<List<Integer>>也是表示二维数组的意思

此时还不算完整的二维数组,List只是一个接口,需要实例化对象

(3)我们需要将这些数字放入该二维数组中
3.思路及代码
(1)思路解析
通过面向对象的思想来完成
第一步:分析杨辉三角的规律
题目要求生成杨辉三角的前numRows行,也就是可以一行一行生成

规律是显而易见的,除了第一行,其他每行的第一个元素和最后一个元素的值都是1;从第3行开始,中间的值与前一行的值紧密相连

第二步:创建二维数组并单独完成杨辉三角的第一行
不用担心测试用例一行都没有,1<=numRows<=30
List<List<Integer>> list = new ArrayList<>();
List<Integer> first = new ArrayList<>();
//先设置第一行的元素
first.add(1);
list.add(first);
核心思想:先单独建立一个一维的顺序表,存放好一行的元素,然后再将这个一维的顺序表当成一个元素放入二维的顺序表中,后面也是一样的思想
第三步:存放第二行及后面的元素
for (int i = 1; i < numRows; i++) {//每层循环代表一行List<Integer> ret = new ArrayList<>();//定义一个一维数组
}
我们将在这个循环里面存放完成后续的行,如果只有一行,就不会进入这个循环内
第四步:分析如何将每一行存入
由前面分析知道,第二行开始,第一个和最后一个元素都是1,我们可以在前面和最后面存入1
for (int i = 1; i < numRows; i++) {//每层循环代表一行List<Integer> ret = new ArrayList<>();//定义一个一维数组//1.添加第一个元素ret.add(1);//2.设置中间元素,从第二列开始//3.添加最后元素ret.add(1);list.add(ret);//将每一行放入二维数组中}
然后中间的元素如何添加?第二行是没有中间元素的,而且中间的元素都是与前一行的元素有着紧密的关系,所以我们也需要考虑好。首先,我们需要从第二个位置开始存放;然后,第几行就说明那一行有多少个元素,就与行号绑定了关系
for (int i = 1; i < numRows; i++) {//每层循环代表一行List<Integer> ret = new ArrayList<>();//定义一个一维数组//1.添加第一个元素ret.add(1);//2.设置中间元素,从第二列开始for (int j = 1; j < i; j++) {//利用面向对象的思想,拿到元素int tmp = list.get(i-1).get(j)+list.get(i-1).get(j-1);ret.add(tmp);}//3.添加最后元素ret.add(1);list.add(ret);}
(2)完整代码
public List<List<Integer>> generate(int numRows) {List<List<Integer>> list = new ArrayList<>();List<Integer> first = new ArrayList<>();//先设置第一行的元素first.add(1);list.add(first);//从第二行开始for (int i = 1; i < numRows; i++) {//每层循环代表一行List<Integer> ret = new ArrayList<>();//定义一个一维数组//1.添加第一个元素ret.add(1);//2.设置中间元素,从第二列开始for (int j = 1; j < i; j++) {int tmp = list.get(i-1).get(j)+list.get(i-1).get(j-1);ret.add(tmp);}//3.添加最后元素ret.add(1);list.add(ret);}return list;
}
(3)总结一下思路
第一:将杨辉三角分成两个部分存储(第一行和第一行后面的)
第二:存储第一行后面的时候,又分成三部分存储(第一个元素、中间部分元素、最后一个元素)
第三:存储中间部分元素时,通过与前一行的元素的关系进行存储(利用面向对象的思想获得前一行的元素)
二、洗牌算法
其实,洗牌算法就是ArrayList的一种应用,或者运用,没有那么的高大尚,下面简单介绍洗牌算法的一些基本功能和流程
下面是程序运行起来的结果:

什么是洗牌算法?
(1)使用类和对象的知识定义一个牌对象
(2)创造出一副排序好的牌,存储在ArrayList中(有牌)
(3)然后将这些牌的顺序打乱(洗牌)
(4)将洗乱的牌随机分发给三个人(发牌)
下面开始讲解洗牌算法
1.创造牌对象
牌这个对象的属性有两个:第一是花色,第二就是号码;然后我们提供一下构造方法,在创建每一张牌的时候就赋值;最后,重写一下toString方法,用来打印牌。
public class Card {//用来定义一张牌public String suit;//牌的花色public int num;//号码public Card(String suit, int num) {this.suit = suit;this.num = num;}@Overridepublic String toString() {return suit+num;}
}
2.创造一副牌
main函数,用来实例化对象,和调用对象中的方法(创造牌的方法)
public static void main(String[] args) {PlayCard game = new PlayCard();System.out.println("设置牌:");List<Card> cards = game.setCard();System.out.println(cards);}
创建一个类,用来表示玩牌的游戏,里面存放创建牌、洗牌和发牌的操作
public class PlayCard {public static final String[] suits = {"♠","♥","♣","♦"};//定义花色的数组//1.设置牌操作public List<Card> setCard() {List<Card> cards = new ArrayList<>();//定义一个数组,用来存放所有牌for (int i = 0; i < 4; i++) {//每次循环代表一个花色for (int j = 1; j <=13 ; j++) {//13个号码String suit = suits[i];//获得一个花色Card card = new Card(suit,j);//定义一个牌对象并赋值cards.add(card);//将牌放入一个牌数组中}}return cards;//返回一副牌}
}
(1)这是一个带返回值的函数。
(2)第一层循环,代表花色;第二层循环代码号码;每循环一次:拿到一个花色和号码,然后将这两个赋值给牌对象,并将牌放入ArrayList集合中(cards)
(3)最后将这个集合返回(接收返回值就拿到了返回值)
3.洗牌操作
这里先把上一阶段创造牌的操作隐藏,独将洗牌操作
这里洗牌的思想是:(1)从后面遍历这副牌,每张牌都随机与前面某一张牌交换
(2)获得前面随机牌使用产生随机数种子
(3)交换则单独包装成一个方法
public class PlayCard {//在这里类里面操作牌:设置牌,洗牌和发牌public static final String[] suits = {"♠","♥","♣","♦"};//定义花色的数组//1.设置牌操作//这里介绍洗牌操作,所以设置牌的操作就省略了//2.洗牌操作public void shuffle(List<Card> cards) {Random random = new Random();for (int i = 51; i > 0; i--) {int index = random.nextInt(i);//随机获取一个牌下标与i下标的牌交换swap(cards,i,index);}//return cards;}private static void swap(List<Card> cards,int i,int j) {//交换两张牌Card tmp = cards.get(i);cards.set(i,cards.get(j));cards.set(j,tmp);}}
4.发牌操作
同样的,我们把前面创造牌和洗牌的操作隐藏起来,单独介绍发牌操作
我们发牌的思路是:(1)有三个人轮流接牌,每次接一张,一共接五轮(2)每个人随机接牌,每拿到一张牌,就从这副牌中删除(3)每个人拿到五张牌,每个人看作一个一维数组;要保存三个人的牌,就需要一个二维数组。
public class PlayCard {//在这里类里面操作牌:设置牌,洗牌和发牌public static final String[] suits = {"♠","♥","♣","♦"};//定义花色的数组//1.设置牌操作//2.洗牌操作//3.发牌操作public List<List<Card>> getCard(List<Card> cards) {//定义三个对象,存取牌List<Card> hand1 =new ArrayList<>();List<Card> hand2 =new ArrayList<>();List<Card> hand3 =new ArrayList<>();//定义一个二维数组,存取三个对象List<List<Card>> hand = new ArrayList<>();hand.add(hand1);hand.add(hand2);hand.add(hand3);//每个人只能拿五张牌for (int i = 0; i < 5; i++) {for (int j = 0; j < 3; j++) {Card card = cards.remove(0);//每次拿到第一张牌,并从数组中删掉//放入每个人手中hand.get(j).add(card);}}return hand;}
}
(1)用三个一维的集合代表三个一维数组 (2)再定义一个集合,存放三个一维集合 (3)第一层循环,每循环一次就是一张牌;第二层循环就是每个人轮流拿牌 (4) hand.get(j)代表第几个人,add(card)代表把这张牌给某个人
完整代码:
public static void main(String[] args) {PlayCard game = new PlayCard();System.out.println("设置牌:");List<Card> cards = game.setCard();System.out.println(cards);System.out.println("洗牌后:");game.shuffle(cards);System.out.println(cards);System.out.println("发牌:");List<List<Card>> hand = game.getCard(cards);for (int i = 0; i < 3 ; i++) {System.out.println("第"+(i+1)+"个人的牌为:"+hand.get(i));}System.out.println("剩余的牌为:");System.out.println(cards);}
public class Card {//用来定义一张牌public String suit;//牌的花色public int num;//号码public Card(String suit, int num) {this.suit = suit;this.num = num;}@Overridepublic String toString() {return suit+num;}
}
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;public class PlayCard {//在这里类里面操作牌:设置牌,洗牌和发牌public static final String[] suits = {"♠","♥","♣","♦"};//定义花色的数组//1.设置牌操作public List<Card> setCard() {List<Card> cards = new ArrayList<>();//定义一个数组,用来存放所有牌for (int i = 0; i < 4; i++) {//四种花色for (int j = 1; j <=13 ; j++) {//13个号码String suit = suits[i];//获得一个花色Card card = new Card(suit,j);//定义一个牌对象并赋值cards.add(card);//将牌放入一个牌数组中}}return cards;//返回一副牌}//2.洗牌操作public void shuffle(List<Card> cards) {Random random = new Random();for (int i = 51; i > 0; i--) {int index = random.nextInt(i);//随机获取一个牌下标与i下标的牌交换swap(cards,i,index);}//return cards;}private static void swap(List<Card> cards,int i,int j) {//交换两张牌Card tmp = cards.get(i);cards.set(i,cards.get(j));cards.set(j,tmp);}//3.发牌操作public List<List<Card>> getCard(List<Card> cards) {//定义三个对象,存取牌List<Card> hand1 =new ArrayList<>();List<Card> hand2 =new ArrayList<>();List<Card> hand3 =new ArrayList<>();//定义一个二维数组,存取三个对象List<List<Card>> hand = new ArrayList<>();hand.add(hand1);hand.add(hand2);hand.add(hand3);//每个人只能拿五张牌for (int i = 0; i < 5; i++) {for (int j = 0; j < 3; j++) {Card card = cards.remove(0);//每次拿到第一张牌,并从数组中删掉//放入每个人手中hand.get(j).add(card);}}return hand;}
}
本节的内容就是介绍ArrayList集合的用法,可以当成一维数组,也可以当成二维数组。看到这里本机就结束了,快趁着这个感觉去刷题吧!
相关文章:
ArrayList集合的两个实例应用,有趣的洗牌算法与杨辉三角
本节课的内容,就让我们来学习一下ArrayList集合的应用,ArrayList的本质就是一个顺序表,那下面一起来学习吧 目录 一、杨辉三角 1.题目详情及链接 2.剖析题目 3.思路及代码 二、洗牌算法 1.创造牌对象 2.创造一副牌 3.洗牌操作 4.发…...
Qt 剪贴板操作
Qt剪贴板操作 剪贴板的操作经常和前面所说的拖放技术在一起使用,因此我们现在先来说说剪贴板的相关操作。大家对剪贴板都很熟悉。我们可以简单的把它理解成一个数据的存储池,可以把外面的数据放置进去,也可以把里面的数据取出来。剪贴板是由操作系统维护的,所以这提供了跨…...
python 学习笔记20 批量修改页眉页脚
需求:修改指定目录下所有文件的页眉页脚,或者往里面添加内容。 1. 这里做了word的实现和excel的实现,如下: 需要先安装 pip3 install pywin32,另外页眉页脚格式设置可以参考: word: 浅谈Wor…...
IIS + Axios 跨域设置
1、服务器端设置IIS (web.config) 即可,不需要对django settings.py做配置(python manage.py runserver 才需要settings.py配置跨域,IIS在iis上配) 网站根目录的web.config中加上这段: <httpProtocol&…...
详细说说vuex
Vuex 是什么 Vuex有几个属性及作用注意事项vuex 使用举例Vuex3和Vuex4有哪些区别 创建 Store 的方式在组件中使用 Store辅助函数的用法响应式的改进Vuex4 支持多例模式 Vuex 是什么 Vuex是一个专门为Vue.js应用设计的状态管理构架,它统一管理和维护各个Vue组件的可…...
Qt之Ui样式表不影响子类的配置
Qt之Ui样式表不影响子类的配置 问题 在ui界面上布局时,当对容器进行样试设计时,会对容器内其它成员对象也进行了修改 分析 对应*.ui文件内容 从这个写法来看,它的样式属性会影响其成员对象样式属性。 解决方法 在容器的样式表中写时适…...
Java集合--Map
1、Map集合概述 在Java的集合框架中,Map为双列集合,在Map中的元素是成对以<K,V>键值对的形式存在的,通过键可以找对所对应的值。Map接口有许多的实现类,各自都具有不同的性能和用途。常用的Map接口实现类有HashMap、Hashtab…...
C语言—每日选择题—Day48
第一题 1. 已知宏定义: #define M y*y3*y , 则表达式 s3*M4*My*M 预处理阶段后的结果是 A:s3*(y*y3*y)4*(y*y3*y)y*(y*y3*y) B:s3*(y*y)3*y4*(y*y)3*yy*(y*y)3*y C:s3*y*y3*y4*y*y3*yy*y*y3*y D:s3*(y*y)(3…...
华为OD试题七(IPv4地址转换成整数、比赛的冠亚季军)
1. IPv4地址转换成整数 示例代码: #测试数据 s1 "100#101#1#5"def fun(s):s_list s.split("#")# 转化成十六进制数 左边补零s_16_list [hex(int(_))[2:].zfill(2) for _ in s_list]s_16_str .join(s_16_list)return int(s_16_str,16) r f…...
SVN优缺点详解及版本控制系统选型建议
Subversion (SVN)是目前可用的众多版本控制选项之一。本篇文章将全面概述什么是 SVN、SVN的历史、SVN存储库是什么,以及在切换到SVN之前您应该谨慎考虑的潜在问题。 什么是Subversion(SVN)? Subversion软件,也称为SV…...
自己动手写数据库: select 查询语句对应查询树的构造和执行
首先我们需要给原来代码打个补丁,在SelectScan 结构体初始化时需要传入 UpdateScan 接口对象,但很多时候我们需要传入的是 Scan 对象,因此我们需要做一个转换,也就是当初始化 SelectScan 时,如果传入的是 Scan 对象&am…...
扬声器(喇叭)
扬声器(喇叭) 电子元器件百科 文章目录 扬声器(喇叭)前言一、扬声器(喇叭)是什么二、扬声器(喇叭)的类别三、扬声器(喇叭)的应用场景四、扬声器(喇叭)的作用原理总结前言 扬声器广泛应用于音响系统、公共广播系统、汽车音响、电视、电脑和移动设备等各种电子设备…...
汇总大厂-校招/社招 Java面试题--持续补充更新中-大家别光收藏,要看起来,巩固基础,就是干呀!
** 接上篇-汇总大厂-校招/社招 Java面试题(补充) ** markdown文件。持续更新中(阿里、腾讯、网易、美团、京东、华为、快手、字节…) 上面这篇也结合着看啊,通宵给整理出来的。 如需下载整套资料。关注公众号后台。…...
六. 函数
基本使用 ts与js一样拥有具名函数和匿名函数两种函数类型。但是ts的函数需要提前定义好参数类型以及函数的返回值类型。 具名函数 function add(num1: number, num2: number):number {return num1 num2 }匿名函数 匿名函数的定义相对麻烦,我们需要提前定义函数的…...
SpringBoot的Starter自动化配置,自己编写配置maven依赖且使用及短信发送案例
目录 一、Starter机制 1. 是什么 2. 有什么用 3. 应用场景 二、短信发送案例 1. 创建 2. 配置 3. 编写 4. 形成依赖 6. 其他项目的使用 每篇一获 一、Starter机制 1. 是什么 SpringBoot中的starter是一种非常重要的机制(自动化配置),能够抛弃以前繁杂…...
<蓝桥杯软件赛>零基础备赛20周--第9周--前缀和与差分
报名明年4月蓝桥杯软件赛的同学们,如果你是大一零基础,目前懵懂中,不知该怎么办,可以看看本博客系列:备赛20周合集 20周的完整安排请点击:20周计划 每周发1个博客,共20周(读者可以按…...
LeetCode-2487. 从链表中移除节点【栈 递归 链表 单调栈】
LeetCode-2487. 从链表中移除节点【栈 递归 链表 单调栈】 题目描述:解题思路一:可以将链表转为数组,然后从后往前遍历,遇到大于等于当前元素的就入栈,最终栈里面的元素即是最终的答案。解题思路二:递归&am…...
Redisson分布式锁原理分析
1.Redisson实现分布式锁 在分布式系统中,涉及到多个实例对同一资源加锁的情况,传统的synchronized、ReentrantLock等单进程加锁的API就不再适用,此时就需要使用分布式锁来保证多服务之间加锁的安全性。 常见的分布式锁的实现方式有ÿ…...
【Linux】:线程(二)互斥
互斥与同步 一.线程的局部存储二.线程的分离三.互斥1.一些概念2.上锁3.锁的原理4.死锁 一.线程的局部存储 例子 可以看到全局变量是所有线程共享的,如果我们想要每个线程都单独访问g_val怎么办呢?其实我们可以在它前面加上__thread修饰。 这就相当于把g…...
vscode报错Pylance client: couldn‘t create connection to server.
问题描述: 一打开vscode,右下角就弹报错,Pylance client: couldn’t create connection to server.,让我打开output,打开后似乎是在说连不上server 因为连不上server,所以我的python代码没法解析࿰…...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
