目录
1.旋转数组的最小数字
二分查找有序数组中的数字,有序数组的旋转数组也可以二分找
如果left<=right 那么相遇进去之后只能返回left ,考虑一下最后mid=left=right=0;如果进去了,right--直接变成-1,不可能返回下标-1的元素
left<right,不需要担心这个问题,直接返回下标left/right元素
class Solution {
public:
//默认区间升序
int minNumberInRotateArray(vector<int> rotateArray) {
int left = 0, right = rotateArray.size() - 1; //左右区间
while (left < right) //条件判断,让相遇的时候直接出来
{
int mid = (left + right) / 2; //中间点
if (rotateArray[mid] < rotateArray[right]) //mid更小说明最小在左区间
right = mid;
else if (rotateArray[mid] > rotateArray[right]) //mid更大说明最小在右区间
left = mid + 1;
else right--; //没有比较出大小,缩小搜索范围继续找
}
return rotateArray[left]; //相遇点,返回left/right
}
};
2.比较版本号
其实看他描述的很复杂,就是挨个比较每个.前后的数字大小
int compare(string version1, string version2) {
// write code here
int p = 0, q = 0, n1 = version1.size(), n2 = version2.size(); //p,q代表两个版本号的起始(遍历)下标,
int t1 = 0, t2 = 0; //表示当前数值,比如1.1和1.21, 第一次比较t1=1,t2=1,第二次t1=1,t2=21
while (p < n1 || q < n2) //任意一个不结束都要再比较,1和1.1.1,要一直比较到1.1.1遍历结束
{
t1 = 0, t2 = 0; //每次都清空之前的
while (p < n1 && version1[p++] != '.') //走到.停止
{
t1 = t1 * 10 + version1[p - 1] - '0'; //需要进位的,这个是固定写法,自己顺一遍就知道为什么这样
}
while (q < n2 && version2[q++] != '.')
{
t2 = t2 * 10 + version2[q - 1] - '0';
}
if (t1 < t2) return -1; //在这一部分能比较出大小就直接返回
if (t1 > t2) return 1;
}
return 0;
}
3.二叉树的前序遍历
void _preorderTraversal(TreeNode* root, vector<int>& v)
{
if (!root) return;
v.push_back(root->val); //根
_preorderTraversal(root->left, v); //左子树
_preorderTraversal(root->right, v); //右子树
}
vector<int> preorderTraversal(TreeNode* root) {
// write code here
vector<int> v; //需要一个数组保存每个节点的值
_preorderTraversal(root, v); //带着数组遍历
return v;
}
4.中序遍历
直接写就好啦,只是变成 左子树 根 右子树
void _inorderTraversal(TreeNode* root,vector<int> &v)
{
if(!root) return;
_inorderTraversal(root->left,v);
v.push_back(root->val);
_inorderTraversal(root->right,v);
}
vector<int> inorderTraversal(TreeNode* root) {
// write code here
vector<int> v;
_inorderTraversal(root, v);
return v;
}
5.后序遍历
void _postorderTraversal(TreeNode* root,vector<int> &v)
{
if(!root) return;
_postorderTraversal(root->left,v);
_postorderTraversal(root->right,v);
v.push_back(root->val);
}
vector<int> postorderTraversal(TreeNode* root) {
// write code here
vector<int> v;
_postorderTraversal(root, v);
return v;
}
6.层序
第一个方法:前序递归
depth不是累加的所以不需要传引用;
void level(vector<vector<int> >& ans, TreeNode* root, int depth) {
if (root == NULL)
return;
if (ans.size() > depth)
ans[depth].push_back(root->val);
else {
vector<int> v;
v.push_back(root->val);
ans.push_back(v);
}
level(ans, root->left, depth + 1);
level(ans, root->right, depth + 1);
}
vector<vector<int> > levelOrder(TreeNode* root) {
// write code here
vector<vector<int> > ans;
level(ans, root, 0);
return ans;
}
第二个常规方法,队列
后面几层也是这样的
vector<vector<int> > levelOrder(TreeNode* root)
{
vector<vector<int>> vv;//二维数组
if (!root) //空树直接返回
return vv;
queue<TreeNode*> q; //用队列保留数据
q.push(root); //把根尾插
int size = 1; //记录队列的数据个数
while (!q.empty()) //空队列说明数的数值都保存到数组了
{
vector<int> v; //保存每一层的元素值
while (size--) //每转移一次就减少一个队列的元素个数
{
TreeNode* tmp = q.front(); //取队头数据
v.push_back(tmp->val); //尾插这个节点的val
q.pop(); //头删,导入之后就没用了
//带入下一层的节点
if (tmp->left) //左节点不为空
q.push(tmp->left); //插入左节点
if (tmp->right)
q.push(tmp->right);
}
size = q.size();//size更新
vv.push_back(v);//把整个这层的数组插入到二维数组
}
return vv;
}