【数据结构与算法】杨辉三角,相同字符的截取以及扑克牌

news2024/12/25 8:53:02

请添加图片描述

✨个人主页:bit me
✨当前专栏:数据结构
✨每日一语:不要等到了你的人生垂暮,才想起俯拾朝花,且行且珍惜。
在这里插入图片描述

ArrayList题训

  • 🌵 一. 杨辉三角
  • 🌴二.相同字符的截取
  • 🌲三.扑克牌

🌵 一. 杨辉三角

给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。
在「杨辉三角」中,每个数是它左上方和右上方的数的和。
请添加图片描述
示例 1:

输入: numRows = 5
输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]

示例 2:

输入: numRows = 1
输出: [[1]]

思路:我们可以把杨辉三角更加抽象化为我们所用
在这里插入图片描述
在这里我们可以看出来它就是类似于一个二维数组,我们从上面的动态图当中也可以知道它所组成的规律

在杨辉三角中,除了每一行第一个和最后一个元素都是固定为元素1之外,其余的元素都是由上一行的同列元素和上一行同列元素的前一个元素之和组成的

所以在这里我们可以试着用i和j来分别表示行和列,用二维数组来表示就是[i][j] = [i-1][j] + [i-1][j-1]

  1. 先定义一个二维数组ret
List<List<Integer>> ret = new ArrayList<>();//二维数组
  1. 第0行的元素不参与规律计算,我们直接给第0行赋值为1
List<Integer> one = new ArrayList<>();
one.add(1);
ret.add(one);
  1. 定义行数为i,遍历行数
for (int i = 1; i < numRows; i++) {
	...
}

①:数组的每一行第一个元素都是固定的为1,把遍历到的数组都定义为curRow,然后赋值第一个元素1

List<Integer> curRow = new ArrayList<>();
curRow.add(1);

②定义这一行的每个元素为j,根据我们上述规律[i][j] = [i-1][j] + [i-1][j-1]来遍历数组实现打印

for (int j = 1; j < i; j++) {
    //curRow[i][j] = [i-1][j] + [i-1][j-1];
    List<Integer> preRow = ret.get(i-1);
    int x = preRow.get(j) + preRow.get(j-1);
    curRow.add(x);
}

③每一行的最后一个元素也是固定不变的,也是元素1,所以我们直接在最后添加一个元素就ok了

curRow.add(1);
ret.add(curRow);

附上总的代码:

public List<List<Integer>> generate(int numRows) {
    List<List<Integer>> ret = new ArrayList<>();//二维数组
    List<Integer> one = new ArrayList<>();
    one.add(1);
    ret.add(one);

    //i代表每一行
    for (int i = 1; i < numRows; i++) {
        List<Integer> curRow = new ArrayList<>();
        //这一行开始的1
        curRow.add(1);
        //j代表这一行的每个元素
        for (int j = 1; j < i; j++) {
            //curRow[i][j] = [i-1][j] + [i-1][j-1];
            List<Integer> preRow = ret.get(i-1);
            int x = preRow.get(j) + preRow.get(j-1);
            curRow.add(x);
        }
        //j == i 这一行最后的一个1
        curRow.add(1);
        ret.add(curRow);
    }
    return ret;
}

 

🌴二.相同字符的截取

给定两串字符串s1,s2
要求:去掉第一串字符串当中所有的第二串字符串当中的字符

示例:
输入字符串:

String s1 = “welcome to my world”;
String s2 = “come”;

输出:

wl t y wrld

在思考这一题的代码实现中,我们先从边角开始考虑

  1. 先考虑特殊情况,两串字符串中有任何一个字符串为空的时候,或者长度为空,我们就需要把它置为空
if(s1 == null || s2 == null){
    return null;
}
if(s1.length() == 0 || s2.length() == 0){
    return null;
}
  1. 创建链表
List<Character> ret = new ArrayList<>();
  1. 对第一串字符串进行遍历,然后记录下每个元素下角标,用第二串数组中的元素进行比较,去掉出现相同的字符串,最后返回未出现相同字符的元素
for (int i = 0; i < s1.length(); i++) {
    char ch = s1.charAt(i);
    if(!s2.contains(ch+"")){
        ret.add(ch);
    }
}

此处简单介绍两种方法:

①charAt()方法是用来检索特定索引下的字符的String实例的方法,返回指定索引位置的char值,索引范围为0~length()-1
②contains()方法是当且仅当此字符串包含指定的char值序列时,返回true。

最后在我们主函数里就可以进行相应的操作了:

public static void main(String[] args) {
    String s1 = "welcome to my world";
    String s2 = "come";
    List<Character> ret = func(s1,s2);
    for (char ch:ret) {
        System.out.print(ch);
    }
    System.out.println();
}

如上执行的结果:
在这里插入图片描述

附上总代码:

public static List<Character> func(String s1,String s2){
    if(s1 == null || s2 == null){
        return null;
    }
    if(s1.length() == 0 || s2.length() == 0){
        return null;
    }
    List<Character> ret = new ArrayList<>();
    for (int i = 0; i < s1.length(); i++) {
        char ch = s1.charAt(i);
        if(!s2.contains(ch+"")){
            ret.add(ch);
        }
    }
    return ret;
}

public static void main(String[] args) {
    String s1 = "welcome to my world";
    String s2 = "come";
    List<Character> ret = func(s1,s2);
    for (char ch:ret) {
        System.out.print(ch);
    }
    System.out.println();
}

 

🌲三.扑克牌

要求我们自己写一副扑克牌

①:完成刚买牌的顺序打印出来
②:我们再完成洗牌随机打乱顺序
③:三个人轮流每个人揭5张牌
④:还要输出最后剩余的牌

  1. 我们需要先创建一副牌,用来我们一系列的操作,单独创建一个Card类,定义花色和数字,写带两个参数的构造方法,以及getter和setter方法,重写ToString方法
class Card {
    private String suit;
    private int rank;

    public Card(String suit, int rank) {
        this.suit = suit;
        this.rank = rank;
    }

    public String getSuit() {
        return suit;
    }

    public void setSuit(String suit) {
        this.suit = suit;
    }

    public int getRank() {
        return rank;
    }

    public void setRank(int rank) {
        this.rank = rank;
    }

    @Override
    public String toString() {
        return "[ " + suit+" "+rank+" ]";
    }
}

  1. 写一个刚买的牌,按照花色和顺序打印出来,J,Q,K我们按照数字11,12,13来打印,再把花色和序号融合在一起组成每个牌每个花色
public static final String[] suits = {"♥","♠","♣","♦"};

public static List<Card> buyCard() {
    List<Card> desk = new ArrayList<>();
    for (int i = 0; i < 4; i++) {
        for (int j = 1; j <= 13 ; j++) {
            String suit = suits[i];
            Card card = new Card(suit,j);
            desk.add(card);
        }
    }
    return desk;
}

最后运行出来的一副新牌就是按照花色的数字从小到大依次打印

  1. 洗牌后随机打乱的函数,那我们如何很好的打乱呢?交换每个元素的下标,让它遍历的时候随机和其他元素下标交换,达到我们的目的,在此处我们还可以优化一下,让下标随机数取元素长度里的任何一个下标,所以反向遍历更好
public static void shuffle(List<Card> cardList) {
    for (int i = cardList.size()-1; i > 0 ; i--) {
        Random random = new Random();
        int index = random.nextInt(i);
        swap(cardList,i,index);
    }
}

在这里我们提及之前学过的元素交换:

int tmp = array[i];
array[i] = array[j];
array[j] = tmp;

所以这里的swap函数就仿照这个来写

private static void swap(List<Card> cardList,int i,int j) {
    Card tmp = cardList.get(i);
    cardList.set(i,cardList.get(j));
    cardList.set(j,tmp);
}
  1. 五个人每个人都轮流揭五张牌,最后揭的牌还需要删除,方便后面我们打印剩余的牌
for (int i = 0; i < 5; i++) {
    for (int j = 0; j < 3; j++) {
        //每次揭牌都去获取 cardList的0下标的数据【删除】
        Card card = cardList.remove(0);
        List<Card> hand = hands.get(j);
        hand.add(i,card);//这里使用add 不能是set
        /*hands.get(j).add(card);*/
    }
}
  1. 当我们此时打印cardList就是剩余的牌了,然后把所有的代码执行结果打印出来(此处主函数省略了,在后面总代码中有,结果截图只有部分结果)
    在这里插入图片描述

附上总代码:

class Card {
    private String suit;
    private int rank;

    public Card(String suit, int rank) {
        this.suit = suit;
        this.rank = rank;
    }

    public String getSuit() {
        return suit;
    }

    public void setSuit(String suit) {
        this.suit = suit;
    }

    public int getRank() {
        return rank;
    }

    public void setRank(int rank) {
        this.rank = rank;
    }

    @Override
    public String toString() {
        return "[ " + suit+" "+rank+" ]";
    }
}

public class TestCard {
    public static final String[] suits = {"♥","♠","♣","♦"};
    
    public static List<Card> buyCard() {
        List<Card> desk = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            for (int j = 1; j <= 13 ; j++) {
                String suit = suits[i];
                Card card = new Card(suit,j);
                desk.add(card);
            }
        }
        return desk;
    }

    public static void shuffle(List<Card> cardList) {
        for (int i = cardList.size()-1; i > 0 ; i--) {
            Random random = new Random();
            int index = random.nextInt(i);
            swap(cardList,i,index);
        }
    }

    private static void swap(List<Card> cardList,int i,int j) {
        /*
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
         */
        Card tmp = cardList.get(i);

        cardList.set(i,cardList.get(j));

        cardList.set(j,tmp);
    }
    
    public static void main(String[] args) {
        List<Card> cardList = buyCard();
        System.out.println("买牌:"+cardList);
        shuffle(cardList);
        System.out.println("洗牌:"+cardList);

        List<Card> hand1 = new ArrayList<>();
        List<Card> hand2 = new ArrayList<>();
        List<Card> hand3 = new ArrayList<>();

        List<List<Card>> hands = new ArrayList<>();
        hands.add(hand1);
        hands.add(hand2);
        hands.add(hand3);

        // 5个人  轮流揭牌5张 i=0就是第一次
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 3; j++) {
                //每次揭牌都去获取 cardList的0下标的数据【删除】
                Card card = cardList.remove(0);
                List<Card> hand = hands.get(j);
                hand.add(i,card);//这里使用add 不能是set
                /*hands.get(j).add(card);*/
            }
        }

        System.out.println("第1个人的牌:"+hand1);
        System.out.println("第2个人的牌:"+hand2);
        System.out.println("第3个人的牌:"+hand3);

        System.out.println("剩余的牌:"+cardList);
    }
}

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

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

相关文章

【SpringCloud】02 搭建springcloud微服务项目,服务治理组件nacos,负载均衡ribbon,远程调用Openfeign

文章目录搭建springcloud微服务项目1. 微服务父工程2. 创建子模块-shop-common3. 创建子模块--shop-product4. 创建子模块--shop-order服务治理组件1. 如何使用nacos2. 微服务客户端连接到nacos注册中心3. 消费端如何通过nacos调用提供者负载均衡1. 自己控制负载均衡2. ribbon完…

Nginx配置SSL证书

目录 获得证书 步骤一&#xff1a;购买证书 步骤二&#xff1a;申请证书 ​编辑 下载证书及证书转换&#xff1a;​编辑 配置SSL证书 在Nginx目录下新建certificate目录&#xff0c;并将下载好的证书/私钥等文件上传至该目录&#xff08;与配置文件同级目录&#xff09;。…

LiDAR点云转换到大地坐标系——简单粗标定

目录一、LiDAR和IMU位姿标定1.1安装角度标定1.2安装位置标定1.3部分代码二、点云转换到当地水平坐标系2.1基本理论2.1.1坐标系2.1.1.1激光雷达2.1.1.2导航坐标系/当地水平坐标系/大地坐标系2.1.2惯性传感器原理2.2点云转换试验2.2.1试验场地2.2.2试验内容2.2.3点云变换效果Wind…

C语言日记 37 类的友元(1)(全局函数做友元)

根据36 类和对象-友元-全局函数做友元_哔哩哔哩_bilibili复现出如下代码&#xff1a; 一、&#xff08;只是&#xff09;访问&#xff08;公开&#xff09;内部成员&#xff1a; #include <iostream> using namespace std; class Building { private:int ws;//卧室 pub…

NewStarCTF 公开赛-web

week1 HTTP cookie 修改admin 源码发现key GET和POST传参即可 Head?Header! User-Agent: CTF Referer: ctf.com X-Forwarded-For: 127.0.0.1我真的会谢 信息泄露 robots.txt www.zip 源码 /.index.php.swp NotPHP 函数绕过 if(file_get_contents($_GET[data]) &qu…

数据备份一般有哪些方式,如何进行数据备份

在如今这个时代&#xff0c;数据于我们而言是特别重要的&#xff0c;一旦发生丢失&#xff0c;可能会带来严重后果&#xff0c;如果你也很苦恼如何保证这些重要数据的安全&#xff0c;小编建议一定要对重要数据进行备份&#xff0c;以防发生丢失的意外。数据备份一般有哪些方式…

设计一个缓存策略,动态缓存热点数据

&#x1f468;‍&#x1f4bb;个人主页&#xff1a; 才疏学浅的木子 &#x1f647;‍♂️ 本人也在学习阶段如若发现问题&#xff0c;请告知非常感谢 &#x1f647;‍♂️ &#x1f4d2; 本文来自专栏&#xff1a; 常见场景解决方案 &#x1f308; 每日一语&#xff1a;努力不一…

C语言 0 —— 信息在计算机中的表示

计算机的电路 由 逻辑门电路组成。一个逻辑门电路可以看成为一个开关&#xff0c;每个开关的状态是“开” 则 高电位 对应 1 或者 “关” 则 低电位 对应 0 &#xff0c; 那么1和0 刚刚好用二进制数来表示&#xff1a; 每个位只能取1和0 &#xff0c;称为 one 个 bit &#…

谈一谈关于Linux内核编译详解原理

前言&#xff1a;为什么要做这个启动盘&#xff0c;因为内核编译是很危险的&#xff0c;中间出了错系统则直接崩溃&#xff0c;然后就无法开机了&#xff0c;你将看到一个_在你的左上角闪烁。知道启动盘可以帮你从外置设备启动系统&#xff0c;能启动系统才能恢复系统。1.编译前…

Java 线程和反射---尚硅谷Java视频学习

1.Java程序在运行得时候默认就会产生一个进程2.这个进程会有一个主线程3.代码都在主线程中执行 线程的生命周期 线程的执行方式 public class Java02_Thread {public static void main(String[] args) throws Exception {// TODO 线程 - 执行方式&#xff08;串行&#xff0c…

ASP.NET Core 3.1系列(14)——分布式缓存Redis的使用

1、前言 前一篇博客介绍了ASP.NET Core中本地缓存MemoryCache的使用方法。相较于本地缓存&#xff0c;分布式缓存更加适合大多数项目应用场景&#xff0c;下面就来介绍一下如何在ASP.NET Core中对Redis缓存进行相关操作。 2、分布式缓存接口——IDistributedCache 对于分布式…

pytorch深度学习实战24

第二十四课 VGG网络 VGG是Oxford的Visual Geometry Group的组提出的&#xff08;大家应该能看出VGG名字的由来了&#xff09;。该网络是在ILSVRC 2014上的相关工作&#xff0c;主要工作是证明了增加网络的深度能够在一定程度上影响网络最终的性能。VGG有两种结构&#xff0c;分…

远程重启电脑

一、设置电脑允许自动启动 在远程计算机上编辑设置远程注册表 步骤1. 按“WindowsR”键调用运行对话框。输入“services.msc”并点击“确定”。 步骤2. 在“服务”窗口中&#xff0c;双击“RemoteRegistry”以检查其状态。 步骤3. 将启动类型更改为“自动”。 二、查找远程计…

SPARKSQL3.0-各阶段自定义扩展规则源码剖析

一、前言 这一节主要介绍如何自定义扩展各阶段规则 虽然spark内部提供了很多优化规则&#xff0c;但在实际工作中&#xff0c;经常因为业务需求需要自定义扩展优化器或解析器&#xff0c;故自己实现一个优化器才对sparksql有更深的理解 二、扩展范围 spark在扩展方便做的很…

vue.js毕业设计,基于vue.js前后端分离教室预约小程序系统设计与实现

功能介绍 【后台管理功能模块】 系统设置&#xff1a;设置关于我们、联系我们、加入我们、法律声明 广告管理&#xff1a;设置小程序首页轮播图广告和链接 留言列表&#xff1a;所有用户留言信息列表&#xff0c;支持删除 会员列表&#xff1a;查看所有注册会员信息&#xff0…

从零开始学前端:DOM、BOM、焦点事件 --- 今天你学习了吗?(JS:Day20)

从零开始学前端&#xff1a;程序猿小白也可以完全掌握&#xff01;—今天你学习了吗&#xff1f;&#xff08;JS&#xff09; 复习&#xff1a;从零开始学前端&#xff1a;CSSOM视图模式 — 今天你学习了吗&#xff1f;&#xff08;JS&#xff1a;Day19&#xff09; 文章目录从…

java8 (jdk 1.8) 新特性——Stream ApI

在java8 中&#xff0c;有两个最重要的改变&#xff0c;一个就是之前了解的Lmbda java8 (jdk 1.8) 新特性——Lambda ,还有一个就是Stream Api 1. 什么是Stream API 简单来说就是一个类库&#xff0c;里边有一些方法方便我们对集合数据进行操作&#xff0c;就好像使用 SQL 语…

Windows cmd 命令及Linux 环境下导入导入mysql 数据库

文章目录一、背景二、Windows cmd 导入导出mysql 数据库1.导出数据库三种方式&#xff08;导出数据库时不需要连接数据库&#xff09;2. 操作步骤2.导入数据库三、linux 环境下导入导出数据库一、背景 最近在本机上安装了一个WMware 虚拟机&#xff0c;需要从本机&#xff08;…

从三层架构说起,谈谈对历史项目的小改造

项目背景说明 最近接手一个 “老” 项目的需求修改&#xff0c;项目整体基于 .net core 3.1 平台&#xff0c;以传统的三层架构为基础构建。了解需求后&#xff0c;逐步对原有项目框架进行大概的了解&#xff0c;主要是熟悉一些框架的开发规范&#xff0c;基本工具类库的使用&…

寒亭5.8万亩盐碱稻 国稻种芯·中国水稻节:山东潍坊插秧期

寒亭5.8万亩盐碱稻 国稻种芯中国水稻节&#xff1a;山东潍坊插秧期 新京报讯&#xff08;记者赵利新&#xff09;新闻中国采编网 中国新闻采编网 谋定研究中国智库网 中国农民丰收节国际贸易促进会 国稻种芯中国水稻节 中国三农智库网-功能性农业农业大健康大会报道&#xff…