不多说,就是干
数字在排序数组中出现的次数
题目描述:统计一个数字在排序数组中出现的次数。
题目分析:这道题如果用count函数的话会超级简单,但是这样就失去了这道题的意义。
class Solution {
public:
int GetNumberOfK(vector<int> data ,int k) {
return count(data.begin(),data.end(),k);
}
};
既然是排序数组的话,其实也很容易,首先用二分法找到这个数组中的这个数,然后向前向后找,加起来就好了。只要遇到排序数组就二分法就完了。但是垃圾编译器会超空间,这里我就不细说了。
class Solution {
public:
int weizhi;
void dian(vector<int>data, int k, int low, int high) { //利用二分法找到存在的位置
if (low == high)return;
int mid = (low + high) / 2;
if (data[mid] == k) {
weizhi = mid;
return;
}
if (data[mid] < k) {
dian(data, k, mid, high);
}
else {
dian(data, k, low, mid);
}
}
int GetNumberOfK(vector<int> data, int k) { //向前向后找相同数字
int number = data.size();
dian(data, k, 0,number-1);
int prenumber = 0;
int nextnumber = 0;
int i = weizhi-1;
int j = weizhi+1;
if (i >= 0) {
while (data[i] == k && i>=0) {
prenumber++;
i--;
}
}
if (j < number) {
while (data[j] == k && j < number) {
nextnumber++;
j++;
}
}
return 1 + prenumber + nextnumber;
}
};
二叉树的深度
题目描述:输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
题目分析:就是找遍历找深度,仅此而已。
class Solution {
public:
int maxdepth = 0;
void Treebianli(TreeNode* pRoot, int k) {
if (pRoot == nullptr) {
if (k > maxdepth) {
maxdepth = k;
}
return;
}
Treebianli(pRoot->left, k+1);
Treebianli(pRoot->right, k+1);
}
int TreeDepth(TreeNode* pRoot)
{
if (pRoot == nullptr)return 0;
Treebianli(pRoot, 0);
return maxdepth;
}
};
平衡二叉树
题目描述:输入一棵二叉树,判断该二叉树是否是平衡二叉树。
题目分析:任何二叉树的题,本质上都是递归求解,否者都会贼难。
class Solution {
public:
bool IsBalanced_Solution(TreeNode* pRoot) {
if(pRoot == nullptr) {
return true;
}
return abs(maxDepth(pRoot->left) - maxDepth(pRoot->right)) <= 1 &&
IsBalanced_Solution(pRoot->left) && IsBalanced_Solution(pRoot->left);
}
int maxDepth(TreeNode* root) {
if(root == nullptr) {
return 0;
}
return 1 + max(maxDepth(root->left), maxDepth(root->right));
}
};
数组中只出现一次的数字
题目描述:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
题目分析:当然这个题遍历也是可以的,但是很傻,面试官肯定不会喜欢这个方案,所以必须采用异或的方法。如果一个整形数组中只有一个数字出现了1次,应该用异或是很容易实现的。出现两个的话就先找两个异或结果,再根据这个结果将整个数组分成两部分,然后在对分组结果进行处理,之后分别在两个数组中找到只出现了一次的数。
class Solution {
public:
int differpoint(int count) { //找到两个单独数的异或值的最小位不同
int point = 1;
while (1) {
if (count & 1 == 1)break;
count=count >> 1;
point=point << 1;
}
return point;
}
void FindNumsAppearOnce(vector<int> data, int* num1, int *num2) {
if (data.size() == 0)return;
if (data.size() == 1) { *num1 = data[0]; return; }
int count=0;
for (int i = 0; i < data.size(); i++) {
count = count ^ data[i]; //找到两个单独数的异或值
}
int differ = differpoint(count);
vector<int>cun1;
vector<int>cun2;
for (int i = 0; i < data.size(); i++) {
if ((data[i] & differ) == differ) { //分别将数据放在不同的篮子中
cun1.push_back(data[i]);
}
else {
cun2.push_back(data[i]);
}
}
int word1 = 0;
int word2 = 0;
for (int i = 0; i < cun1.size(); i++) {
word1 = word1 ^ cun1[i];
}
for (int i = 0; i < cun2.size(); i++) {
word2 = word2 ^ cun2[i];
}
*num1 = word1;
*num2 = word2;
}
};
和为S的连续正数序列
题目描述:小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序
题目分析:最简单的方法就是用两个指针走,判断两个指针之间的数是否符合结果。
class Solution {
public:
vector<vector<int> > FindContinuousSequence(int sum) {
vector<vector<int> > res;
int begin = 1, end = 2;
int mid = (sum+1)/2;
int cur = begin+end;
while(begin<mid && end < sum){ //终止条件,开始值大于等于半值或者中值大于等于sum
while(cur>sum){ //大于sum
cur-=begin;
begin++;
}
if(cur == sum){ //等于sum
vector<int> tmp;
for(int i = begin;i<=end;i++) tmp.push_back(i);
res.push_back(tmp);
}
end++; //小于sum
cur+=end;
}
return res;
}
};