一、杨辉三角
给定一个非负数numRows,生成杨辉三角的前 numRows 行。
在杨辉三角中,每个数是它左上方和右上方的数之和。
示例:输入:numRows = 5
输出: [ [1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1] ]
思路 :使用二维数组的思路,使用列表的思路创建二维数组,定义行和列。

我们说过要用List列表的思路去创建二维数组:

示例:可以往这个列表中添加元素,只不过这个元素是一个个实例化的对象(传递的参数是一个泛型类,那么它也需要明确传递的参数类型,因此需要实例化对象),证明是一个二维数组:

输出结果:

那么,具体如何向这个二维数组存放具体的元素呢?
------ 前面说过,传递的参数是一个泛型类,因此需要实例化对象,但是不可以这样:

那么我们可以单独将列表每个实例化的元素写出来,往这一个个元素中,使用add方法添加元素,然后再将这些实例化的对象的引用传递给列表:
输出结果:

我们也可以通过调试观察:

前面的准备知识学习完后,我们正式开始写杨辉三角:
使用 [i][j] = [i-1][j-1] + [i-1][j-1] 的思路。

写一个方法 generate ,它的返回值是List<LIst<Integer>>,在方法中,我们首先处理第一行,因为杨辉三角的第一行只有一个元素,那就是1 ,因此,我们先处理第一行,将这一行的元素先添加到列表中;然后从第二行开始,进行求每一个元素 (使用前面的公式),由于杨辉三角的每一行的第一个元素和最后一个元素都是1 ,于是也可以直接添加,从每一行的第二个元素开始求 ,也就是中间的这些位置:根据公式,需要先求该行的前一行的元素信息,然后利用这些信息进行该行的元素求解;最后返回列表。
java
public class Test {
public static List<List<Integer>> generate(int numRows) {
List<List<Integer>> ret = new ArrayLIst<>();
//处理第一行
List<Integer> list0 = new ArrayList<>();
list0.add(1);
ret.add(list0);
//从第2行开始 进行求元素
for(int i = 1;i < numRows; i++) {
//处理第一个元素
List<Integer> curRow = new ArrayList<>();
curRow.add(1);
//中间
//从第二个元素开始求元素
List<Integer> preRow = ret.get(i-1);//前一行
for(int j = 1;j < i; j++) {
//[i][j] = [i-1][j-1] + [i-1][j-1]
int val1 = preRow.get(j);
int val2 = preRow.get(j-1);
ret.add(val1 + val2);
}
//尾巴
curRow.add(1);
ret.add(curRow);
}
return ret;
}
public static void main(String[] args) {
List<List<Integer>> list = new ArrayList<>();
List<List<Integer>> ret = generate(4);
for(int i = 0;i < ret.size(); i++) {
for(int j = 0;j < ret.get(i).size(); j++) {
System.out.print(ret.get(i).get(j) + " ");
}
System.out.println();
}
}
}
输出结果:
二、洗牌算法
要完成洗牌,有三个步骤:
- 1.买扑克牌 52张牌
- 2.洗牌
- 3.设有3个人,每个人轮流揭5张牌
1.Card类------描述一副牌的组成
首先我们写一个类Card,用来描述买来的一副牌的组成:
java
public class Card {
private String suit;//花色
private int rank;//牌面值
//构造方法
public Card(String suit,int rank) {
this.suit = suit;
this.rank = rank;
}
//重写toSTring
public void toString() {
return "{" + suit + rank + "}";
}
}
2.CardDemo类------完成买牌、洗牌等操作
然后再写一个类CardDemo,在这个类中,完成买牌、洗牌等一些列事情;一副牌中,包括四种花色,分别是红心、方块、梅花和黑桃,每种花色有13张牌,总计52张牌。
因此,我们可以先定义一个字符串数组,数组内存放四种花色牌,各一张,由于这四种花色是固定不变的,可以写成一个常量数组(final修饰);
然后写一个 buyCard方法,它的返回值是List<Card>,表示买牌的动作,在这个方法中:先实例化一个Card类对象,然后通过for循环嵌套将各个花色的所有牌放入对象中(每个花色的牌各有13张,一样的牌各有4张),最后通过add方法添加到Card类对象中。
注意:该方法的返回值是一个泛型类,它的参数是一个Card类类型,因此,需要实例化Card类对象,这里每添加一个花色牌就利用Card的构造方法初始化一下suit和rank,最后将这个Card类型引用作为参数传递给泛型类。
java
public class CardDemo {
public static final String[] suits = {"♥","♠","♣","♦"};
//买一副牌
public List<Card> buyCard() {
List<Card> cardList = new ArrayList<>();
for(int i = 1;i <= 13; i++) {
for(int j = 0;j < 4; j++) {
int rank = i;
String suit = suits[j];
Card card = new Card(suit,rank);
cardList.add(card);
}
}
return cardList;
}
}
接着写一个 shuffle 方法,表示洗牌的动作,在这个方法中,我们需要做的就是打乱牌的顺序,即洗牌。这里需要用到一个类------Random ,这个类中的一个 nextInt 方法,用于生成一个随机数值,该方法的有两种使用方式:
- nextInt():生成一个随机的 int 值,范围是所有可能的 int 值
- nextInt(int bound):生成一个在 [0, bound) 范围内的随机 int 值,包含 0 但不包含 bound
而我们此时需要用的是第2种方式。
写一个for循环,初始条件从最后一张牌 开始,在这个循环中,使用random.nextInt() 方法,每次将随机生成的数值和最后一张牌进行随机交换,比如,有52张牌,它们对应下标是0~51,对这副牌进行洗牌,从最后一张牌开始进入循环,通过random.nextInt(51)生成0~50之间的随机牌,让最后一张牌,即第52张牌与随机的一张牌进行位置交换,接着是通过random.nextInt(50)生成0~49之间的随即牌,再将此时的最后一张牌与随机牌位置交换,直到全部牌交换完成,就完成了洗牌的动作。
注意:循环继续直到i > 0,当i变成0时,循环停止。这是因为当i=0时,只有一个元素 left,不需要交换自己。
而位置交换的动作则写一个 swap 方法来完成:按照之前写swap方法的思路:
- Card tmp = cardLIst[i];
- cardList[i] = cardList[j];
- cardList[j] = tmp;
但是这样写是不行的,cardList引用的类型是List<Card>泛型类,并不是一个数组,不可以使用数组下标运算符[],对于List<Card>类,应该使用 get() 和 set() 方法来代替进行位置交换操作。
java
public void shuffle(List<Card> cardList) {
Random random = new Random();
for(int i = cardList.size()-1;i > 0; i--) {
int index = random.nextInt(i);
swap(cardList,i,index);
}
}
public void swap(List<Card> cardList,int i,int j) {
Card tmp = cardList.get(i);
cardList.set(i,cardList.get(j));
cardList.set(j,tmp);
}
最后写一个轮流揭牌的方法 play ,假设有3个人,每个人要揭5张牌,那么每个人的5张牌要如何存放呢?------ 3个人各自实例化一个List泛型类,将各自的牌存放在各自的引用对象中;使用for循环嵌套,进行轮流揭牌,每次揭玩一张牌,牌就会少一张,使用remove方法,每次揭玩一张牌就删除最上面的那张牌,即下标为0的那张牌。
问题:如何将对应的牌放到对应的人手里呢?
------ 使用二维数组。
java
public <List<Card>> play(List<Card> cardList) {
List<Card> hand0 = new ArrayList<>();
List<Card> hand1 = new ArrayList<>();
List<Card> hand2 = new ArrayList<>();
List<List<Card>> hand = new ArrayList<>();
hand.add(hand0);
hand.add(hand1);
hand.add(hand2);
for(int i = 0;i < 5; i++) {
for(int j = 0;j < 3; j++) {
Card card = cardList.remove(0);
hand.get(j).add(card);//比如:hand.hand0.add(card);
}
}
return hand;
}
3.完整代码
java
//Card类
public class Card {
private String suit;
private int rank;
public Card(String suit,int rank) {
this.suit = suit;
this.rank = rank;
}
public void toString() {
return "{" + suit + rank + "}";
}
}
java
//CardDemo类
public class CardDemo {
public static final String[] suits = {"♥","♠","♣","♦"};
//买一副牌
public List<Card> buyCard() {
List<Card> cardList= new ArrayList<>();
for(int i = 1;i <= 13; i++) {
for(int j = 0;j < 4; j++) {
int rank = i;
String suit = suits[j];
Card card = new Card(suit,rank);
cardList.add(card);
}
}
return cardList;
}
//洗牌
public void shuffle(List<Card> cardList) {
Random random = new Random();
for(int i = cardList.size()-1;i > 0; i--) {
int index = random.nextInt(i);
swap(cardList,i,index);
}
}
public void swap(List<Card> cardList,int i,int j) {
Card tmp = cardList.get(i);
cardList.set(i,cardList.get(j));
cardList.set(j,tmp);
}
//3个人,轮流揭5张牌
public List<List<Card>> play(List<Card> cardList) {
List<Catd> hand0 = new ArrayList<>();
List<Card> hand1 = new ArrayList<>();
List<Card> hand1 = new ArrayList<>();
List<List<Card>> hand = new ArrayList<>();
for(int i = 0;i < 5; i++) {
for(int j = 0;j < 3; j++) {
Card card = cardList.remove(0);
hand.get(j).add(card);
}
}
return hand;
}
}
4.测试
java
public class Test {
public static void main(String[] args) {
CardDemo cardDemo = new CardDemo();
//买一副牌
System.out.println("洗牌前:");
List<Card> cardList = cardDemo.buyCard();
System.out.println(cardList);
//洗牌
System.out.println("洗牌后:");
cardDemo.shuffle(cardList);
System.out.println(cardList);
//3个人轮流揭5张牌
System.out.println("抽牌:");
List<List<Card>> ret = cardDemo.play(cardList);
for(int i = 0;i < ret,size(); i++) {
System.out.println("第"+(i+1)+"个人的牌:"+ret.get(i));
}
System.out.println("剩下的牌:");
System.out.println(cardList);
}
}
输出结果:
