一.链表
1.翻转链表(过)
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @return ListNode类
*/
public ListNode ReverseList (ListNode head) {
// write code here
if(head == null || head.next == null){
return head;
}
ListNode cur = head.next;
head.next = null;
while(cur != null){
ListNode curNext = cur.next;
cur.next = head;
head = cur;
cur = curNext;
}
return head;
}
}
2.指定区间翻转链表(过)
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @param m int整型
* @param n int整型
* @return ListNode类
*/
public ListNode reverseBetween (ListNode head, int m, int n) {
// write code here
if(head == null || m <= 0 || n <= 0){
return null;
}
ListNode node = new ListNode(-1);
node.next = head;
ListNode tmp = node;
for(int i = 0;i < m - 1;i++){
tmp = tmp.next;
}
ListNode cur = tmp.next;
for(int i = 0;i < n - m;i++){
ListNode curNext = cur.next;
cur.next = curNext.next;
curNext.next = tmp.next;
tmp.next = curNext;
}
return node.next;
}
}
3. 链表中的节点每k个一组翻转
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @param k int整型
* @return ListNode类
*/
public ListNode reverseKGroup (ListNode head, int k) {
// write code here
if(head == null || head.next == null || k <= 0){
return head;
}
ListNode node = new ListNode(-1);
node.next = head;
ListNode per = head;
for(int i = 0;i < k;i++){
if(per == null){
return head;
}
per = per.next;
}
ListNode cur = node.next;
while(cur != per){
ListNode curNext = cur.next;
cur.next = node;
node = cur;
cur = curNext;
}
head.next = reverseKGroup(per,k);
return node;
}
}
4.合并两个有序链表(过)
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pHead1 ListNode类
* @param pHead2 ListNode类
* @return ListNode类
*/
public ListNode Merge (ListNode pHead1, ListNode pHead2) {
// write code here
if(pHead1 == null && pHead2 == null){
return null;
}
ListNode node = new ListNode(-1);
ListNode tmp = node;
while(pHead1 != null && pHead2 != null){
if(pHead1.val > pHead2.val){
tmp.next = pHead2;
pHead2 = pHead2.next;
tmp = tmp.next;
}else{
tmp.next = pHead1;
pHead1 = pHead1.next;
tmp = tmp.next;
}
}
if(pHead1 != null){
tmp.next = pHead1;
}
if(pHead2 != null){
tmp.next = pHead2;
}
return node.next;
}
}
5.合并k个已排序的链表
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param lists ListNode类ArrayList
* @return ListNode类
*/
public ListNode Merge (ListNode pHead1, ListNode pHead2) {
// write code here
if(pHead1 == null && pHead2 == null){
return null;
}
ListNode node = new ListNode(-1);
ListNode tmp = node;
while(pHead1 != null && pHead2 != null){
if(pHead1.val > pHead2.val){
tmp.next = pHead2;
pHead2 = pHead2.next;
tmp = tmp.next;
}else{
tmp.next = pHead1;
pHead1 = pHead1.next;
tmp = tmp.next;
}
}
if(pHead1 != null){
tmp.next = pHead1;
}
if(pHead2 != null){
tmp.next = pHead2;
}
return node.next;
}
public ListNode diver(ArrayList<ListNode> lists,int left,int right){
if(left > right){
return null;
}else if(left == right){
return lists.get(left);
}else{
int mid = (left + right) >> 1;
return Merge(diver(lists,left,mid),diver(lists,mid + 1,right));
}
}
public ListNode mergeKLists (ArrayList<ListNode> lists) {
// write code here
return diver(lists,0,lists.size() - 1);
}
}
6.判断链表中是否有环(过)
import java.util.*;
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
if(head == null || head.next == null){
return false;
}
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
if(slow == fast){
return true;
}
}
return false;
}
}
7. 链表中环的入口结点(过)
import java.util.*;
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ListNode EntryNodeOfLoop(ListNode pHead) {
if(pHead == null || pHead.next == null){
return null;
}
ListNode fast = pHead;
ListNode slow = pHead;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
if(fast == slow){
break;
}
}
if(fast == null || fast.next == null){
return null;
}
fast = pHead;
while(fast != slow){
fast = fast.next;
slow = slow.next;
}
return slow;
}
}
8.链表中倒数最后k个结点(过)
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pHead ListNode类
* @param k int整型
* @return ListNode类
*/
public ListNode FindKthToTail (ListNode pHead, int k) {
// write code here
if(pHead == null || k <= 0){
return null;
}
ListNode fast = pHead;
ListNode slow = pHead;
while(k-- > 0){
if(fast == null){
return null;
}
fast = fast.next;
}
while(fast != null){
fast = fast.next;
slow = slow.next;
}
return slow;
}
}
9.删除链表的倒数第n个节点
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @param n int整型
* @return ListNode类
*/
public ListNode removeNthFromEnd (ListNode head, int n) {
// write code here
if(head == null || n <= 0){
return head;
}
ListNode node = new ListNode(-1);
node.next = head;
ListNode tmp = node;
ListNode fast = head;
while(n-- > 0){
if(fast == null){
return head;
}
fast = fast.next;
}
ListNode slow = head;
while(fast != null){
fast = fast.next;
slow = slow.next;
tmp = tmp.next;
}
tmp.next = slow.next;
return node.next;
}
}
10.两个链表的第一个公共结点(过)
import java.util.*;
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if(pHead1 == null || pHead2 == null){
return null;
}
int len1 = 0;
int len2 = 0;
ListNode p1 = pHead1;
ListNode p2 = pHead2;
while(p1 != null){
p1 = p1.next;
len1++;
}
while(p2 != null){
p2 = p2.next;
len2++;
}
int len = len1 - len2;
if(len < 0){
len = -len;
p1 = pHead2;
p2 = pHead1;
}else{
p1 = pHead1;
p2 = pHead2;
}
while(len-- > 0){
p1 = p1.next;
}
while(p1 != null && p2 != null){
if(p1 == p2){
return p1;
}
p1 = p1.next;
p2 = p2.next;
}
return null;
}
}
11.链表相加
解法一:借助翻转链表
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head1 ListNode类
* @param head2 ListNode类
* @return ListNode类
*/
//翻转链表
public ListNode reverse(ListNode head){
if(head == null || head.next == null){
return head;
}
ListNode cur = head.next;
head.next = null;
while(cur != null){
ListNode curNext = cur.next;
cur.next = head;
head = cur;
cur = curNext;
}
return head;
}
public ListNode addInList (ListNode head1, ListNode head2) {
// write code here
if(head1 == null){
return head2;
}
if(head2 == null){
return head1;
}
head1 = reverse(head1);
head2 = reverse(head2);
ListNode node = new ListNode(-1);
ListNode tmp = node;
int carray = 0;//进位位数
while(head1 != null || head2 != null || carray != 0){
int val1 = (head1 == null) ? 0 : head1.val;
int val2 = (head2 == null) ? 0 : head2.val;
int num = val1 + val2 + carray;
carray = num / 10;
num %= 10;
tmp.next = new ListNode(num);
tmp = tmp.next;
if(head1 != null){
head1 = head1.next;
}
if(head2 != null){
head2 = head2.next;
}
}
return reverse(node.next);
}
}
解法二:借用栈
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head1 ListNode类
* @param head2 ListNode类
* @return ListNode类
*/
public ListNode addInList (ListNode head1, ListNode head2) {
// write code here
Stack<Integer> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
while(head1 != null){
stack1.push(head1.val);
head1 = head1.next;
}
while(head2 != null){
stack2.push(head2.val);
head2 = head2.next;
}
ListNode node = null;
ListNode tmp = null;
int carray = 0;
while(!stack1.empty() || !stack2.empty() || carray != 0){
int val1 = (stack1.empty()) ? 0 : stack1.pop();
int val2 = (stack2.empty()) ? 0 : stack2.pop();
int num = val1 + val2 + carray;
carray = num / 10;
num = num % 10;
node = new ListNode(num);
node.next = tmp;
tmp = node;
}
return tmp;
}
}
12.单链表的排序
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类 the head node
* @return ListNode类
*/
// 合并链表
public ListNode merge(ListNode head1,ListNode head2){
if(head1 == null && head2 == null){
return null;
}
ListNode node = new ListNode(-1);
ListNode tmp = node;
while(head1 != null && head2 != null){
if(head1.val < head2.val){
tmp.next = head1;
head1 = head1.next;
tmp = tmp.next;
}else{
tmp.next = head2;
head2 = head2.next;
tmp = tmp.next;
}
}
if(head1 != null){
tmp.next = head1;
}
if(head2 != null){
tmp.next = head2;
}
return node.next;
}
public ListNode sortInList (ListNode head) {
// write code here
if(head == null || head.next == null){
return head;
}
ListNode left = head;
ListNode mid = head.next;
ListNode right = head.next.next;
// 找到链表的中间节点
while(right != null && right.next != null){
left = left.next;
mid = mid.next;
right = right.next.next;
}
left.next = null;
// 合并分开的链表
return merge(sortInList(head),sortInList(mid));
}
}
13.判断一个链表是否是回文结构(过)
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类 the head
* @return bool布尔型
*/
public boolean isPail (ListNode head) {
// write code here
if(head == null || head.next == null){
return true;
}
ListNode fast = head;
ListNode slow = head;
// 找到中间节点slow
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
}
// 翻转中间节点后面的结点
ListNode cur = slow.next;
while(cur != null){
ListNode curNext = cur.next;
cur.next = slow;
slow = cur;
cur = curNext;
}
while(slow != head){
if(slow.val != head.val){
return false;
}
// 说明是由偶数个结点
if(head.next == slow){
return true;
}
head = head.next;
slow = slow.next;
}
// 说明是奇数个结点,且是回文
return true;
}
}
14.链表的奇偶重排(过)
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @return ListNode类
*/
public ListNode oddEvenList (ListNode head) {
// write code here
if(head == null || head.next == null){
return head;
}
ListNode cur = head;
ListNode curNext = cur.next;
ListNode tmp = curNext;
// 将奇数位和偶数位的结点分别组成一个新的链表
while(curNext != null && curNext.next != null){
cur.next = curNext.next;
cur = cur.next;
curNext.next = curNext.next.next;
curNext = curNext.next;
}
// 连接奇数和偶数排列后的结果
cur.next = tmp;
return head;
}
}
15.删除有序链表中重复的元素-I(过)
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @return ListNode类
*/
public ListNode deleteDuplicates (ListNode head) {
// write code here
if(head == null || head.next == null){
return head;
}
ListNode cur = head;
ListNode curNext = cur.next;
while(cur != null && curNext != null){
if(cur.val == curNext.val){
cur.next = curNext.next;
curNext = curNext.next;
}else{
cur = curNext;
curNext = cur.next;
}
}
return head;
}
}
16.删除有序链表中重复的元素-II(过)
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @return ListNode类
*/
public ListNode deleteDuplicates (ListNode head) {
// write code here
if(head == null || head.next == null){
return head;
}
ListNode node = new ListNode(-1);
node.next = head;
ListNode tmp = node;
ListNode cur = head;
boolean falg = false;
while(cur != null && cur.next != null){
if(cur.val == cur.next.val){
cur = cur.next;
falg = true;
}else{
// 当前结点与下一个节点的值不相等,且需要删除结点,需要修改指向
if(falg == true){
tmp.next = cur.next;
cur = cur.next;
falg = false;
}else{
// 当前结点与下一个节点的值不相等,但不需要删除结点
cur = cur.next;
tmp = tmp.next;
}
}
}
// 需要删除最后一个节点
if(falg == true){
tmp.next = null;
}
return node.next;
}
}
二、二分查找/排序
1.二分查找-1
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型一维数组
* @param target int整型
* @return int整型
*/
public int search (int[] nums, int target) {
// write code here
if(nums == null || nums.length == 0){
return -1;
}
int left = 0;
int right = nums.length - 1;
while(left <= right){
int mid = (left + right) /2;
if(nums[mid] < target){
left = mid + 1;
}else if(nums[mid] > target){
right = mid - 1;
}else{
return mid;
}
}
return -1;
}
}
2.二维数组中的查找
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param target int整型
* @param array int整型二维数组
* @return bool布尔型
*/
public boolean Find (int target, int[][] array) {
// write code here
if(array == null || array.length == 0){
return false;
}
int i = 0;
int j = array[0].length - 1;
while(i < array.length && j >= 0){
if(array[i][j] > target){
j--;
}else if(array[i][j] < target){
i++;
}else if(array[i][j] == target){
return true;
}
}
return false;
}
}
3.寻找峰值
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型一维数组
* @return int整型
*/
public int findPeakElement (int[] nums) {
// write code here
if(nums == null || nums.length == 0){
return -1;
}
int left = 0;
int right = nums.length - 1;
while(left < right){
int mid = (left + right) / 2;
// 右边的值往下不一定有山峰
if(nums[mid] > nums[right]){
right = mid;
}else{
// 右边的值往上一定有山峰
left = mid + 1;
}
}
return right;
}
}
4.数组中的逆序对
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型一维数组
* @return int整型
*/
public int mod = 1000000007;
// 计算逆序对的个数
public int reversePairs(int[] nums, int[] temp, int left, int right) {
if (left >= right) {
return 0;
}
int mid = (left + right) >> 1;
// 左边逆序对的个数
int leftReverse = reversePairs(nums, temp, left, mid);
// 右边逆序对的个数
int rightReverse = reversePairs(nums, temp, mid + 1, right);
// 两边排序完成后逆序对的个数
int countReverse = merge(nums, temp, left, mid, right);
return (leftReverse + rightReverse + countReverse) % mod;
}
// 此时[left,mid]和[mid + 1,right]是有序的
private int merge(int[] nums, int[] temp, int left, int mid, int right) {
for (int i = left; i <= right; i++) {
temp[i] = nums[i];
}
// 此时i 和 j 分别指向要合并的两个数组的第一个元素
int i = left;
int j = mid + 1;
int count = 0;
for (int k = left; k <= right; k++) {
// i == mid + 1说明左边的已经归并完成
if (i == mid + 1) {
nums[k] = temp[j];
j++;
} else if (j == right + 1 || temp[i] <= temp[j]) {
// j == right + 1说明右边的已经归并完成
// temp[i] <= temp[j]说明右边的数字大,就将左边的进行归并
nums[k] = temp[i];
i++;
} else {
// 将右边数组的元素进行归并且进行逆序对的统计
nums[k] = temp[j];
j++;
count += mid - i + 1;
}
}
return count % mod;
}
public int InversePairs (int[] nums) {
// write code here
int[] temp = new int[nums.length];
return reversePairs(nums, temp, 0, nums.length - 1);
}
}
public class Solution {
public int mod = 1000000007;
public int mergeSort(int left,int right,int[] nums,int[] temp){
if(left >= right){
return 0;
}
int mid = (left + right) >> 1;
int result = mergeSort(left,mid,nums,temp) + mergeSort(mid + 1,right,nums,temp);
result %= mod;
for(int i = left;i <= right;i++){
temp[i] = nums[i];
}
// 此时i 和 j 分别指向要合并的两个数组的第一个元素
int i = left;
int j = mid + 1;
for(int k = left;k <= right;k++){
// i == mid + 1说明左边的已经归并完成
if(i == mid + 1){
nums[k] = temp[j];
j++;
}else if(j == right + 1 || temp[i] <= temp[j]){
// j == right + 1说明右边的已经归并完成
// temp[i] <= temp[j]说明右边的数字大,就将左边的进行归并
nums[k] = temp[i];
i++;
} else{
// 将右边数组的元素进行归并且进行逆序对的统计
nums[k] = temp[j];
j++;
result += mid - i + 1;
}
}
return result % mod;
}
public int InversePairs(int[] array) {
int[] result = new int[array.length];
return mergeSort(0,array.length - 1,array,result);
}
}
5.旋转数组中的最小数字
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型一维数组
* @return int整型
*/
public int minNumberInRotateArray (int[] nums) {
// write code here
if(nums == null || nums.length == 0){
return -1;
}
int i = 0;
int j = nums.length - 1;
int mid = 0;
while(nums[i] >= nums[j]){
if(j - i == 1){
return nums[j];
}
mid = (i + j ) >> 1;
if(nums[i] == nums[mid] && nums[j] == nums[i]){
int result = nums[i];
for(int k = i;k < j;k++){
if(nums[k] < result){
result = nums[k];
}
}
return result;
}
if(nums[mid] >= nums[i]){
i = mid;
}else{
j = mid;
}
}
return nums[mid];
}
}
6.比较版本号
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 比较版本号
* @param version1 string字符串
* @param version2 string字符串
* @return int整型
*/
public int compare (String version1, String version2) {
// write code here
int length1 = version1.length();
int length2 = version2.length();
int start1 = 0;
int start2 = 0;
while(start1 < length1 || start2 < length2){
long num1 = 0;
// 将每个点号之前的字符串转化为整数,进行比较
while(start1 < length1 && version1.charAt(start1) != '.'){
num1 = num1 * 10 + version1.charAt(start1) - '0';
start1++;
}
start1++;//跳过点号
long num2 = 0;
while(start2 < length2 && version2.charAt(start2) != '.'){
num2 = num2 * 10 + version2.charAt(start2) - '0';
start2++;
}
start2++;//跳过点号
// version1 < version2
if(num1 < num2){
return -1;
}else if(num1 > num2){
// version1 > version2
return 1;
}
}
return 0;
}
}
三、二叉树
1.二叉树的前序遍历
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @return int整型一维数组
*/
public void preorder(ArrayList<Integer> list,TreeNode root){
if(root == null){
return;
}
list.add(root.val);
preorder(list,root.left);
preorder(list,root.right);
}
public int[] preorderTraversal (TreeNode root) {
// write code here
ArrayList<Integer> list = new ArrayList<>();
preorder(list,root);
int[] result = new int[list.size()];
for(int i = 0;i < result.length;i++){
result[i] = list.get(i);
}
return result;
}
}
2.二叉树的中序遍历
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @return int整型一维数组
*/
public void inorder(ArrayList<Integer> list,TreeNode root){
if(root == null){
return;
}
inorder(list,root.left);
list.add(root.val);
inorder(list,root.right);
}
public int[] inorderTraversal (TreeNode root) {
// write code here
ArrayList<Integer> list = new ArrayList<>();
inorder(list,root);
int[] result = new int[list.size()];
for(int i = 0;i < result.length;i++){
result[i] = list.get(i);
}
return result;
}
}
3.二叉树的后续遍历
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @return int整型一维数组
*/
public void postorder(ArrayList<Integer> list,TreeNode root){
if(root == null){
return;
}
postorder(list,root.left);
postorder(list,root.right);
list.add(root.val);
}
public int[] postorderTraversal (TreeNode root) {
// write code here
ArrayList<Integer> list = new ArrayList<>();
postorder(list,root);
int[] result = new int[list.size()];
for(int i = 0;i < result.length;i++){
result[i] = list.get(i);
}
return result;
}
}
4.求二叉树的层序遍历
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @return int整型ArrayList<ArrayList<>>
*/
public ArrayList<ArrayList<Integer>> levelOrder (TreeNode root) {
// write code here
ArrayList<ArrayList<Integer>> result = new ArrayList<>();
if(root == null){
return result;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
ArrayList<Integer> list = new ArrayList<>();
int n = queue.size();
while(n-- > 0){
TreeNode tmp = queue.poll();
list.add(tmp.val);
if(tmp.left != null){
queue.offer(tmp.left);
}
if(tmp.right != null){
queue.offer(tmp.right);
}
}
result.add(list);
}
return result;
}
}
5.按之字形顺序打印二叉树
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pRoot TreeNode类
* @return int整型ArrayList<ArrayList<>>
*/
public ArrayList<ArrayList<Integer>> Print (TreeNode pRoot) {
// write code here
ArrayList<ArrayList<Integer>> result = new ArrayList<>();
if(pRoot == null){
return result;
}
Stack<TreeNode> stack = new Stack<>();
Queue<TreeNode> queue = new LinkedList<>();
stack.push(pRoot);
boolean flag = true;
while(!stack.isEmpty()){
ArrayList<Integer> list = new ArrayList<>();
while(!stack.empty()){
TreeNode tmp = stack.pop();
list.add(tmp.val);
TreeNode first = (flag == true) ? tmp.left : tmp.right;
TreeNode second = (flag == true) ? tmp.right : tmp.left;
if(first != null){
queue.offer(first);
}
if(second != null){
queue.offer(second);
}
}
result.add(list);
while(!queue.isEmpty()){
stack.push(queue.poll());
}
flag = (flag == true) ? false : true;
}
return result;
}
}
6.二叉树的最大深度
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @return int整型
*/
public int maxDepth (TreeNode root) {
// write code here
if(root == null){
return 0;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int depth = 0;
while(!queue.isEmpty()){
int n = queue.size();
depth++;
for(int i = 0;i < n;i++){
TreeNode tmp = queue.poll();
if(tmp.left != null){
queue.offer(tmp.left);
}
if(tmp.right != null){
queue.offer(tmp.right);
}
}
}
return depth;
}
}
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @return int整型
*/
public int maxDepth (TreeNode root) {
// write code here
if(root == null){
return 0;
}
return Math.max(maxDepth(root.left),maxDepth(root.right)) + 1;
}
}
7.二叉树中和为某一值的路径
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @param sum int整型
* @return bool布尔型
*/
public boolean hasPathSum (TreeNode root, int sum) {
// write code here
if(root == null){
return false;
}
// 当前结点是叶子结点且路径的和为sum
if(root.left == null && root.right == null && sum - root.val == 0){
return true;
}
// 递归查看左右结点
return hasPathSum(root.left,sum-root.val) || hasPathSum(root.right,sum-root.val);
}
}
8.二叉搜索树与双向链表
import java.util.*;
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public TreeNode prev = null;
// 二叉搜索树中序遍历的结果就是有序的
public void ConvertChild(TreeNode root){
if(root == null){
return;
}
ConvertChild(root.left);
root.left = prev;
if(prev != null){
prev.right = root;
}
prev = root;
ConvertChild(root.right);
}
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree == null){
return null;
}
// 调整
ConvertChild(pRootOfTree);
// 从树的根结点向前找,直到左节点为空就说明是链表的头
TreeNode head = pRootOfTree;
while(head.left != null){
head = head.left;
}
return head;
}
}
9.对称的二叉树
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pRoot TreeNode类
* @return bool布尔型
*/
public boolean isSymmetricalChild(TreeNode root1,TreeNode root2){
if(root1 == null && root2 == null){
return true;
}
if(root1 == null || root2 == null || root1.val != root2.val){
return false;
}
return isSymmetricalChild(root1.left,root2.right) && isSymmetricalChild(root1.right,root2.left);
}
public boolean isSymmetrical (TreeNode pRoot) {
// write code here
return isSymmetricalChild(pRoot,pRoot);
}
}
10.合并二叉树
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param t1 TreeNode类
* @param t2 TreeNode类
* @return TreeNode类
*/
public TreeNode mergeTrees (TreeNode t1, TreeNode t2) {
// write code here
if(t1 == null){
return t2;
}
if(t2 == null){
return t1;
}
TreeNode root = new TreeNode(t1.val + t2.val);
root.left = mergeTrees(t1.left,t2.left);
root.right = mergeTrees(t1.right,t2.right);
return root;
}
}
11. 二叉树的镜像
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pRoot TreeNode类
* @return TreeNode类
*/
public TreeNode Mirror (TreeNode pRoot) {
// write code here
if(pRoot == null){
return null;
}
TreeNode tmp = pRoot.left;
pRoot.left = pRoot.right;
pRoot.right = tmp;
Mirror(pRoot.left);
Mirror(pRoot.right);
return pRoot;
}
}
12. 判断是不是二叉搜索树
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @return bool布尔型
*/
// 将pre初始化为int的最小值
public int pre = Integer.MIN_VALUE;
public boolean isValidBST (TreeNode root) {
// write code here
if(root == null){
return true;
}
// 向左递归
if(!isValidBST(root.left)){
return false;
}
// 如果前一个节点的值大于当前结点的值,返回false
if(root.val < pre){
return false;
}
// 存下当前结点的值,下一次递归就是当前结点的前一个节点
pre = root.val;
return isValidBST(root.right);
}
}
13.判断是不是完全二叉树
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @return bool布尔型
*/
public boolean isCompleteTree (TreeNode root) {
// write code here
if(root == null){
return true;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
boolean flag = false;
while(!queue.isEmpty()){
TreeNode tmp = queue.poll();
// 找到第一次出现空节点的位置
if(tmp == null){
flag = true;
continue;
}
// 如果flag为真,说明提前出现了叶子结点
if(flag){
return false;
}
queue.offer(tmp.left);
queue.offer(tmp.right);
}
return true;
}
}
14.判断是不是平衡二叉树
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pRoot TreeNode类
* @return bool布尔型
*/
// 计算树的深度
public int depth(TreeNode pRoot){
if(pRoot == null){
return 0;
}
return Math.max(depth(pRoot.left),depth(pRoot.right)) + 1;
}
public boolean IsBalanced_Solution (TreeNode pRoot) {
// write code here
if(pRoot == null){
return true;
}
int leftDepth = depth(pRoot.left);
int rightDepth = depth(pRoot.right);
// 左右子树之差不大于1
if(leftDepth - rightDepth > 1 || rightDepth - leftDepth > 1){
return false;
}
// 看左右子树是否是平衡二叉树
return IsBalanced_Solution(pRoot.left) && IsBalanced_Solution(pRoot.right);
}
}
15.二叉搜索树的最近公共祖先
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @param p int整型
* @param q int整型
* @return int整型
*/
public int lowestCommonAncestor (TreeNode root, int p, int q) {
// write code here
if (root == null) {
return -1;
}
if (root.val == p || root.val == q) {
return root.val;
}
int leftTree = lowestCommonAncestor(root.left, p, q);
int rightTree = lowestCommonAncestor(root.right, p, q);
// 要查询的公共结点的两个结点在root的两边
if (leftTree != -1 && rightTree != -1) {
return root.val;
}
// 要查询的公共结点的两个结点在root的左边
if (leftTree != -1) {
return leftTree;
}
// 要查询的公共结点的两个结点在root的右边
if (rightTree != -1) {
return rightTree;
}
return -1;
}
}
16.序列化二叉树
import java.util.*;
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
// 序列化
String Serialize(TreeNode root) {
if (root == null) {
return "#";
}
StringBuffer sb = new StringBuffer();
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
TreeNode tmp = queue.poll();
if (tmp == null) {
sb.append("#,");
} else {
sb.append(tmp.val + ",");
if (tmp.left != null) {
queue.offer(tmp.left);
} else {
queue.offer(null);
}
if (tmp.right != null) {
queue.offer(tmp.right);
} else {
queue.offer(null);
}
}
}
return new String(sb);
}
// 反序列化
TreeNode Deserialize(String str) {
if (str.equals("#")) {
return null;
}
String[] s = str.split(",");
TreeNode root = new TreeNode(Integer.parseInt(s[0]));
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int i = 1;
while(!queue.isEmpty()){
TreeNode tmp = queue.poll();
String left = s[i++];
String right = s[i++];
if(left.equals("#")){
tmp.left = null;
}else{
TreeNode leftTree = new TreeNode(Integer.parseInt(left));
tmp.left = leftTree;
queue.offer(leftTree);
}
if(right.equals("#")){
tmp.right = null;
}else{
TreeNode rightTree = new TreeNode(Integer.parseInt(right));
tmp.right = rightTree;
queue.offer(rightTree);
}
}
return root;
}
}
17.重建二叉树
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param preOrder int整型一维数组
* @param vinOrder int整型一维数组
* @return TreeNode类
*/
public TreeNode reConstructBinaryTreeChild(int[] preOrder,int preStart,int preEnd,int[] vinOrder,int vinStart,int vinEnd){
if(preStart > preEnd || vinStart > vinEnd){
return null;
}
TreeNode root = new TreeNode(preOrder[preStart]);
for(int i = vinStart;i <= vinEnd;i++){
if(vinOrder[i] == root.val){
root.left = reConstructBinaryTreeChild(preOrder,preStart + 1,i - vinStart + preStart,vinOrder,vinStart,i - 1);
root.right = reConstructBinaryTreeChild(preOrder,i - vinStart + preStart + 1,preEnd,vinOrder,i + 1,vinEnd);
}
}
return root;
}
public TreeNode reConstructBinaryTree (int[] preOrder, int[] vinOrder) {
// write code here
if(preOrder == null || vinOrder == null){
return null;
}
return reConstructBinaryTreeChild(preOrder,0,preOrder.length-1,vinOrder,0,vinOrder.length - 1);
}
}
18.输出二叉树的右视图
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值blank即可
*
* 求二叉树的右视图
* @param preOrder int整型一维数组 先序遍历
* @param inOrder int整型一维数组 中序遍历
* @return int整型一维数组
*/
// 根据前序遍历和中序遍历的结果构建二叉树
public TreeNode build(int[] preOrder, int preStart,int preEnd, int[] vinOrder, int vinStart, int vinEnd) {
if (preStart > preEnd || vinStart > vinEnd) {
return null;
}
TreeNode root = new TreeNode(preOrder[preStart]);
for (int i = vinStart; i <= vinEnd; i++) {
if (vinOrder[i] == root.val) {
root.left = build(preOrder, preStart + 1,i - vinStart + preStart, vinOrder, vinStart, i - 1);
root.right = build(preOrder, i - vinStart + preStart + 1,preEnd, vinOrder, i + 1, vinEnd);
}
}
return root;
}
// 层序遍历这棵二叉树将每一层的最右边的元素添加到顺序表中
public ArrayList<Integer> levelOrder(TreeNode root){
ArrayList<Integer> list = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
int size = queue.size();
for(int i = 0;i < size;i++){
TreeNode tmp = queue.poll();
if(tmp.left != null){
queue.offer(tmp.left);
}
if(tmp.right != null){
queue.offer(tmp.right);
}
// 将最右边的元素添加到list中
if(i == size - 1){
list.add(tmp.val);
}
}
}
return list;
}
public int[] solve (int[] preOrder, int[] inOrder) {
// write code here
if(preOrder == null || inOrder == null){
return null;
}
// 建树
TreeNode root = build(preOrder,0,preOrder.length - 1,inOrder,0,inOrder.length - 1);
// 获取右视图
ArrayList<Integer> list = levelOrder(root);
// 转换为数组输出
int[] result = new int[list.size()];
for(int i = 0;i < list.size();i++){
result[i] = list.get(i);
}
return result;
}
}