算法练习day8——190326(猫狗队列、转圈打印矩阵、旋转正方形矩阵、反转单向双向链表、数N的加法组合)
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;
一轮结束!
第二轮:
- next指向head的后继节点(节点3);
- head的后继指向pre(节点1);
- pre指向当前节点(节点2);
- 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. 转圈打印矩阵 题目描述 代码实现 public class Code_PrintMatrixSpiralOrde ...
- 数据结构与算法之猫狗队列
数据结构与算法之猫狗队列 目录 猫狗队列 1. 猫狗队列 描述 代码实现 import java.util.LinkedList; import java.util.Queue;public clas ...
- 左神算法:猫狗队列(通过给不同实例盖时间戳的方法实现)
本题来自左神<程序员面试代码指南>"猫狗队列"题目. 题目 宠物.狗和猫的类如下: public class Pet {private String type;publ ...
- JAVA中在某游戏系统有猫狗猪_算法面试题之猫狗队列(java)
[题目]: 已知有宠物:狗.猫如下,实现一种猫狗队列的结构: /** * @ClassName Pet * @Description 宠物 * @Author Huarray * @Date 2019 ...
- 程序员代码面试指南第二版 4.猫狗队列
welcome to my blog 程序员代码面试指南第二版 4.猫狗队列 题目描述 题目描述 实现一种猫狗队列的结构,要求如下: 1. 用户可以调用 add 方法将 cat 或者 dog 放入队列 ...
- python 旋转矩阵_【每日算法Day 93】不用额外空间,你会旋转一个矩阵吗?
第 100 天时,我可能会对这 100 天以来的算法题进行一个总结,然后暂时停止更新 LeetCode 题解了. 下一步可能更新 NLP 相关算法了,非常感谢大家每天的支持. 题目链接 LeetCod ...
- 算法练习day8——190326(队列实现栈、栈实现队列)
1.仅用队列结构实现栈结构 1.1 分析: 1.所有数先入data队列: 2.将前n-1个数入help队列,弹出最后一个数: 3.将help中的前n-2个数入data队列,弹出最后一个数: 4.重复2 ...
- CV之CNN:基于tensorflow框架采用CNN(改进的AlexNet,训练/评估/推理)卷积神经网络算法实现猫狗图像分类识别
CV之CNN:基于tensorflow框架采用CNN(改进的AlexNet,训练/评估/推理)卷积神经网络算法实现猫狗图像分类识别 目录 基于tensorflow框架采用CNN(改进的AlexNet, ...
- 猫狗图像识别(卷积神经网络算法,TensorFlow安装)
目录 一.tensorflow库安装 (1)TensorFlow的历史版本与对应Python版本 (2)Python版本查询 (3)找到上面的版本框进行对应的TensorFlow下载 (4)安装成功 ...
最新文章
- 2022-2028年中国绿冻石行业市场研究及前瞻分析报告
- 用于主题检测的临时日志(d94169f9-f1c0-45a2-82d4-6edc4bd35539 - 3bfe001a-32de-4114-a6b4-4005b770f6d7)...
- ES6中的Promise使用方法与总结
- 修改 pip 下载源
- 数据库元数据数据字典查询_7_列出给定表的检查约束
- hadoop高速扫盲帖,从零了解hadoop
- JSON.toJSONString
- UIImageView01
- DC/OS 的安装与部署
- Linux开机启动过程(10):start_kernel 初始化(至setup_arch初期)
- MySQL实习训练1
- PCL三维点云拼接融合
- jdk api 1.8中文手册
- 机器学习UCI数据库
- 推荐一个好看且实用的火狐浏览器新标签页插件【火狐浏览器新标签页自定义美化】
- ROS新建工作空间及编译
- 学习python爬虫-爬取豆瓣top250相关信息
- 简单的个人介绍网页-主页面【附代码】
- android studio 雷电模拟器
- Python每日一编程小练习(2019.06.10)——赛场统分
热门文章
- Cisco PT模拟实验(16) 路由器重分发配置
- 使用WPF动画编程的几点注意事项[转]
- Win7x64中使用VS调试WEB项目报“ORA-06413: 连接未打开”错误解决方法
- 演示:混合配置基于Linux winows cisco环境动态路由
- 摘抄 web 经 关于 自适应网页设计(Responsive Web Design)
- PCA与LDA算法的解释,浅显易懂
- gorm的零值问题:默认仅更新非零值
- 有没有高效的记视频笔记方法?--天若OCR文字识别记视频笔记
- Linux CentOS 6.x 关闭图形化界面的方法
- Java二维数组排序(按照某一列值大小)