21.调整数组顺序使奇数位于偶数前面
快慢指针法
class Solution {
public int[] exchange(int[] nums) {
//快慢指针法
int fast=0,low=1;
while(low < nums.length){
if(nums[fast] %2 ==1) {
fast++;
low++;
}else if(nums[low]%2 == 1){ //fast是偶数而low是奇数,则可以直接交换
int tmp = nums[fast];
nums[fast] = nums[low];
nums[low] = tmp;
fast++;
low++;
}else{ fast是偶数而low也是偶数,则需要找到low是奇数为止才可以交换
low++;
}
}
return nums;
}
}
22.链表中倒数第k个节点
快慢指针法
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
if(head == null || k<1){
return null;
}
ListNode fast = head;
ListNode slow = head;
for(int i =0;i<k;i++){ //fast先走k步
if(fast == null){
return null;
}
fast = fast.next;
}
while(fast != null){
fast = fast.next;
slow = slow.next;
}
return slow; //fast遍历结束slow指向的节点就是倒数第k个节点
}
}
24.反转链表
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode next = curr.next;
curr.next = prev; //此处的作用就是箭头反向
prev = curr;
curr = next;
}
return prev;
}
}
25.合并两个排序的链表
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode preHead = new ListNode(0);
ListNode pre = preHead;
while(l1!=null && l2 !=null){
if(l1.val < l2.val){
pre.next = l1;
l1 = l1.next;
}else{
pre.next = l2;
l2 = l2.next;
}
pre = pre.next;
}
pre.next = l1==null? l2:l1;
return preHead.next;
}
}
26.树的子结构
B是A的子结构, 即 A中有出现和B相同的结构和节点值。
dfs:
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
return (A != null && B != null) && (recur(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B));
}
boolean recur(TreeNode A, TreeNode B) {
if(B == null) return true;
if(A == null || A.val != B.val) return false;
return recur(A.left, B.left) && recur(A.right, B.right);
}
}
27.二叉树的镜像
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode mirrorTree(TreeNode root) {
if(root == null) return null;
Stack<TreeNode> stack = new Stack<>() ;
stack.add(root);
while(!stack.isEmpty()) {
TreeNode node = stack.pop();
if(node.left != null) stack.add(node.left);
if(node.right != null) stack.add(node.right);
TreeNode tmp = node.left;
node.left = node.right;
node.right = tmp;
}
return root;
}
}
28.对称二叉树
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
//只能使用后序遍历,用递归的返回值判断内侧结点与外侧结点是否相等
if(root == null) return true;
return cmp(root.left,root.right);
}
public boolean cmp(TreeNode left,TreeNode right){
if(left == null && right !=null ) return false;
else if(left != null && right == null) return false;
else if(left ==null && right ==null) return true;
else if(left.val != right.val) return false;
else{
boolean outside = cmp(left.left,right.right); //比较外侧:左子树:左、 右子树:右
boolean inside = cmp(left.right,right.left); //比较内侧:左子树:右、 右子树:左
boolean issame = outside && inside;
return issame;
}
}
}
29.顺时针打印矩阵
注意处理矩阵的边界
class Solution {
public int[] spiralOrder(int[][] matrix) {
if(matrix.length == 0) return new int[0];
int l = 0, r = matrix[0].length - 1, t = 0, b = matrix.length - 1, x = 0;
int[] res = new int[(r + 1) * (b + 1)];
while(true) {
for(int i = l; i <= r; i++) res[x++] = matrix[t][i]; // left to right.
if(++t > b) break;//++t保证了不访问重复的位置
for(int i = t; i <= b; i++) res[x++] = matrix[i][r]; // top to bottom.
if(l > --r) break;
for(int i = r; i >= l; i--) res[x++] = matrix[b][i]; // right to left.
if(t > --b) break;
for(int i = b; i >= t; i--) res[x++] = matrix[i][l]; // bottom to top.
if(++l > r) break;
}
return res;
}
}
30 .包含min函数的栈
双栈模拟队列
class MinStack {
Stack<Integer> A, B;
public MinStack() {
A = new Stack<>();
B = new Stack<>();
}
public void push(int x) {
A.add(x);
if(B.empty() || B.peek() >= x) //保持栈中最小元素
B.add(x);
}
public void pop() {
if(A.pop().equals(B.peek()))
B.pop();
}
public int top() {
return A.peek();
}
public int min() {
return B.peek();
}
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(x);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.min();
*/