算法技巧篇
前言
本次算法入门训练主要训练以下三个内容:
- 以特殊数据结构为载体的算法结构,比如:数组、链表、栈、二叉树等
- 以考察常见算法思想基础的算法题,比如:动态规划、贪心、回溯等
- 基于某种场景包装下的1和2
提示:以下是本篇文章正文内容
内容
第一题:二叉树的深度
解题思路:这题有两种做法:1.直接使用二叉树的构建方式递归,2.利用二叉树的层序遍历思路,每一层一个深度。
OJ链接:第一题
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
import java.util.*;
public class Solution {
public int TreeDepth(TreeNode root) {
//层序遍历的思路实现
if(root == null){
return 0;
}
Queue<TreeNode> que = new LinkedList<>();
que.offer(root);
//每层是一个深度
int ret = 0;
while(!que.isEmpty()){
ret++;
int size = que.size();
//把每层的出完后停止
for(int i = 0; i < size; i++){
//出的同时也可以入
TreeNode tmp = que.poll();
if(tmp.left != null){
que.offer(tmp.left);
}
if(tmp.right != null){
que.offer(tmp.right);
}
}
}
return ret;
}
}
//{
// 1.
// return 1+Math.max(TreeDepth(root.left),TreeDepth(root.right)
//}
第二题:数组中只出现一次的数字
解题思路:这题的基础版本是只有一个不同的数字,解决基础版本我们只需要全体数据异或一次就行,但是如果找两个不同的数字,就需要把全体数据异或完的那个值一定不为零,然后找到其为1的比特位,最低位最高位都行,找按照有无这个比特位进行分组,就把两个不同的数字分开了,然后再异或就可以找出这两个数字。
OJ链接:第二题
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
if(array == null || array.length == 0){
return;
}
//整体数据全部异或0,得出一个值
int result = 0;
for(int i = 0; i < array.length; i++){
result ^= array[i];
}
//找到这个值的比特位为1的第一个位置,从高到低
int size = Integer.SIZE;
int flg = 1;
while(size >= 0){
size--;
if(((flg << size) & result) != 0){
flg <<= size;
break;
}
}
//分组
for(int i = 0; i < array.length; i++){
if((array[i] & flg) == 0){
//分组的同时直接异或
num1[0] ^= array[i];
}else{
num2[0] ^= array[i];
}
}
}
}
第三题:和为S的连续正数序列
解题思路:滑动窗口,通过两个指针来确定窗口的范围,再根据窗口范围之和来移动窗口,可以画图理解一下。
OJ链接:第三题
import java.util.ArrayList;
public class Solution {
public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
ArrayList<ArrayList<Integer>> ret = new ArrayList<>();
//定义两个指针来确定范围
int start = 1;
int end = 2;
//至少包括两个数
while(start < end){
//求这个范围的值
int result = (start + end) * (end - start + 1) / 2;
//如果相等加入返回集中
if(result == sum){
ArrayList<Integer> list = new ArrayList<>();
//[]
for(int i = start; i <= end; i++){
list.add(i);
}
ret.add(list);
//某段序列符合后,缩小范围再查找
start++;
}else if(result < sum){
//如果小于 范围向后扩大
end++;
}else{
//如果大于 范围向后缩小
start++;
}
}
return ret;
}
}
总结
以上就是今天练习的内容,今天的二三题的代码虽然不多但是如果思想没有相通还是比较困难的,第三题就是练习的第三种类型在场景中提取学的算法思想,比较看阅读理解能力,要多多练习。