文章目录
- 网友1
- 5) maybe是贪心?问你有140g糖,要称出来64g,你有7g的砝码和2g的砝码各1个,问你最少称多少次能称出来。
- 6) maybe二分查找?有100个杯子,有1个重量和其他的不同,问你最少称多少次能找出来
- 7) 【最后一道填空】有两个栈,分别是接收序列(容量P)和中转序列(容量Q),P<Q,需要满足先进接收序列的机器人先出来工作(先进先出),条件是进了中转序列后不能返回接收序列。问你通道(序列)满的时候,两个通道容纳的最多的机器人和最少的机器人
- 8) 有5个人,分别是a b c d e,按照上述顺序顺时针就坐成圆圈,他们每个人都给(向左邻投票的人)投票(每个人只能投一票),结果最后所有人得票都一样,问你他们是怎么投票的
- 9) 有7层楼,每层楼之间的距离是10步(比如从1层走到2层需要10步);今天电梯坏了只能停在某一层,需要去每一层的人的人数和层高一致(去i层的有i个人),问你电梯停在哪层,所有人走的距离最少,以及最少距离总和是多少?
- 10) HashMap扩容,映射方法为i%map长度,如果冲突再寻址的方法是i%map长度+k^2(冲突次数);初始长度是8,负载因子是0.7,每次扩容成之前的两倍。原来有3,6,8,9在map里,问你插入12,19映射的位置是哪?
- 11) 加密传输,原始图片是n,你的朋友通过m异或x得到了n,并且把x和m都发送给了你,问你怎么通过这两个还原n。
- 12) 先进后出的空间复杂度和时间复杂度(?记不清了)
- 13) 带符号加减法,问你有8位有符号的数(范围-128~127),问你127+10=多少
- 1. 反转链表代码补全
网友1
1. 顺序数组寻址(方阵里按行从左到右报号,第一个人报0,第二个人报3,依次类推,一共有65列;你在55行第22列,问你报号是多少)
考察矩阵的索引和规律性数列的分析:
最简单:54行有:54*65人;再加上22人即为总人数;通过等差数列;得10593
2. 二叉搜索树的种类,问你1-2-3-4和1-2-3这2个序列分别有多少种不同的二叉搜索树
数学:Catalan数,
class Solution {
public:
int numTrees(int n) {
vector<int> G(n + 1, 0); // 初始化一个大小为 n+1 的数组,初始值都为 0
G[0] = 1; // 空树的种类数是 1
G[1] = 1; // 只有一个节点的树的种类数是 1
// 从2开始计算每个 i 个节点的树的种类数
for (int i = 2; i <= n; ++i) {
// 对于每个 i,计算以不同节点为根的情况
for (int j = 1; j <= i; ++j) {
// G[i] 是将以第 j 个节点作为根节点的左子树种类数和右子树种类数的乘积累加
G[i] += G[j - 1] * G[i - j];
}
}
return G[n]; // 返回对于 n 个节点的二叉搜索树的种类数
}
};
代码解释:
对于含有 i 个节点的二叉搜索树:(外循环)
选择第 j 个节点作为根节点,这个根节点会将树分成左右两部分:(内循环)
左子树有 j-1 个节点
右子树有 i-j 个节点
因此,以 j 作为根节点时,不同的二叉搜索树的总数为 dp[j-1] * dp[i-j]。
对于所有可能的 j(从 1 到 i),我们需要累加这些值:
红黑树,问你存在A-B-Nil(叶子节点)的序列时,这棵红黑树最多有多少节点
当你提到存在 A-B-NIL 的序列时,这意味着红黑树中可能有一个路径从根节点到叶子节点的形式是:一个红色节点(A),接着是一个黑色节点(B),然后是一个叶子节点(NIL)。这种情况下,我们要找出这棵红黑树可能具有的最多节点数。
分析
为了找到最大节点数,我们考虑以下几点:
**红色节点的约束:**由于红色节点不能有红色子节点,所以每个红色节点必须直接连接一个黑色节点。这意味着如果有一个红色节点 A,那么它的子节点 B 必须是黑色的。
**最大化节点数:**为了最大化节点数,我们可以让树中尽可能多的节点成为红色节点。这样每个黑色节点下都有一个红色节点。
若A是红色:B是黑色
这条路径的黑色高度为2(B和nil)
若B为红色,A为黑色,
这条路径的黑色高度也为2(A和nil)
根据树的最大高度小于等于2倍的黑色高度;所以树最大为4;
在最大高度下,红黑树是最不平衡的;(红黑交替到达叶子结点)
5) maybe是贪心?问你有140g糖,要称出来64g,你有7g的砝码和2g的砝码各1个,问你最少称多少次能称出来。
解析:这是一道智力题:
类型这种问题,
虽然我们只有两个砝码,7g和2g,
但是我们不止能秤出7g和2g的重量
通过和天平的组合我们还可以称出 9g,5g。
还有我们直接不用砝码,把盐平分就可以得到70g。
需要注意的一点是,在我们称重的过程中,得到的固定重量的盐也是可以当砝码使用的,所以我们的称重就有了很多的可能性。各种砝码重量的组合就有了很多可能性。
6) maybe二分查找?有100个杯子,有1个重量和其他的不同,问你最少称多少次能找出来
天平称次品问题其实有两类:
对于 B类问题 ,则要复杂很多。
对于B类问题,我们举一个实际的例子,13个物品里有1个次品,答案是3次。我给出了具体的决策树:
具体地,首先我们拿出8个,天平左右各4个,剩下5个(记作 4 v 4 ∼ 5 4v4\sim5 4 v 4 ∼ 5 )。如果天平是水平的,说明次品在剩下的5个里,不平则在这8个里,但由于不清楚次品和正品的轻重关系,因此无法确定在左边4个还是右边4个。
7) 【最后一道填空】有两个栈,分别是接收序列(容量P)和中转序列(容量Q),P<Q,需要满足先进接收序列的机器人先出来工作(先进先出),条件是进了中转序列后不能返回接收序列。问你通道(序列)满的时候,两个通道容纳的最多的机器人和最少的机器人
解析,这道题目就是两个栈实现队列:
参考:https://blog.csdn.net/SCS199411/article/details/91443928
一个接收栈,一个输出栈,输出栈的容量Q大于接收栈的P;满足先进先出的情况下,两个栈中容纳最多元素和最少元素的数量
如果输出栈的容量是P,接收栈的容量是Q Q大于P
我的答案:接收栈先接受Q个元素,然后缓存到输出栈中,然后接收栈再接受Q+1个元素;输出的时候,输出栈先输出Q个元素,然后将接收栈中Q个元素(Q+2到2Q+1)然后接收栈弹出1个元素,也就是第Q+!个元素,再弹出接收栈中的Q个元素,此时输出为;1,2,Q Q+1 O+2…2Q+1;所以此时元素最多为2Q+1个;
当将push栈中的数据弹出并插入到pop栈时,必须确保push栈中的所有数据都被移动到pop栈中。这是因为只有这样,最早入队的元素才能位于pop栈的栈顶。
在pop栈为空之前,所有的出队操作(即pop栈弹出数据)都应该从pop栈中进行,而不能再从push栈中直接插入数据到pop栈中,否则会破坏队列的FIFO顺序。
8) 有5个人,分别是a b c d e,按照上述顺序顺时针就坐成圆圈,他们每个人都给(向左邻投票的人)投票(每个人只能投一票),结果最后所有人得票都一样,问你他们是怎么投票的
9) 有7层楼,每层楼之间的距离是10步(比如从1层走到2层需要10步);今天电梯坏了只能停在某一层,需要去每一层的人的人数和层高一致(去i层的有i个人),问你电梯停在哪层,所有人走的距离最少,以及最少距离总和是多少?
10) HashMap扩容,映射方法为i%map长度,如果冲突再寻址的方法是i%map长度+k^2(冲突次数);初始长度是8,负载因子是0.7,每次扩容成之前的两倍。原来有3,6,8,9在map里,问你插入12,19映射的位置是哪?
11) 加密传输,原始图片是n,你的朋友通过m异或x得到了n,并且把x和m都发送给了你,问你怎么通过这两个还原n。
考异或加密;
对密文再次异或就是明文
12) 先进后出的空间复杂度和时间复杂度(?记不清了)
13) 带符号加减法,问你有8位有符号的数(范围-128~127),问你127+10=多少
根据补码计算;
0111 1111 (127)
+ 0000 1010 (10)
-----------
1000 1001 (-119)
这里的二进制都是补码表示,补码的补码·就是源码
1. 反转链表代码补全
双指针法:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
//双指针法:
//定义一个pre和一个cur定义当前结点和前一个结点
// 定义一个temp用来充当临时结点,用来保存当前节点指向的下一节点;
ListNode* temp;
ListNode* cur = head;
ListNode* pre = nullptr;
while(cur)
{
temp = cur->next; //获得需要处理的下一个结点,进行保存
cur->next = pre; //将本结点反转
pre = cur;//当前结点处理晚了,将当前节点作为上一结点
cur = temp;//获得下一次循环的当前节点;
}
return pre;//经过不断地循环,pre就成为了头结点
}
};
递归法:
class Solution {
public:
//递归方法本质上是和双指针方法是一样的,只不过是使用了递归函数,更加简洁
ListNode* resverse(ListNode* pre, ListNode* cur)
{
if(cur == nullptr) return pre;
ListNode* temp = cur->next;
cur->next = pre;
return resverse(cur,temp);
}
ListNode* reverseList(ListNode* head) {
//递归方法求解
return resverse(nullptr,head);
}
};