26届暑期实习PDD4.20笔试题

1. 给出n个字符串,每个字符串可以选择x_i个字符,要求从n个字符串里面选出来的字符中输出长为k的最小字典序的字符串。

输入每一个字符串s,转换为[]byte然后排序,切片前x_i个字节;将这n个切出来的字节数组拼成一个大的字节数组,排序,返回

2. 根据演员之间的意见来确定薪资分配,输入n,m表示一共有n个演员和m条意见,一条意见的格式是(a,b),也就是有一条意见表示演员a应该比演员b薪资高。

先建成一个有向图,节点是演员编号,如果有意见(a,b),那么就建一条(b,a)的边;同时建一个数组,用来存储每个节点的入读。可以看出,每个节点的费用只和指向该节点的费用相关,这样就可以使用BFS来做。

  1. 入度为0的节点入队,入队的是一个结构体包括节点编号x以及节点的费用money
  2. 队列不为空
  3. 弹出一个节点t
  4. res += t.money
  5. b遍历t指向的节点v
  6. 如果v的度数为1,将其加入队列,v.money = t.money + 10
  7. v的度数减去1

3. 遍历一遍度数的数组,如果有节点度数大于0,表示图中有环的存在,res = -1

3. 将一个数组变为严格上升的数组,可以将数组中某个元素减小或增大,求最小变化的次数

没做出来,下面是deepseek给的思路:

如果数组中的元素位置不能改变,即不能通过重新排列元素来形成严格递增序列,那么我们需要找到一种方法,通过仅增加或减少某些元素的值(不能交换位置)来使数组严格递增,并且操作次数最少。

方法思路

此时,问题转化为:在保持元素原始顺序的前提下,调整某些元素的值(可以增大或减小),使得整个数组严格递增(nums[i] < nums[i+1]),并且调整的次数最少。

关键观察

  1. 严格递增约束:对于所有 i,必须满足 nums[i] < nums[i+1]
  2. 调整方式:可以对任意元素进行增加或减少操作,但不能交换位置。
  3. 目标:找到最少的调整次数,使得整个数组严格递增。

动态规划解法

我们可以使用动态规划(DP)来解决这个问题:

  • 定义 dp[i] 表示以 nums[i] 结尾的严格递增子序列的最小操作次数。
  • 对于每个 i,我们需要检查所有 j < i,并确保 nums[j] < nums[i],同时计算调整 nums[i]nums[j] 的最小操作次数。

但由于直接DP的时间复杂度是 O(n^2),对于较大的 n(如 n ≤ 1e5),我们需要更优化的方法。

贪心优化

我们可以采用类似 最长递增子序列(LIS) 的贪心策略,但需要额外考虑调整后的值必须满足严格递增:

  1. 维护一个动态数组 d,其中 d[i] 表示长度为 i+1 的严格递增子序列的最小末尾值。
  2. 对于每个 nums[i],找到 d 中第一个 ≥ nums[i] 的位置 k,并用 nums[i] 替换 d[k]
  3. 这样,d 的长度即为最长严格递增子序列的长度,最少操作次数为 n - len(d)

但需要注意:

  • 由于位置不能改变,我们需要确保在调整时,nums[i] 可以比前一个数大(如果选择保留它),否则必须调整它或前面的数。
  • 因此,直接使用LIS的长度可能不完全准确,需要进一步优化。

最优解法

我们可以结合 贪心 + 二分查找 的方法,并额外记录调整后的值:

  1. 初始化 d = []
  2. 遍历 nums,对于每个 num: 如果 num 可以放在 d 的末尾(即 num > d[-1]),直接加入 d。否则,找到 d 中第一个 ≥ num 的位置 k,并尝试用 num 替换 d[k](相当于调整 d[k] 或 num)。
  3. 最少操作次数为 n - len(d)

解决代码

def min_operations_to_increase(nums):
    if not nums:
        return 0
    d = []
    for num in nums:
        if not d or num > d[-1]:
            d.append(num)
        else:
            left, right = 0, len(d) - 1
            pos = right
            while left <= right:
                mid = (left + right) // 2
                if d[mid] >= num:
                    pos = mid
                    right = mid - 1
                else:
                    left = mid + 1
            d[pos] = num
    return len(nums) - len(d)

代码解释

  1. 初始化动态数组 d:用于存储当前严格递增子序列的最小末尾值。
  2. 遍历 nums: 如果 num 可以扩展当前严格递增序列(num > d[-1]),直接加入 d。否则,用二分查找找到 d 中第一个 ≥ num 的位置,并用 num 替换它(相当于调整 num 或 d[k])。
  3. 最少操作次数n - len(d),即总元素数减去最长严格递增子序列的长度。

例子验证

  • nums = [1, 2, 3, 6, 5, 4]: LIS 为 [1, 2, 3, 6] 或 [1, 2, 3, 5],长度 4。最少操作次数 6 - 4 = 2(调整 5 和 4)。
  • nums = [1, 3, 2, 4]: LIS 为 [1, 3, 4] 或 [1, 2, 4],长度 3。最少操作次数 4 - 3 = 1(调整 2 或 3)。

结论

  • 该方法保证了最少操作次数,且仅通过增加或减少某些元素的值来实现严格递增。
  • 时间复杂度为 O(n log n),适用于较大的 n

4. 给出一个数组a和一个整数x,当x大于a[i]时可以与x互换,求数组a变为递增序列时的最小交换次数。

双指针。

  1. i,j := 0,0
  2. 当a[i] < a[i + 1]的使用,如果j <= i 那么j ++
  3. 如果a[j] > x , 则进行交换 a[j],x=x,a[j],并且cnt ++
  4. 重新遍历a数组,如果存在a[i] > a[i + 1],cnt = -1即不存在

全部评论
pdd笔试a几道能过啊
点赞 回复 分享
发布于 05-09 11:10 河南

相关推荐

1.&nbsp;接触前端多久了,看两个项目的完成时间都比较近。2.&nbsp;对于前端掌握的一个熟悉程度怎么样,能自我评价一下吗3.&nbsp;对于React,之前有了解过吗?了解的程度是怎么样的4.&nbsp;说一下SSE传输和普通的HTTP请求之间的差别和不同5.&nbsp;SSE和WebSocket有什么区别呢?6.&nbsp;提到的这个打字机的效果,说一下它实现的思路或者是一个原理7.&nbsp;SSE返回的数据可能是一段,而不是这种一个一个的数据,比如说是十个字符串吧,那这种应该怎么办呢,有实现的一个思路吗8.&nbsp;HTTP和HTTPS之间的区别9.&nbsp;看到项目中依赖了一个第三方平台的api,能说一下这里是怎么去鉴权的呢,以及代码这边需要做什么样的开发和改造10.&nbsp;第三方平台和这种openai的api其实有一些地方是跨域的,对于跨域,其实有时候一些跨域的请求会失败,你对这方面有了解吗?或者说浏览器跨域的一个限制11.&nbsp;图片性能的优化,可以介绍一下这个方式并且说一下实现的原理吗12.&nbsp;想做一个登录的拦截,有什么实现的思路13.&nbsp;三列布局的一个样式,左中右,要求中间宽度是800px,左边和右边平分剩余的大小,有几种实现的方式14.&nbsp;flex:1&nbsp;指的是什么15.&nbsp;如果用flex,那如果页面宽度为600px的时候,左右是多宽16.&nbsp;position的定位方式都有哪些17.&nbsp;一个事件循环的题,说输出18.&nbsp;手写Promise&nbsp;All
查看18道真题和解析
点赞 评论 收藏
分享
评论
4
11
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务