文远知行算法笔试0921

题1:数组中找一段异或和等于 k 的子数组

题干
给定整数数组 a[1..n] 与整数 k,求是否存在连续子数组使其异或和为 k。若存在输出该子数组的左右下标(1-based),否则输出 -1

说明
定义前缀异或 px[i] = a1 ⊕ ⋯ ⊕ ai,则区间 [l, r] 的异或和为 px[r] ⊕ px[l−1]

import sys

def main():
    data = list(map(int, sys.stdin.read().strip().split()))
    if not data:
        return
    n, k = data[0], data[1]
    a = data[2:2+n]

    first_pos = {0: 0}  # px[0]=0 at position 0
    px = 0
    for r in range(1, n+1):
        px ^= a[r-1]
        need = px ^ k                   # need px[l-1] == px[r]^k
        if need in first_pos:
            l = first_pos[need] + 1     # 1-based
            print(l, r)
            return
        if px not in first_pos:         # keep earliest
            first_pos[px] = r
    print(-1)

if __name__ == "__main__":
    main()

题2:最长“美观”括号子串(支持 () [] {})

题干
给定仅由括号 ()[]{} 组成的字符串 s,定义:

  • 空串是美观;
  • A 美观,则 (A)[A]{A} 也美观;
  • AB 都美观,则 AB 也美观。

s 中最长美观的连续子串长度。

import sys

pairs = {')':'(', ']':'[', '}':'{'}

def longest_beautiful(s: str) -> int:
    idx_stack = [-1]   # 下标栈,-1 为哨兵
    ch_stack  = ['#']  # 类型栈
    ans = 0
    for i, ch in enumerate(s):
        if ch in "([{":
            idx_stack.append(i)
            ch_stack.append(ch)
        else:
            if len(idx_stack) > 1 and ch_stack[-1] == pairs.get(ch, '?'):
                idx_stack.pop()
                ch_stack.pop()
                ans = max(ans, i - idx_stack[-1])
            else:
                idx_stack.append(i)
                ch_stack.append('#')    # 新的无效基底
    return ans

def main():
    s = sys.stdin.read().strip()
    print(longest_beautiful(s))

if __name__ == "__main__":
    main()

题3:n×m 乘法表的第 k 小元素

题干
乘法表第 i 行第 j 列为 i×j(下标从 1 开始)。给定 n, m, k,将整个乘法表按非降序排列后,求第 k 个元素。

思路
二分答案 x,并统计表中不大于 x 的个数:

找到最小的 x 使得 count(x) ≥ k

import sys

def count_le(n, m, x, k):
    s = 0
    up = min(n, x)
    for i in range(1, up + 1):
        s += min(m, x // i)
        if s >= k:
            return s
    return s

def main():
    n, m, k = map(int, sys.stdin.read().strip().split())
    if n > m:
        n, m = m, n
    lo, hi = 1, n * m
    while lo < hi:
        mid = (lo + hi) // 2
        if count_le(n, m, mid, k) >= k:
            hi = mid
        else:
            lo = mid + 1
    print(lo)

if __name__ == "__main__":
    main()
26秋招算法笔试 文章被收录于专栏

26秋招算法笔试

全部评论
三道题给了多长时间,有没有限制时间
点赞 回复 分享
发布于 09-27 13:50 陕西

相关推荐

基本情况:&nbsp;·&nbsp;前端·&nbsp;南方人,未来肯定回南方(另:不太喜欢北京、租房环境极差,一些东西受限,比如车牌)·&nbsp;薪资=职业发展&amp;gt;城市&amp;gt;wlb·&nbsp;其他公司薪资比不过这俩、就不考虑了纠结的地方(在二者薪资相差不大的情况下):·&nbsp;字节是tob,个人更倾向pdd的toc(之前咨询过同事这个问题,看法是:tob更要求全面,要学习接触的更多、toc更精专,追求极致;但我很怀疑工作后个人的学习自我驱动力,相较于学生时代而言)·&nbsp;在字节干的事有时候会怀疑它的价值,以至于需要自证价值,另外还有360环评等形式主义较重等事(前半段当初实习的时候已经感受过了、后半段是以一个正职的身份规避不掉的话题)·&nbsp;pdd10106,这一点咬咬牙还能接受;但还有一个竞业无法忽略,很怕职业生涯刚开始就结束(当然也想过直接在pdd干到提前退休、在跳出三贷之外的情况下)历史上也没看见在竞业上全身而退的·&nbsp;网传pdd做事风格实在,但毕竟没去待过,且小组之间的差别比公司的差别还大,万一踩雷几乎无planeB;字节毕竟在那实习了好长段时间,和mt、ld相处得比较融洽,离职之前ld还给画了大饼·&nbsp;pdd有普调,相比字节“以能定级、以级定薪”似乎更友好一点?毕竟现在坑位越来越少、人越来越多希望牛友们可以说说理由~
投递字节跳动等公司10个岗位
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

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