将数组转换成栈及其一些基本操作
public static class ArrayStack {
private Integer[] arr;
private Integer size;
public ArrayStack(Integer initSize) {
if (initSize < 0) {
throw new IllegalArgumentException("The init size is less than 0");
}
arr = new Integer[initSize];
size = 0;
}
//取栈顶元素
public Integer peek() {
if (size == 0) {
return null;
}
return arr[size - 1];
}
//入栈
public void push(int obj) {
if (size == arr.length) {
throw new ArrayIndexOutOfBoundsException("The stack is full");
}
arr[size++] = obj;
}
//出栈
public Integer pop() {
if (size == 0) {
throw new ArrayIndexOutOfBoundsException("The stack is null");
}
return arr[--size];
}
}
数组转换成队列
public static class ArrayQueue {
private Integer[] arr;
private Integer size;
private Integer first;
private Integer last;
private ArrayQueue(int initSize) {
if (initSize < 0) {
throw new IllegalArgumentException("The init size is less than 0");
}
arr = new Integer[initSize];
size = 0;
first = 0;
last = 0;
}
public Integer peek() {
if (size == 0) {
return null;
}
return arr[first];
}
public void push(int obj) {
if (size == arr.length) {
throw new ArrayIndexOutOfBoundsException("The queue is full");
}
size ++;
arr[last] = obj;
//到达队列尾部的处理
last = last == arr.length - 1 ? 0 : last + 1;
}
public Integer poll() {
if (size == 0) {
throw new ArrayIndexOutOfBoundsException("The queue is empty");
}
size --;
int tmp = first;
//到达队列头部的处理
first = first == arr.length - 1 ? 0 : first + 1;
return arr[tmp];
}
}
两个栈转换成一个队列
public static class TwoStacksToQueue {
private Stack<Integer> stackPush;
private Stack<Integer> stackPop;
public TwoStacksToQueue() {
stackPush = new Stack<>();
stackPop = new Stack<>();
}
public void push(int pushInt) {
stackPush.push(pushInt);
}
public int poll() {
if (stackPop.empty() && stackPush.empty()) {
throw new RuntimeException("Queue is empty!");
} else if (stackPop.empty()) {
while (! stackPush.empty()) {
stackPop.push(stackPush.pop());
}
}
return stackPop.pop();
}
public int peek() {
if (stackPop.empty() && stackPush.empty()) {
throw new RuntimeException("Queue is empty!");
} else if (stackPop.empty()) {
while (! stackPush.empty()) {
stackPop.push(stackPush.pop());
}
}
return stackPop.peek();
}
}
两个队列转换成栈
public static class TwoQueuesToStack {
private Queue<Integer> queue;
private Queue<Integer> help;
public TwoQueuesToStack() {
queue = new LinkedList<>();
help = new LinkedList<>();
}
public void push(int pustInt) {
queue.add(pustInt);
}
public int peek() {
if (queue.isEmpty()) {
throw new RuntimeException("Stack is empty!");
}
//将队列中的除最后一个元素外,全部放入help中
while (queue.size() != 1) {
help.add(queue.poll());
}
//取出queue的最后一个元素
int res = queue.poll();
help.add(res);
//将queue与help交换
swap();
return res;
}
public int pop() {
if (queue.isEmpty()) {
throw new RuntimeException("Stack is empty!");
}
while (queue.size() > 1) {
help.add(queue.poll());
}
int res = queue.poll();
swap();
return res;
}
private void swap() {
Queue<Integer> tmp = help;
help = queue;
queue = tmp;
}
}
1.定义Pet类,Dog Cat继承Pet类
public static class Pet {
private String type;
public Pet(String type) {
this.type = type;
}
public String getPetType() {
return this.type;
}
}
public static class Dog extends Pet {
public Dog() {
super("dog");
}
}
public static class Cat extends Pet {
public Cat() {
super("cat");
}
}
2.pet入的队列
public static class PetEnterQueue {
private Pet pet;
private long count;
public PetEnterQueue(Pet pet, long count) {
this.pet = pet;
this.count = count;
}
public Pet getPet() {
return this.pet;
}
public long getCount() {
return this.count;
}
//获取pet类型
public String getEnterPetType() {
return this.pet.getPetType();
}
}
//dog cat队列
public static class DogCatQueue {
private Queue<PetEnterQueue> dogQ;
private Queue<PetEnterQueue> catQ;
private long count;
public DogCatQueue() {
this.dogQ = new LinkedList<PetEnterQueue>();
this.catQ = new LinkedList<PetEnterQueue>();
this.count = 0;
}
//当有pet入时,判断类型,对号入座
public void add(Pet pet) {
if (pet.getPetType().equals("dog")) {
this.dogQ.add(new PetEnterQueue(pet, this.count++));
} else if (pet.getPetType().equals("cat")) {
this.catQ.add(new PetEnterQueue(pet, this.count++));
} else {
throw new RuntimeException("err, not dog or cat");
}
}
//将队列中的所有实例按照顺序出队列
public Pet pollAll() {
if (!this.dogQ.isEmpty() && !this.catQ.isEmpty()) {
if (this.dogQ.peek().getCount() < this.catQ.peek().getCount()) {
return this.dogQ.poll().getPet();
} else {
return this.catQ.poll().getPet();
}
} else if (!this.dogQ.isEmpty()) {
return this.dogQ.poll().getPet();
} else if (!this.catQ.isEmpty()) {
return this.catQ.poll().getPet();
} else {
throw new RuntimeException("err, queue is empty!");
}
}
//将Dog中的所有实例按照顺序出
public Dog pollDog() {
if (!this.isDogQueueEmpty()) {
return (Dog) this.dogQ.poll().getPet();
} else {
throw new RuntimeException("Dog queue is empty!");
}
}
////将Cat中的所有实例按照顺序出
public Cat pollCat() {
if (!this.isCatQueueEmpty()) {
return (Cat) this.catQ.poll().getPet();
} else
throw new RuntimeException("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();
}
}
//数组旋转90度
public static void rotate(int[][] matrix) {
//数组左上角坐标(a,b)右下角坐标(c,d)
int a = 0;
int b = 0;
int c = matrix.length - 1;
int d = matrix[0].length - 1;
//分圈打印
while (a < c) {
rotateEdge(matrix, a++, b++, c--, d--);
}
}
public static void rotateEdge(int[][] matrix, int a, int b, int c, int d) {
int times = d - b;
int tmp = 0;
//坐标对应关系
for (int i = 0; i != times; i ++) {
tmp = matrix[a][b+i];
matrix[a][b+i] = matrix[c-i][b];
matrix[c-i][b] = matrix[c][d-i];
matrix[c][d-i] = matrix[a+i][d];
matrix[a+i][d] = tmp;
}
}
方法二:找坐标对应关系
//(正方形)矩阵顺时针旋转90度
//原纵坐标=新横坐标
//原横坐标+新纵坐标=列数(行数)-1
public static int[][] rotate(int [][]matrix) {
int[][] temp = new int[matrix[0].length][matrix.length];
int row = matrix.length - 1;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
temp[j][row - i] = matrix[i][j];
}
}
return temp;
}
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 [][]temp=rotate(matrix);
for(int i=0;i<temp.length;i++){
for(int j=0;j<temp[0].length;j++){
System.out.print(temp[i][j]+"\t");
}
System.out.println();
}
}
public static void spiralOrderPrint(int[][] matrix) {
int a = 0;
int b = 0;
int c = matrix.length - 1;
int d = matrix[0].length - 1;
while (a <= c && b <= d) {
printEdge(matrix, a++, b++, c--, d--);
} }
public static void printEdge(int[][] m, int a, int b, int c, int d) {
//只有一列
if (a == c) {
for (int i = 0; i < d; i ++) {
System.out.print(m[a][i] + " ");
}
} else if (b == d) {//只有一行
for (int i = 0; i < c; i ++) {
System.out.print(m[i][b] + " ");
}
} else {
//矩形数组
int curRow = a;
int curCol = b;
//此处参考上图
while (curCol != d) {
System.out.print(m[a][curCol++] + " ");
}
while (curRow != c) {
System.out.print(m[curRow++][d] + " ");
}
while (curCol != b) {
System.out.print(m[c][curCol--] + " ");
}
while (curRow != a) {
System.out.print(m[curRow--][b] + " ");
}
}
}
public static void main(String[] args) {
int[][] matrix = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 },
{ 13, 14, 15, 16 } };
spiralOrderPrint(matrix);//1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10
}
//单链表
public static class Node {
int value;
Node next;
public Node(int value) {
this.value = value;
}
}
public static Node reverseList(Node head) {
Node pre = null;
Node next = null;
while (head != null) {
next = head.next;
head.next = pre;
pre = head;
head = next;
}
return pre;
}
//双链表
public static class DoubleNode {
int value;
DoubleNode last;
DoubleNode next;
public DoubleNode(int value) {
this.value = value;
}
}
public static DoubleNode reverseList(DoubleNode head) {
DoubleNode pre = null;
DoubleNode next = null;
while (head != null) {
next = head.next;
head.next = pre;
head.last = next;
pre = head;
head = next;
}
return pre;
}
public static void printZigZagMatrix(int[][] matrix) {
//标记初始打印点的位置。
int aR = 0;
int aC = 0;
int bR = 0;
int bC = 0;
int endR = matrix.length - 1;
int endC = matrix[0].length - 1;
boolean flag = false;//判断斜向上打印还是斜向下打印
while (aR != endR + 1) {
printNum(matrix, aR, aC, bR, bC, flag);
//先判断列再判断行,否则会出现打印错误
aR = aC == endC ? aR + 1 : aR;//判断a是否到达最后一列,如果到达,则a向下,aR+1
aC = aC == endC ? aC : aC + 1;//如果没有到达,则a向右,aC+1
bC = bR == endR ? bC + 1 : bC;
bR = bR == endR ? bR : bR + 1;
flag = !flag;
}
System.out.println();
}
public static void printNum(int[][] m, int aR, int aC, int bR,
int bC, boolean flag) {
if (flag) { //从右上到左下
while (aR != bR + 1) {
System.out.print(m[aR++][aC--] + " ");
}
} else {
while (bR != aR - 1) {
System.out.print(m[bR--][bC++] + " ");
}
}
}
public static void main(String[] args) {
int[][] matrix = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, {13, 14, 15, 16} };
printMatrixZigZag(matrix);//1 2 5 9 6 3 4 7 10 13 14 11 8 12 15 16
}
public static boolean isContains(int[][] matrix, int K) {
int row = matrix.length - 1;//行号
int col = matrix[0].length - 1;//列号
while (row >= 0 && col >= 0) {
if (matrix[row][col] == K) {
return true;
} else if (matrix[row][col] > K) {
col--;//当前数大于K,向左移动
} else {
row--;//当前数小于K,向下移动
}
}
return false;
}
public static void main(String[] args) {
int[][] matrix = new int[][] { { 0, 1, 2, 3, 4, 5, 6 },// 0
{ 10, 12, 13, 15, 16, 17, 18 },// 1
{ 23, 24, 25, 26, 27, 28, 29 },// 2
{ 44, 45, 46, 47, 48, 49, 50 },// 3
{ 65, 66, 67, 68, 69, 70, 71 },// 4
{ 96, 97, 98, 99, 100, 111, 122 },// 5
{ 166, 176, 186, 187, 190, 195, 200 },// 6
{ 233, 243, 321, 341, 356, 370, 380 } // 7
};
int K = 101;
System.out.println(isContains(matrix, K));
}
public static class Node {
int value;
Node next;
public Node(int value) {
this.value = value;
}
}
public static void printCommonPart(Node head1, Node head2) {
while (head1 != null && head2 != null) {
if (head1.value < head2.value) {
head1 = head1.next;
} else if (head1.value > head2.value) {
head2 = head2.next;
} else {
System.out.print(head1.value + " ");
head1 = head1.next;
head2 = head2.next;
}
}
}
public static class Node {
int value;
Node next;
public Node(int value) {
this.value = value;
}
}
//1 额外空间O(n),利用栈
public static boolean isPalindrome1(Node head) {
Stack<Node> stack = new Stack<>();
Node cur = head;
while (cur != null) {
stack.push(cur);
cur = cur.next;
}
while (head != null) {
if (head.value != stack.pop().value) {
return false;
}
head = head.next;
}
return true;
}
//额外空间复杂度O(n/2)
public static boolean isPalindrome2(Node head) {
if (head == null || head.next == null) {
return true;
}
//快慢指针一同遍历,快指针遍历完成,慢指针遍历到一半,慢指针继续遍历压栈,
// 快指针重新以慢指针的速度遍历,出栈比较,直到栈空
Node right = head.next;
Node cur = head;
while (cur.next != null && cur.next.next != null) {
right = right.next;
cur = cur.next.next;
}
Stack<Node> stack = new Stack<>();
while (right != null) {
stack.push(right);
right = right.next;
}
while (!stack.isEmpty()) {
if (head.value != stack.pop().value) {
return false;
}
head = head.next;
}
return true;
}
//不用辅助空间
public static boolean isPalindrome3(Node head) {
if (head == null || head.next == null) {
return true;
}
Node n1 = head;
Node n2 = head;
while (n2.next != null && n2.next.next != null) {
n1 = n1.next;//n1遍历到一半
n2 = n2.next.next;//n2遍历完成
}
//以n2所指节点为头节点,反转链表
n2 = n1.next;
n1.next = null;
Node n3 = null;
while (n2 != null) {
n3 = n2.next;
n2.next = n1;
n1 = n2;
n2 = n3;
}
//两个指针分别指向链表两端,开始向中间遍历,并比较值是否相等
n2 = head;//first
n3 = n1;//last
boolean res = true;
while (n1 != null && n2 != null) {
if (n1.value != n2.value) {
res = false;
break;
}
n1 = n1.next;
n2 = n2.next;
}
//重新将反转后的链表恢复原样
n1 = n3.next;
n3.next = null;
while (n1 != null) {
n2 = n1.next;
n1.next = n3;
n3 = n1;
n1 = n2;
}
return res;
}
public static void printLinkedList(Node node) {
System.out.print("Linked List: ");
while (node != null) {
System.out.print(node.value + " ");
node = node.next;
}
System.out.println();
}