第十五题:反转链表
题目描述:
输入一个链表,反转链表后,输出链表的所有元素。
思路:
由于在做指针反转的过程中,对于结点i,需要知道它前一个结点h来作为反转后的下一个结点,以及后一个结点j来继续推进。
代码:
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode ReverseList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode p1 = null;
ListNode p2 = head;
ListNode p3 = head.next;
while (p3 != null) {
p2.next = p1;
p1 = p2;
p2 = p3;
p3 = p3.next;
}
p2.next = p1;
return p2;
}
}
第十六题:合并两个排序的链表
题目描述:
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
思路:
需要两个指针,分别指向两个链表的要比较的那个结点,比较大小后指向下一个结点,要注意的是比较完之后多余的链表结点要加在新链表后面。当然这个题目可以用递归的思路解决。
代码:
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode Merge(ListNode list1,ListNode list2) {
if (list1 == null) {
return list2;
}
if (list2 == null) {
return list1;
}
ListNode ret = null;
if (list1.val <= list2.val) {
ret = list1;
ret.next = Merge(list1.next, list2);
} else {
ret = list2;
ret.next = Merge(list1, list2.next);
}
return ret;
}
}
第十七题:树的子结构
题目描述:
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
思路:
先比较AB两树的根结点是否相同,相同的基础上进一步比较AB树的子结点是否相同。遍历的方式采用递归的方法。
代码:
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
if(root2 == null || root1 == null) {
return false;
}
boolean ret = false;
if (root1.val == root2.val) {
ret = IsSubtree(root1, root2);
}
if (!ret) {
ret = HasSubtree(root1.left, root2);
}
if (!ret) {
ret = HasSubtree(root1.right, root2);
}
return ret;
}
public boolean IsSubtree(TreeNode root1, TreeNode root2) {
if (root2 == null) {
return true;
}
if (root1 == null) {
return false;
}
if (root1.val == root2.val){
return IsSubtree(root1.left, root2.left) && IsSubtree(root1.right, root2.right);
}else {
return false;
}
}
}
第十八题:二叉树的镜像
题目描述:
操作给定的二叉树,将其变换为原二叉树的镜像。
思路:
对跟结点而言,只要它的左右儿子不都为null,则交换它的左右结点,并且递归这个过程。
代码:
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public void Mirror(TreeNode root) {
if (root == null ||
(root.left == null && root.right == null)) {
return ;
}
TreeNode tmp = root.left;
root.left = root.right;
root.right = tmp;
Mirror(root.left);
Mirror(root.right);
}
}
第十九题:顺时针打印矩阵
题目描述:
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 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.
思路:
这个题目需要具体在纸上画一下,其实每一圈的起始点的行列坐标时相同的,即(0,0)-》(1,1)-》(2,2)-》(n,n);其背后的规律就是每一圈能打印的前提就是这个行数大于2n,并且列数大于2n。要注意的是每一圈的打印,除了每一圈的第一行一定可以打印以外,其余的都需要判断是否符合条件。具体看代码。
代码:
import java.util.ArrayList;
public class Solution {
ArrayList<Integer> ret = new ArrayList<>();
public ArrayList<Integer> printMatrix(int [][] matrix) {
if (matrix == null || matrix.length <=0 ||
matrix[0].length <= 0) {
return ret;
}
int index = 0;
int rows = matrix.length;
int columns = matrix[0].length;
while ((rows > 2 * index) && (columns > 2 * index)) {
print(matrix, index);
index ++;
}
return ret;
}
public void print(int [][] matrix, int index){
int endX = matrix[0].length - 1 - index;
int endY = matrix.length - 1 - index;
//第一行放进去
for (int i = index; i <= endX; i++) {
ret.add(matrix[index][i]);
}
//最后一列
if (endY > index) {
for (int i = index+1; i <= endY; i++) {
ret.add(matrix[i][endX]);
}
}
//最后一行
if (endY>index && endX > index) {
for (int i = endX-1; i >= index; i--) {
ret.add(matrix[endY][i]);
}
}
//第一列
if (endX > index && endY > index+1) {
for (int i = endY-1; i > index; i--) {
ret.add(matrix[i][index]);
}
}
}
}
第二十题:包含min函数的栈
题目描述:
定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。
思路:
需要一个辅助栈min,每次让数据栈里面放数据时,先判断min中前一个数字a与放入的数字b的大小,如果b小,则往min中压入b,如果a小,则往min中再一次压入a;这个辅助栈的数据个数与数据栈的数据个数一样,保证了在提取当前栈的最小值时能后以o(1) 的时间复杂度找到。
代码:
import java.util.Stack;
public class Solution {
Stack<Integer> data = new Stack<Integer>();
Stack<Integer> min = new Stack<Integer>();
public void push(int node) {
data.push(node);
if(!min.isEmpty() && min.peek()<=node) {
min.push(min.peek());
}else{
min.push(node);
}
}
public void pop() {
if((!data.isEmpty())&&(!min.isEmpty())) {
data.pop();
min.pop();
}
}
public int top() {
if((!data.isEmpty())&&(!min.isEmpty())) {
return data.peek();
}else{
return -1;
}
}
public int min() {
if((!data.isEmpty())&&(!min.isEmpty())) {
return min.peek();
}else {
return -1;
}
}
}