复习 29顺时针。
调整数组顺序,奇数位于偶数前面,奇数、偶数相对位置不变:
原书没有说明相对位置不变,可使用两个指针,一个从头检索,一个从尾检索,奇偶相反则呼唤,知道指针重叠。考虑解藕,程序变为1.判断数字奇偶;2.调整位置。
题目思路:1.使用直接插入,奇数往前移动,偶数位置不动,O(n^2)。
2.拷贝数组,第一次遍历数组,奇数放进去,第二次遍历,偶数放进去,O(n),但需要额外空间。
3.冒泡,奇偶相邻互换,O(n^2)。
22.输出链表倒数第k个节点
考虑代码鲁棒性,k大雨节点数,空头节点等问题。
思路1. 遍历两次数组:第一次得到长度,第二次得到倒数第k个节点。
思路2.遍历一次数组:两个指针,当遍历到第k个节点时,第二个指针开始遍历,第一个指针到头,第二个便是倒数第k个节点。
24.反转链表
循环:next指向head的next,head指向pre,(pre指向head,head指向head)作为下一个处理的块。自己指向前节点,并保存后继节点,防止断裂。
递归:递归找到最后一个节点,返回最后一个节点,当前节点的next的next指向自己,next指向空。后继节点指向自己,自己指空,不存在断裂。
/*循环*/
ListNode pre = null;
ListNode next = null;
while(head!=null) {
next = head.next;
head.next = pre;
pre = head;
head = next;
}
return pre;
/*递归*/
if (head==null||head.next==null) {
return head;
}
ListNode newNode = ReverseList(head.next);
head.next.next = head;
head.next = null;
return newNode;
参考https://www.cnblogs.com/kubixuesheng/p/4394509.html
25.合并链表
递归:谁小,谁就作为当前节点,指向下一个节点,下一个节点递归求得。
循环:小的做头节点,比较节点,小的做其后继节点,直到遍历结束,将剩余链表接上,返回头节点。
if (list1==null) {
return list2;
}
if (list2==null) {
return list1;
}
if (list1.val<=list2.val) {
list1.next = Merge(list1.next, list2);
return list1;
}else {
list2.next = Merge(list1, list2.next);
return list2;
}
ListNode mergeHead = null;
ListNode currentNode = null;
while(list1!=null&&list2!=null) {
if (list1.val<=list2.val) {
if (mergeHead==null) {
mergeHead = currentNode = list1;
}else {
currentNode.next = list1;
currentNode = currentNode.next;
}
list1 = list1.next;
}else {
if (mergeHead==null) {
mergeHead = currentNode = list2;
}else {
currentNode.next = list2;
currentNode = currentNode.next;
}
list2 = list2.next;
}
}
if (list1!=null) {
currentNode.next = list1;
}
if (list2!=null) {
currentNode.next = list2;
}
return mergeHead;
26.二叉树子树结构
递归:1.判断跟节点和子树跟节点值是否相等,否则遍历左右子树。
2.相等,再判断子树节点值是否相等。
27.二叉树镜像
思路1:递归,当前子树非空,交换左右子树。
思路2:循环,根压入栈,进入循环(栈非空),则出栈,交换左右元素,若左右元素存在,入栈,继续循环,直到栈空。
if (root==null) {
return;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.empty()) {
TreeNode currentNode = stack.pop();
TreeNode temp = currentNode.right;
if (currentNode.left!=null||currentNode.right!=null) {
currentNode.right = currentNode.left;
currentNode.left = temp;
}
if (currentNode.left!=null) {
stack.push(currentNode.left);
}
if (currentNode.right!=null) {
stack.push(currentNode.right);
}
/*有问题的版本*/
/* if (currentNode.left!=null) {
currentNode.right = currentNode.left;
stack.push(currentNode.left);
}
if (currentNode.right!=null) {
currentNode.left = temp;
stack.push(temp);
}*/
29.顺时针打印矩阵
先打上行,再打右列,再打下行,再打左列。
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printMatrix(int [][] matrix) {
if (matrix==null||matrix.length == 0||matrix[0] == null||matrix[0].length == 0) {
return null;
}
ArrayList<Integer> result = new ArrayList<>();
int topLimit = 0;
int bottomLimit = matrix.length-1;
int leftLimit = 0;
int rightLimit = matrix[0].length-1;
int init = (int) (bottomLimit>rightLimit?((double)rightLimit/2)+0.5:((double)bottomLimit/2)+0.5);
int col = 0, row = 0;
while(col<=init&&row<=init) {
//上行
for(int i = col; i <= rightLimit; i++) {
result.add(matrix[topLimit][i]);
//System.out.print(matrix[topLimit][i]+" ");
}
topLimit++;
if (topLimit>bottomLimit) {
break;
}
if (leftLimit>rightLimit) {
break;
}
//右行
for(int i = topLimit; i <= bottomLimit; i++) {
result.add(matrix[i][rightLimit]);
//System.out.print(matrix[i][rightLimit]+" ");
}
rightLimit--;
//只有一列时的情况
if (leftLimit>rightLimit) {
break;
}
//下行
for(int i = rightLimit; i>= leftLimit; i--) {
result.add(matrix[bottomLimit][i]);
//System.out.println(matrix[bottomLimit][i]+" ");
}
bottomLimit--;
if (topLimit>bottomLimit) {
break;
}
//左行
for(int i = bottomLimit; i >= topLimit; i--) {
result.add(matrix[i][leftLimit]);
//System.out.println(matrix[i][leftLimit]+" ");
}
leftLimit++;
col++;
row++;
}
return result;
}
}