一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第28天,点击查看活动详情。
剑指 Offer 67. 把字符串转换成整数
思路
(模拟) O(n)
先来看看题目的要求:
- 1、忽略所有行首空格,找到第一个非空格字符,可以是
‘+/−’表示是正数或者负数,紧随其后找到最长的一串连续数字,将其解析成一个整数。 - 2、整数后可能有任意非数字字符,请将其忽略。
- 3、如果整数大于
INT_MAX,请返回INT_MAX;如果整数小于INT_MIN,请返回INT_MIN;
具体过程:
-
1、定义
k = 0,用k来找到第一个非空字符位置。 -
2、使用
flag记录数字的正负性,false表示正号,true表示负号。 -
3、使用
res来存贮结果,当str[k]为数字字符时进入while循环,执行res = res * 10 +str[k] - '0'。- 根据
flag判断,如果res大于INT_MAX,则返回INT_MAX;如果res * -1小于INT_MIN,则返回INT_MIN;
- 根据
-
4、计算
res。
时间复杂度分析: 字符串长度是 n,每个字符最多遍历一次,所以总时间复杂度是 O(n)。
c++代码
class Solution {
public:
int strToInt(string str) {
int k = 0;
bool flag = false;
while (k < str.size() && str[k] == ' ') k++;
if (str[k] == '-') flag = true, k++;
else if (str[k] == '+' ) k++;
long long res = 0;
while(k < str.size() && str[k] >= '0' && str[k] <= '9'){
res = res * 10 + str[k] - '0';
if (res > INT_MAX && !flag) return INT_MAX;
if (res * -1 < INT_MIN && flag) return INT_MIN;
k++;
}
if(flag) res *= -1;
return res;
}
};
剑指 Offer 68 - I. 二叉搜索树的最近公共祖先
思路
(递归) O(n)
二叉搜索树的定义:左子树p->val小于根节点root->val,根节点值小于右子树q->val。
因此可以利用二叉搜索树的特点,如果p、q的值都小于root,说明p,q 肯定在root的左子树中;如果p,q都大于root,说明肯定在root的右子树中,如果一个在左一个在右,则说明此时的root记为对应的最近公共祖先。
递归过程中只有3种情况:
p->val <= root->val && q->val >=root->val(结束,返回root值即结果)p->val > root->val && q->val > root->val(root->right递归)p->val > root->val && q->val > root->val(root->left递归)
时间复杂度分析: 每个节点最多只会被遍历一次,因此时间复杂度为O(n)。
c++代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(!root) return NULL;
if(p->val < root->val && q->val < root->val) return lowestCommonAncestor(root->left, p, q);
if(p->val > root->val && q->val > root->val) return lowestCommonAncestor(root->right, p, q);
return root;
}
};
剑指 Offer 68 - II. 二叉树的最近公共祖先
思路
(递归) O(n)
p和q这两个节点共有三种情况: 1、p 和 q在root的子树中,且位于两侧。 2、p = root 且 q 在 root 的左或右子树中。 3、q = root 且 p 在 root 的左或右子树中。
考虑在左子树和右子树中查找这两个节点,如果两个节点分别位于左子树和右子树,则最低公共祖先为自己(root),若左子树中两个节点都找不到,说明最低公共祖先一定在右子树中,反之亦然。考虑到二叉树的递归特性,因此可以通过递归来求得。
时间复杂度分析: 需要遍历树,复杂度为 O(n)。
c++代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(!root) return NULL; //没有找到,返回null
if(root == p || root == q) return root; //找到其中之一,返回root
TreeNode* left = lowestCommonAncestor(root->left, p, q); //返回左子树查找节点
TreeNode* right = lowestCommonAncestor(root->right,p ,q); //返回右子树查找节点
if(left && right) return root;
if(left) return left;
else return right;
}
};