1、树的层次遍历
// 二叉树的层序遍历
public List<List<Integer>> levelOrder(TreeNode root) {
// 存储结果的数组
List<List<Integer>> res = new ArrayList<>();
if(root == null){
return res;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
List<Integer> level = new ArrayList<>();
int size = queue.size();
for(int i=0; i<size; i++){
TreeNode node = queue.poll();
level.add(node.val);
if(node.left != null) queue.offer(node.left);
if(node.right != null) queue.offer(node.right);
}
res.add(level);
}
return res;
}
2.求二叉树的最大深度
//最大深度
public int maxDepth(TreeNode root) {
int maxD = 0;
if(root == null){
return maxD;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
int size = queue.size();
for(int i=0; i<size; i++){
TreeNode treeNode = queue.poll();
if(treeNode.left != null) queue.offer(treeNode.left);
if(treeNode.right != null) queue.offer(treeNode.right);
}
maxD++; // 增加深度
}
return maxD;
}
2、N*N旋转
3、二叉树三种遍历
3.1前序遍历
//前序遍历
void preOrderTraversal(TreeNode root) {
if (root == null) {
return;
}
System.out.print(root.val + " ");
preOrderTraversal(root.left);
preOrderTraversal(root.right);
}
//非递归的前序遍历
void preOrderTraversalNor(TreeNode root) {
if (root == null) {
return;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.empty()) {
while (cur != null) {
stack.push(cur);
System.out.print(cur.val + " ");
cur = cur.left;
}
TreeNode top = stack.pop();
cur = top.right;
}
}
3.2中序遍历
//中序遍历
void inOrderTraversal(TreeNode root) {
if (root == null) {
return;
} else {
inOrderTraversal(root.left);
System.out.print(root.val + " ");
inOrderTraversal(root.right);
}
}
//非递归的中序遍历
void inOrderTraversalNor(TreeNode root) {
if (root == null) {
return;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.empty()) {
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
TreeNode top = stack.pop();
System.out.print(top.val + " ");
cur = top.right;
}
}
3.3后序遍历
//后序遍历
void poseOrderTraversal(TreeNode root) {
if (root == null) {
return;
} else {
poseOrderTraversal(root.left);
poseOrderTraversal(root.right);
System.out.print(root.val + " ");
}
}
//非递归的后序遍历
void poseOrderTraversalNor(TreeNode root) {
if (root == null) {
return;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode pre = null;
TreeNode cur = root;
while (cur != null || !stack.empty()) {
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
cur = stack.peek();
if (cur.right == null||pre==cur.right) {
TreeNode top = stack.pop();
System.out.print(top.val+ " ");
pre=cur;
cur=null;
} else {
cur=cur.right;
}
}
}
4.层次遍历
void levelOderTraversal(TreeNode root) {
Queue<TreeNode> q1 = new LinkedList<>();
if (root == null) {
return;
}
q1.offer(root);
while (!q1.isEmpty()) {
TreeNode top = q1.poll();
System.out.print(top.val + " ");
if (top.left != null) {
q1.offer(top.left);
}
if (top.right != null) {
q1.offer(top.right);
}
}
System.out.println();
}
5、堆排
//编写一个堆排序的方法
public static void heapSort(int[] arr) {
int length = arr.length - 1;
int temp = 0;
//利用循环 排成大顶堆 (叶子结点 小于父节点 满足a[i]>a[i*2+1]&&a[i]>a[i*2+2]条件 )
for (int i = arr.length / 2 - 1; i >= 0; i--) {
heapSort(arr, i, length);
}
for (; length > 0; length--) {
temp = arr[0];
arr[0] = arr[length];
arr[length] = temp;
heapSort(arr, 0, length);
}
}
/**
* 完成以i对应的非叶子节点的树 调整成大堆顶
*
* @param arr 待调整的数组
* @param i 表示非叶子结点在数组中的索引
* @param length 表示多少个元素进行调整
*/
public static void heapSort(int[] arr, int i, int length) {
int temp = arr[i];
for (int k = 2 * i + 1; k <length; k = k * 2 + 1) {
if (k + 1 < length && arr[k] < arr[k + 1]) {
k++;
}
if (arr[i] < arr[k]) {
arr[i] = arr[k];
i = k;
} else {
break;
}
}
arr[i] = temp;
}
6、快排
//快排实现方法
public static void quickRow(int[] array,int low,int high) {
int i,j,pivot;
//结束条件
if(low >= high) {
return;
}
i = low;
j = high;
//选择的节点,这里选择的数组的第一数作为节点
pivot = array[low];
while(i<j) {
//从右往左找比节点小的数,循环结束要么找到了,要么i=j
while(array[j] >= pivot && i<j) {
j--;
}
//从左往右找比节点大的数,循环结束要么找到了,要么i=j
while(array[i] <= pivot && i<j) {
i++;
}
//如果i!=j说明都找到了,就交换这两个数
if(i<j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
//i==j一轮循环结束,交换节点的数和相遇点的数
array[low] = array[i];
array[i] = pivot;
//数组“分两半”,再重复上面的操作
quickRow(array,low,i-1);
quickRow(array,i+1,high);
}
7、冒泡排序
int[] arr = {1,5,3,4,7,8,9,6,2,0};
for(int i = 0; i < arr.length-1; i++)
{
//外循环是控制排序的次数N-1, 每次循环结束确定一个最大值
for(int j = 0; j < arr.length - 1 - i; j++) // 内循环是比较的次数N-i
{
if(arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
7.1直接插入排序
public void insertSort(int[] array){
for(int i=1;i<array.length;i++)//第0位独自作为有序数列,从第1位开始向后遍历
{
if(array[i]<array[i-1])//0~i-1位为有序,若第i位小于i-1位,继续寻位并插入,否则认为0~i位也是有序的,忽略此次循环,相当于continue
{
int temp=array[i];//保存第i位的值
int j = i - 1;
while(j>=0 && temp<array[j])//从第i-1位向前遍历并移位,直至找到小于第i位值停止
{
array[j+1]=array[j];
j--;
}
array[j+1]=temp;//插入第i位的值
}
}
}
8.进制转换
public fun converse(num:Int, radix:Int ) {
var sb = StringBuffer();
var temp=num
while (temp != 0) {
sb.append(temp % radix);
temp /= radix;
}
System.out.println(sb.reverse().toString());
}
9、反转连接
public ListNode reverseList(ListNode head) {
ListNode prev = null; //表示当前节点的前一个节点,初始值为null
ListNode temp = head; //表示当前节点,初始值为head
ListNode next; //表示当前节点的下一个节点
while(temp != null){
//先提前保存当前节点的下一个节点
next = temp.next;
//将当前节点的next指针指向当前节点的前一个节点
temp.next = prev;
//更新prev,即将temp赋值给prev
prev = temp;
//更新temp,即将next赋值给temp
temp = next;
}
return prev;
}
10、汉诺斯牌移动次数
static int count=0;//用于计数
public static void main(String[] args) {
f(5);
System.out.println(count);
}
public static void f(int n) {
if(n==1) {//出口,只剩一个圆盘时只需要再移动一步,然后return整个函数
count++;
return;
}
f(n-1);//把n-1个盘子移动到辅助柱
count++;//把最下面最大的盘子移动到C柱,因为只有一步所以,步骤++
f(n-1);
}
public static int getWalkNum2(int n) {
if (n <= 2) {
return n;
}
int first = 1, second = 2;
int third = 0;
for (int i = 3; i <= n; i++) {
third = first + second;
first = second;//计算完third值之后将second值再赋值给first
second = third;//计算完third值之后将third值再赋值给second,方便下一轮计算
}
return third;
}
10、有n步台阶,一次只能上1步或2步,共有多少种走法
public static int getWalkNum(int n) {
if (n <= 2) {
return n;
}
return getWalkNum(n - 1)+ getWalkNum(n - 2);
}
11.不用加减法计算两个数的和
static int sum(int a,int b)
{
/**
先计算进位结果 c
然后计算无进位结果 a
如果有进位,设置给b,进入下一次计算
*/
while (b != 0) {
int c = (a&b)<<1;
a = a^b;
b = c;
}
return a;
}
后面将持续更新。。。。。。。。。。。。。。。。。。。。。。。。。。。