jjzjj

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

bit me 2024-05-24 原文

✨个人主页: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);
    }
}

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

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  3. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  4. ruby-on-rails - unicode 字符串的长度 - 2

    在我的Rails(2.3,Ruby1.8.7)应用程序中,我需要将字符串截断到一定长度。该字符串是unicode,在控制台中运行测试时,例如'א'.length,我意识到返回了双倍长度。我想要一个与编码无关的长度,以便对unicode字符串或latin1编码字符串进行相同的截断。我已经了解了Ruby的大部分unicode资料,但仍然有些一头雾水。应该如何解决这个问题? 最佳答案 Rails有一个返回多字节字符的mb_chars方法。试试unicode_string.mb_chars.slice(0,50)

  5. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  6. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  7. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  8. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  9. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  10. ruby - 如何使用文字标量样式在 YAML 中转储字符串? - 2

    我有一大串格式化数据(例如JSON),我想使用Psychinruby​​同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解

随机推荐