48天笔试强训——第21天

96 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 8 天,点击查看活动详情


选择题

image.png

首先要遍历比较链表中节点的值与新节点的大小,遍历一遍链表的时间复杂对位O(n)

image.png

只需要p->next指向p->next->next

image.png

频繁使用头插和尾插,必须要是双向的,那么答案选A

image.png

根据题目的描述,很显然是头插,先处理插入的那个节点,即p->next=TOp->next;最后在链接头指针,即:Top->next=p

image.png

对头一定要进行修改的,那么队尾需不需要呢?要的,因为如果队列里面就一个元素,那么此时出队,也要进行修改队尾的指针。

image.png

设叶子节点的个数为x,那么度为2的节点的个数为x-1,度为1的节点为y(0/1)个, 公式:2n=x+x-1+y=2x-1+y,为了保证有结果,此次y取1,所以x为n。选A

image.png

v是叶子节点,删除之后,该二叉树还是满足二叉树排序树的性质;重新插入之后,T1和T3还是相同的。 当v不是叶子节点的话,删除之后,T1就不是二叉排序树,需要进行调整,调整之后原先节点的相对位置就发生了改变,再插入v之后,T1和T3就不同了。

image.png

二叉排序树是不满足这种性质,二叉树的最左边、最右边路径才满足这种性质,随便找个具体的例子就可以证明。无论是大堆还是小堆,节点和它的孩子节点具有严格的大于或者小于关系,所以堆是满足的。 哈夫曼树要考虑需不需要算上它合成的节点。

image.png

对于哈希问题,哈希冲突是无法避免的。所以要处理好散列文件不仅要选择好的散列函数,还要解决哈希冲突。

image.png

堆顶的元素和堆尾的元素进行交换,然后对除堆尾的元素进行堆的向下调整。所以选C

编程题

洗牌

通过题目的描述,我们可以看出,可以先放左手的,然后放右手的,来回循环,直到放完。 我们可以发现一个结论: 第一次洗好之后的牌(t)和原来的牌(v)的下标存在一定的规律。 当t的下标为偶数的时候:t[x]=v[x/2]; 当t的下标为奇数的时候:t[x]=v[n+i++], x从0开始依次遍历t,i也是从0开始

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    int T;
    cin>>T;
    for(int i=0;i<T;i++)
    {
        int n,k;
        cin>>n>>k;
        vector<int> v(2*n),t(2*n);
        for(int j=0;j<2*n;j++)
        {
            cin>>v[j];
        }
        while(k--)
        {
            int p=0;
            for(int j=0;j<2*n;j++)
            {
                if(j%2==0)
                t[j]=v[j/2];
                else
                {
                    t[j]=v[n+p];
                    p++;
                }
            }
            v=t;
        }
        for(auto x:v)
        cout<<x<<' ';
        cout<<endl;
    }
    return 0;
}

MP3光标位置

这道题目主要要注意边界问题,当向上调的时候,如果在第一首就要变成最后一首,同时改变屏幕显示的歌曲;当向下调的时候,如果处于最后一首,就要变成第一首,同时改变屏幕显示的歌曲;除此之外,如果下调或者上调的时候,当前的歌曲不在显示的歌曲里面的时候,也要改变屏幕中显示的歌曲。

#include <iostream>
#include <string>
using namespace std;
int main()
{
    int n;
    cin>>n;
    string arr;
    cin>>arr;
    int left=1,right=4,cur=1;
    if(n<4)
    {
        right=n;
    }
    for(int i=0;i<arr.size();i++)
    {
        if(arr[i]=='U')
        {
            cur--;
            if(cur<=0){
                cur=right=n;
                left=(right-3)<=0?1:right-3;
            }
            else if(cur<left){
                left=cur;
                right--;
            }
        }
        else
        {
            cur++;
            if(cur>n){
                cur=left=1;
                right=(left+3)>right?n:left+3;
            }
            else if(cur>right){
                right=cur;
                left++;
            }
        }
    }
    while(left<=right)
    {
        cout<<left<<' ';
        left++;
    }
    cout<<endl;
    cout<<cur<<endl;
    return 0;
}