1.猫狗队列

【题目】 宠物、 狗和猫的类如下:

public class Pet {private String type;public Pet(String type) {this.type = type;}public String getPetType() {return this.type;}
}public class Dog extends Pet {public Dog() {super("dog");}
}public class Cat extends Pet {public Cat() {super("cat");}
}

实现一种狗猫队列的结构, 要求如下:

  • 用户可以调用add方法,将cat类或dog类的实例放入队列中;
  • 用户可以调用pollAll方法, 将队列中所有的实例按照进队列的先后顺序依次弹出;
  • 用户可以调用pollDog方法, 将队列中dog类的实例按照进队列的先后顺序依次弹出;
  • 用户可以调用pollCat方法, 将队列中cat类的实例按照进队列的先后顺序依次弹出;
  • 用户可以调用isEmpty方法, 检查队列中是否还有dog或cat的实例;
  • 用户可以调用isDogEmpty方法, 检查队列中是否有dog类的实例;
  • 用户可以调用isCatEmpty方法, 检查队列中是否有cat类的实例。

1.1 分析

使用两个队列实现:

add():当宠物进入结构时:

  • 若宠物为狗,则进入Dog队列;
  • 若为猫,则进入Cat队列。

pollDog():从Dog队列取头一个狗;

pollCat():从Cat队列取头一个猫;

pollAll():得设置一个计数器count,作为时间戳,进来一个宠物,无论猫狗,count++,赋给这个宠物的count,取出时,由Dog队列和Cat队列的头一个的count来判断哪个宠物进的早点。

isEmpty():Dog队列和Cat队列都为空时返回true;

isDogEmpty():Dog队列为空时返回true;

isDogEmpty():Cat队列为空时返回true;

1.2 代码实现

注:不能更改给定的Pet、Cat、Dog类,需自己写其他的类实现以上功能。

package Solution;import java.util.LinkedList;
import java.util.Queue;class Pet {private String type;public Pet(String type) {this.type = type;}public String getPetType() {return this.type;}
}class Dog extends Pet {public Dog() {super("dog");}
}
class Cat extends Pet {public Cat() {super("cat");}
}class PetQueue{private Pet pet;private long count;public PetQueue(Pet pet, long count) {this.pet=pet;this.count=count;}public Pet getPet() {return this.pet;}public long getCount() {return this.count;}public String getPetType() {return this.pet.getPetType();}
}
public class CatDogQueue {private Queue<PetQueue> DogQ;private Queue<PetQueue> CatQ;long count;//计数器public CatDogQueue() {this.DogQ=new LinkedList<PetQueue>();this.CatQ=new LinkedList<PetQueue>();this.count=0;}public void add(Pet pet) {//根据类型入相应的队列if(pet.getPetType().equals("cat"))CatQ.add(new PetQueue(pet,count++));else if(pet.getPetType().equals("dog"))DogQ.add(new PetQueue(pet,count++));elsethrow new RuntimeException("err, not dog or cat");}public Pet pollAll() {if(!DogQ.isEmpty()&&!CatQ.isEmpty())if(DogQ.peek().getCount()<CatQ.peek().getCount())//越小越早return this.DogQ.poll().getPet();elsereturn this.CatQ.poll().getPet();else if(!DogQ.isEmpty())return this.DogQ.poll().getPet();else if(!CatQ.isEmpty())return this.CatQ.poll().getPet();elsethrow new RuntimeException("err, queue is empty!");}public Dog pollDog() {if(!DogQ.isEmpty())return (Dog)this.DogQ.poll().getPet();elsethrow new RuntimeException("err, Dog queue is empty!");}public Cat pollCat() {if(!CatQ.isEmpty())return (Cat)this.CatQ.poll().getPet();elsethrow new RuntimeException("err, Cat queue is empty!");}public boolean isEmpty() {return this.DogQ.isEmpty()&&this.CatQ.isEmpty();}public boolean isDogQueueEmpty() {return this.DogQ.isEmpty();}public boolean isCatQueueEmpty() {return this.CatQ.isEmpty();}public static void main(String[] args) {CatDogQueue test = new CatDogQueue();Pet dog1 = new Dog();Pet cat1 = new Cat();Pet dog2 = new Dog();Pet cat2 = new Cat();Pet dog3 = new Dog();Pet cat3 = new Cat();test.add(dog1);test.add(cat1);test.add(dog2);test.add(cat2);test.add(dog3);test.add(cat3);System.out.println(test.pollAll().getPetType());System.out.println(test.pollDog().getPetType());System.out.println(test.pollCat().getPetType());while (!test.isDogQueueEmpty()) {System.out.println(test.pollDog().getPetType());}while (!test.isEmpty()) {System.out.println(test.pollAll().getPetType());}}
}

运行结果:

2.转圈打印矩阵

【题目】 给定一个整型矩阵matrix, 请按照转圈的方式打印它。例如: 1 2 3 4 5 6 7 8 9 10 11 12 13 14  15 16 打印结果为: 1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9,5, 6, 7, 11, 10
【要求】 额外空间复杂度为O(1)

另一篇已写过

2.1 分析

2.1.1 子过程

给定左上角和右下角两个点,可以确定一个矩形。

打印上边的边:

打印右边的边:

打印下边的边:

打印左边的边:

2.1.2 整体分析

一层一层打印,第一层打完,由左上角和右下角移动后,分别确定下一层的范围:

2.2 代码实现

package Solution;public class PrintMatrix {public static void main(String[] args) {int[][] matrix= {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16},{17,18,19,20}};int[][] ma1= {{1,2,3,4}};int[][] ma2= {{1},{2},{3},{4}};printMatrix(matrix);System.out.println();printMatrix(ma1);System.out.println();printMatrix(ma2);}public static void printMatrix(int[][] matrix) {int hstart=0;int hend=0;int lstart=matrix.length-1;//行数int lend=matrix[0].length-1;//列数while(hstart<=lstart&&hend<=lend) {printEdge(matrix,hstart++,hend++,lstart--,lend--);}}public static void printEdge(int[][] ma,int hs,int he,int ls,int le) {if(hs==ls)while(he<=le)System.out.print(ma[hs][he++]+" ");else if(he==le)while(hs<=ls)System.out.print(ma[hs++][he]+" ");else {int curC=hs;//当前行标int curR=he;//当前列标while(curR<le) System.out.print(ma[curC][curR++]+" ");while(curC<ls)System.out.print(ma[curC++][curR]+" ");while(curR>he) System.out.print(ma[curC][curR--]+" ");while(curC>hs)System.out.print(ma[curC--][curR]+" ");}}
}

运行结果:

3.旋转正方形矩阵

【题目】 给定一个整型正方形矩阵matrix, 请把该矩阵调整成顺时针旋转90度的样子。
【要求】 额外空间复杂度为O(1)。

3.1 分析

分层转。如下,分成两层:

第一层:

拿出1放到4的位置,4放到16的位置,16放到13的位置,13放到1的位置;

接着:

第一层中的2放到8的位置,8放到15的位置,15放到9的位置,9放到2的位置;

3,5,12,14类似。

第二层也一样。

3.2 代码实现

package Solution;public class RotateMatrix {public static void main(String[] args) {int[][] matrix= {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};int hstart=0;int hend=0;int lstart=matrix.length-1;int lend=matrix[0].length-1;while(hstart<=lstart)rotateMatrix(matrix,hstart++,hend++,lstart--,lend--);for(int i=0;i<matrix.length;i++) {for(int j=0;j<matrix[0].length;j++)System.out.print(matrix[i][j]+"  ");System.out.println();}}public static void rotateMatrix(int[][] ma,int hs,int he,int ls,int le) {int times=le-he;for(int i=0;i<times;i++){int temp=ma[hs][he+i];ma[hs][he+i]=ma[ls-i][he];ma[ls-i][he]=ma[ls][le-i];ma[ls][le-i]=ma[hs+i][le];ma[hs+i][le]=temp;           }}
}

运行结果:

注意:代码中times的使用。

int times=le-he;

  • 即每行元素的个数-1
  • 每一列第一个元素加到最后一个元素所需加的次数
  • 但是不能到最后一个元素,所以循环的i应小于times。到达最后一个元素的前一个元素就可停止。

4.反转单向和双向链表

【题目】 分别实现反转单向链表和反转双向链表的函数。

【要求】 如果链表长度为N, 时间复杂度要求为O(N), 额外空间复杂度要求为O(1)。

4.1 反转单链表

4.1.1 分析

反转之前:

需要设置两个指针pre、next,next指向当前节点的后继(以确定当前节点的下一个节点的位置),pre指向当前节点的前驱(以确定当前节店反转之后的后继)。head指向的是当前节点。

Node pre=null;
Node next=head.next;

首先,令当前节点的后继指向pre所指的节点(此处为null,反转之后1为末节点,所以他的后继本应也就为null):

head.next=pre;

然后,令pre指向head,以保存2节点反转之后的后继节点位置:

pre=head;

接着,head移到它的后继位置,继续处理下一个节点(节点2):

head=next;

一轮结束!

第二轮:

  1. next指向head的后继节点(节点3);
  2. head的后继指向pre(节点1);
  3. pre指向当前节点(节点2);
  4. head指向next节点(节点3);

代码:

next=head.next;
head.next=pre;
pre=head;
head=next;

图示:

4.1.2 代码实现

package Solution;class Node {public int value;public Node next;public Node(int data) {this.value = data;}
}public class ReverseList {public static void main(String[] args) {Node head=new Node(1);head.next=new Node(2);head.next.next=new Node(3);printList(head);Node revhead=reverseList(head);printList(revhead);}public static Node reverseList(Node head) {//head不为空Node pre=null;Node next=null;while(head!=null) {next=head.next;head.next=pre;pre=head;head=next;}return pre;}public static void printList(Node head) {while(head!=null) {System.out.print(head.value+" ");head=head.next;}System.out.println();}}

运行结果:

4.2 反转双向链表

4.2.1 分析

同样准备两个指针pre、next:

步骤和反转单向链表一样:

代码:

next=head.next;
head.next=pre;
head.last=next;
pre=head;
head=next;

图示:

4.2.2 代码实现

package Solution;class DoubleNode {public int value;public DoubleNode last;public DoubleNode next;public DoubleNode(int data) {this.value = data;}
}
public class ReverseDoubleList {public static void main(String[] args) {DoubleNode head2 = new DoubleNode(1);head2.next = new DoubleNode(2);head2.next.last = head2;head2.next.next = new DoubleNode(3);head2.next.next.last = head2.next;head2.next.next.next = new DoubleNode(4);head2.next.next.next.last = head2.next.next;printDoubleList(head2);printDoubleList(reverseDoubleList(head2));}public static DoubleNode reverseDoubleList(DoubleNode head) {DoubleNode next=null;DoubleNode pre=null;while(head!=null) {next=head.next;head.next=pre;head.last=next;pre=head;head=next;}return pre;}public static void printDoubleList(DoubleNode head) {System.out.print("Double Linked List: ");DoubleNode end = null;while (head != null) {System.out.print(head.value + " ");end = head;head = head.next;}System.out.print("| ");while (end != null) {System.out.print(end.value + " ");end = end.last;}System.out.println();}
}

运行结果:

5.求n的加法组合,将一个整数拆分成多个整数相加的形式, O(N)时间,O(N)空间

原博

算法练习day8——190326(猫狗队列、转圈打印矩阵、旋转正方形矩阵、反转单向双向链表、数N的加法组合)相关推荐

  1. 数据结构与算法之转圈打印矩阵和旋转正方形矩阵

    数据结构与算法之转圈打印矩阵和旋转正方形矩阵 目录 转圈打印矩阵 旋转正方形矩阵 1. 转圈打印矩阵 题目描述 代码实现 public class Code_PrintMatrixSpiralOrde ...

  2. 数据结构与算法之猫狗队列

    数据结构与算法之猫狗队列 目录 猫狗队列 1. 猫狗队列 描述 代码实现 import java.util.LinkedList; import java.util.Queue;public clas ...

  3. 左神算法:猫狗队列(通过给不同实例盖时间戳的方法实现)

    本题来自左神<程序员面试代码指南>"猫狗队列"题目. 题目 宠物.狗和猫的类如下: public class Pet {private String type;publ ...

  4. JAVA中在某游戏系统有猫狗猪_算法面试题之猫狗队列(java)

    [题目]: 已知有宠物:狗.猫如下,实现一种猫狗队列的结构: /** * @ClassName Pet * @Description 宠物 * @Author Huarray * @Date 2019 ...

  5. 程序员代码面试指南第二版 4.猫狗队列

    welcome to my blog 程序员代码面试指南第二版 4.猫狗队列 题目描述 题目描述 实现一种猫狗队列的结构,要求如下: 1. 用户可以调用 add 方法将 cat 或者 dog 放入队列 ...

  6. python 旋转矩阵_【每日算法Day 93】不用额外空间,你会旋转一个矩阵吗?

    第 100 天时,我可能会对这 100 天以来的算法题进行一个总结,然后暂时停止更新 LeetCode 题解了. 下一步可能更新 NLP 相关算法了,非常感谢大家每天的支持. 题目链接 LeetCod ...

  7. 算法练习day8——190326(队列实现栈、栈实现队列)

    1.仅用队列结构实现栈结构 1.1 分析: 1.所有数先入data队列: 2.将前n-1个数入help队列,弹出最后一个数: 3.将help中的前n-2个数入data队列,弹出最后一个数: 4.重复2 ...

  8. CV之CNN:基于tensorflow框架采用CNN(改进的AlexNet,训练/评估/推理)卷积神经网络算法实现猫狗图像分类识别

    CV之CNN:基于tensorflow框架采用CNN(改进的AlexNet,训练/评估/推理)卷积神经网络算法实现猫狗图像分类识别 目录 基于tensorflow框架采用CNN(改进的AlexNet, ...

  9. 猫狗图像识别(卷积神经网络算法,TensorFlow安装)

    目录 一.tensorflow库安装 (1)TensorFlow的历史版本与对应Python版本 (2)Python版本查询 (3)找到上面的版本框进行对应的TensorFlow下载 (4)安装成功 ...

最新文章

  1. 2022-2028年中国绿冻石行业市场研究及前瞻分析报告
  2. 用于主题检测的临时日志(d94169f9-f1c0-45a2-82d4-6edc4bd35539 - 3bfe001a-32de-4114-a6b4-4005b770f6d7)...
  3. ES6中的Promise使用方法与总结
  4. 修改 pip 下载源
  5. 数据库元数据数据字典查询_7_列出给定表的检查约束
  6. hadoop高速扫盲帖,从零了解hadoop
  7. JSON.toJSONString
  8. UIImageView01
  9. DC/OS 的安装与部署
  10. Linux开机启动过程(10):start_kernel 初始化(至setup_arch初期)
  11. MySQL实习训练1
  12. PCL三维点云拼接融合
  13. jdk api 1.8中文手册
  14. 机器学习UCI数据库
  15. 推荐一个好看且实用的火狐浏览器新标签页插件【火狐浏览器新标签页自定义美化】
  16. ROS新建工作空间及编译
  17. 学习python爬虫-爬取豆瓣top250相关信息
  18. 简单的个人介绍网页-主页面【附代码】
  19. android studio 雷电模拟器
  20. Python每日一编程小练习(2019.06.10)——赛场统分

热门文章

  1. Cisco PT模拟实验(16) 路由器重分发配置
  2. 使用WPF动画编程的几点注意事项[转]
  3. Win7x64中使用VS调试WEB项目报“ORA-06413: 连接未打开”错误解决方法
  4. 演示:混合配置基于Linux winows cisco环境动态路由
  5. 摘抄 web 经 关于 自适应网页设计(Responsive Web Design)
  6. PCA与LDA算法的解释,浅显易懂
  7. gorm的零值问题:默认仅更新非零值
  8. 有没有高效的记视频笔记方法?--天若OCR文字识别记视频笔记
  9. Linux CentOS 6.x 关闭图形化界面的方法
  10. Java二维数组排序(按照某一列值大小)