选择题
1、采用递归方式对顺序表进行快速排序,下列关于递归次数的叙述中,正确的是()
A 递归次数与初始数据的排列次序无关
B 每次划分后,先处理较长的分区可以减少递归次数
C 每次划分后,先处理较短的分区可以减少递归次数
D 递归次数与每次划分后得到的分区处理顺序无关
正确答案 D:递归次数取决于递归树,而递归树取决于轴枢的选择。树越平衡递归次数越少。分区的长短处理顺序,影响的是递归时对栈的使用内存,而不是递归次数
2、一棵完全二叉树第六层有9个叶结点(根为第一层),则结点个数最多有()
A 112
B 111
C 107
D 109
正确答案 D:根据二叉树的性质,第i层上的结点数最多为2^i(i >= 0,所以第一层为i=0)个,所以第六层的结点数最多为2^5=32个,根据题意第六层有9个叶子结点,推测出还有第七层,所以第六层结点数减去9个叶子结点,剩下的23个结点都有左右子树,故第七层有23*2=46个结点,总的结点数=1+2+4+8+16+32+46=109个
编程题
题目1:
解题思路:此题用到了摩尔投票算法,在此之前有写过该算法,题目类似
算法 摩尔投票算法(图解例题)
代码:
class Gift {
public:
int getValue(vector<int> gifts, int n)
{
int res = gifts[0];
int count = 1;
for (int i = 0; i < n; ++i)
{
if (count == 0)
{
res = gifts[i];
}
else if (gifts[i] == res)
count++;
else if (gifts[i] != res)
count--;
}
count = 0;
for (int i = 0; i < n; ++i)
{
if (gifts[i] == res)
++count;
}
if (count < n/2)
return 0;
return res;
}
};
题目2:
解题思路:动态规划,我们有3种操作,删除、添加或替换。我们可以借助一个矩阵图来理解
我们将二维矩阵初始化,每个矩阵位置上的值为要操作的次数,例如当str1只有a时,需要看字符串的个数和是否相同,向左取值+1表示str1的删除操作,向上取值+1表示str2的删除操作,取对角线的值则表示替换操作,当字符相同不需要替换,不需要+1.当字符不同时,无论那种操作都需要+1
代码:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int minDistance(const string& str1, const string& str2)
{
if (str1.empty() || str2.empty())
return max(str1.size(), str2.size());
int len1 = str1.size();
int len2 = str2.size();
vector<vector<int>> f(len1+1, vector<int>(len2+1, 0));
//初始化距离
for (int i = 0; i <= len1; ++i)
f[i][0] = i;
for (int j = 0; j <= len2; ++j)
f[0][j] = j;
for (int i = 1; i <= len1; ++i)
{
for (int j = 1; j <= len2; ++j)
{
if (str2[j - 1] == str1[i - 1])
{
f[i][j] = 1 + min(f[i-1][j], f[i][j-1]);//增加或删除
//字符相同,距离不发生变化
f[i][j] = min(f[i][j], f[i-1][j-1]);//替换
}
else
{
f[i][j] = 1 + min(f[i-1][j], f[i][j-1]);//增加或删除
//字符不相同,距离+1
f[i][j] = min(f[i][j], 1 + f[i-1][j-1]);//替换
}
}
}
return f[len1][len2];
}
int main()
{
string str1;
string str2;
while (cin >> str1 >> str2)
{
cout << minDistance(str1, str2) << endl;
}
return 0;
}