目录
选择题
Q1 下面给出的四种排序法中( )排序法是不稳定性排序法
A.插入排序
B.冒泡排序
C.归并排序
D.堆,希尔排序,快速排序
我认为快速判断排序算法是否稳定的一个粗略的标准就判断在两个数值比相等时,是否可以不交换。
像堆,希尔,快速,都是一种 “近似无序” 的顺序处理数组中的值进行排序
堆,因为有向上/下调整算法,所以这个数值是否交换无法把握
希尔需要预排序,这个阶段就没法把握相同数值是否交换。
快速排序,需要先选一个标记元素去分割整个数组中元素。这样就会出现相同元素交换的问题
答案:D
Q2 对数据序列 { 15,9,7,8,20,-1,4 } 进行排序,进行一趟后数据的排序变为 { 9,15,7,8,20,-1,4 } ,则采用的是( )算法
A.直接选择排序
B.冒泡排序
C.直接插入排序
D.希尔排序
观察一趟排序后和一趟排序前的数组顺序,仅仅只有前两个元素的位置发生了变化。
- 直接选择排序:会选择出第一个元素以外的最小的元素进行交换位置,很明显 - 9不是最小的
- 冒泡排序:一趟排序之后,会将最大或者最小的元素放置在数组的左边或者右边,这个情况也不符合
- 希尔排序,其是跨数据进行预排序,者仅仅改变了相邻两个的元素的位置,也不符合
答案:C
Q3 某学生信息表,设一组表示成绩的关键字序列 (24,15,32,28,19,10,40) 采用直接插入排序时,当插入记录 19 到有序表时,为找插入位置需比较次数为( )
A.2
B.3
C.4
D.5
当直接插入排序到元素19时的元素排序 {15,24,28,32,19,10,40}
元素19需要和元素15,24进行比较即可插入,所以需要比较2次
答案:A
Q4 最坏情况下 insert sort , quick sort , merge sort 的复杂度分别是多少?( )
A. O(nn), O(nlogn), O(nn)
B. O(nn),O(nn),O(nlogn)
C. O(n*n),O(nlogn),O(nlogn)
D. O(nlogn),O(nlogn),O(nlogn)
答案:B
Q5 关于堆排序复杂度分析的叙述中正确的是( )
A.堆排序的时间复杂度为 O(nlogn)
B.整个构建堆的时间复杂度为 O(n)
C.堆排序的空间复杂度为 O(1)
D.堆排序是一种不稳定的排序算法
对堆进行排序时,需要堆每一个非叶子节点进行向下调整算法,所以是n/2 * logn,时间复杂度为O(nlogn)
堆排序中构建堆的时间复杂度请看2022暑期复习-Day1
中的Q5
堆排序在数组中操作不会创建其他空间
答案:ABCD
编程题
Q6
由于仅有小写字母,所以只需创建一个26个大小的数组进行桶计数即可,分别遍历两个字符串,一个字符桶计数后加1,另一个桶计数后减一,最后在统计数组中的元素。
class Solution {
public:
bool checkAlmostEquivalent(string word1, string word2) {
int arr[26] = {0};
for(int i=0;i<word1.size();i++)
{
arr[word1[i]-'a'] += 1;
}
for(int i = 0;i<word2.size();i++)
{
arr[word2[i]-'a'] -=1;
}
for(int i=0;i<26;i++)
{
if(abs(arr[i])>3)
return false;
}
return true;
}
};
Q7
这个明显需要利用栈的先入后出的思想。
一次遍历字符串,分别使用两个栈来统计数字和字符串。
使用一个标记符作为字符串栈中的标志位
当遍历到 ‘ ] ’时,就进行处理扩充的字符,然后放回栈中,因为不确定这个字符会不会继续被扩充,标志位就是 ‘[’
该算法,时间复杂度O(N)
class Solution {
public:
string decodeString(string s) {
stack<string> st1;
stack<int> st2;
int i = 0;
int len = s.size();
int flag = 0;
int ge = 0;
while (i < len)
{
if (isdigit(s[i]))
{
ge = ge * 10 + s[i] - '0';//防止出现多位数
if (!isdigit(s[i + 1]))
{
st2.push(ge);
ge = 0;
}
}
else if (s[i] == '[')
{
st1.push("[");//做一个标志位
}
else if (isalpha(s[i]))
{
string tmp = "";
tmp.push_back(s[i]);
st1.push(tmp);
}
else if (s[i] == ']')
{
string t1 = "";
string t2 = "";
while (st1.top() != "[")//提取字符用于扩充
{
t1.insert(0, st1.top());
st1.pop();
}
if(!st1.empty()&&st1.top() == "[")//一次],处理一次[
st1.pop();
int count = st2.top();
st2.pop();
while (count > 0)//字符扩充
{
t2 += t1;
count--;
}
st1.push(t2);
}
i++;
}
string ret = "";
while (!st1.empty())//依次拼接栈中所有字符串
{
ret.insert(0, st1.top());
st1.pop();
}
return ret;
}
};