【2025春招真题改编】03.07-饿了么春招-算法岗

✅ 春招备战指南 ✅

💡 学习建议:

  • 先尝试独立解题(建议用时:90分钟/套)
  • 对照解析查漏补缺
  • 配套练习题库

互联网必备刷题宝典🔗

01. 数据特征最大化

题目内容

小基是一个数据分析师,他最近获得了一个长度为 的数组 。作为一名分析师,他定义了两个重要的数据特征函数:

(所有元素的按位异或和) (所有元素的最大公约数)

为了寻找数据中的关键信息,小基需要从数组 中选择一个非空连续子数组 ,使得该子数组的 值尽可能大。请帮助小基计算这个最大可能值。

输入描述

第一行一个正整数 ,表示测试数据的组数。

接下来对于每组测试数据,输入包含两行:

  • 第一行一个正整数 ,表示数组 的长度。
  • 第二行 个整数 ,表示数组 的元素。

保证所有测试数据中 的总和不超过

输出描述

对于每组测试数据,输出一行一个整数表示最大的 值。

样例1

输入:

1
4
1 1 1 1

输出:

1

题解

这道题看似需要枚举所有可能的子数组并计算特征值,但通过分析可以发现一个重要性质:对于任意单元素子数组,其异或值和最大公约数都等于元素本身,因此乘积就是元素的平方。

关键发现:

  1. 单元素子数组的 值就是元素本身
  2. 单元素子数组的 值也是元素本身
  3. 对于多元素子数组, 值不会超过子数组中的最小元素

通过数学证明可知,数组中最大元素的平方就是问题的最优解。时间复杂度为 ,只需遍历一次数组找出最大值即可。

参考代码

  • Python
def solve_case():
    # 读取输入
    size = int(input())
    nums = list(map(int, input().split()))
    
    # 查找最大值
    get_max = lambda x: max(x)
    peak = get_max(nums)
    
    # 返回平方值
    return peak * peak

def main():
    # 处理多组测试
    cases = int(input())
    for _ in range(cases):
        res = solve_case()
        print(res)

if __name__ == "__main__":
    main()
  • Cpp
#include <bits/stdc++.h>
using namespace std;

long long solve_case() {
    int size;
    cin >> size;
    
    // 记录最大值
    long long peak = 0;
    
    // 内联函数更新最大值
    auto update_peak = [&peak](long long val) {
        peak = max(peak, val);
    };
    
    // 读取并处理数组
    for(int i = 0; i < size; ++i) {
        long long val;
        cin >> val;
        update_peak(val);
    }
    
    return peak * peak;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int cases;
    cin >> cases;
    
    while(cases--) {
        cout << solve_case() << "\n";
    }
    
    return 0;
}
  • Java
import java.util.Scanner;

public class Main {
    // 查找最大值的辅助方法
    private static long findPeak(long[] nums) {
        long peak = 0;
        for(long val : nums) {
            peak = Math.max(peak, val);
        }
        return peak;
    }
    
    // 处理单个测试用例
    private static long solveCase(Scanner sc) {
        int size = sc.nextInt();
        
        // 读取数组
        long[] nums = new long[size];
        for(int i = 0; i < size; i++) {
            nums[i] = sc.nextLong();
        }
        
        // 找出最大值
        long peak = findPeak(nums);
        
        return peak * peak;
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int cases = sc.nextInt();
        
        for(int i = 0; i < cases; i++) {
            System.out.println(solveCase(sc));
        }
        
        sc.close();
    }
}

02. 同质接龙字符串

题目内容

小柯是一位语言学家,他正在研究一种特殊的字符串序列,称为"同质接龙序列"。他手中有一个长度为 的初始字符串

小柯希望基于这个初始字符串,构造出总共 个字符串 组成的序列,要求如下:

  1. 对于任意 ,必须满足 的首字母等于 的末字母。
  2. 序列中每个字符串都与初始字符串 包含完全相同的字母种类和数量。

输入描述

第一行输入一个整数 ,表示测试数据的组数。

接下来对于每组测试数据,输入一个长度为 且仅由小写字母构成的字符串 和一个整数

输出描述

对于每组测试数据,输出一行一个整数,表示不同的方案总数,结果对 取模后输出。

样例1

输入:

2
abc 2
abc 1

输出:

2
1

题解

这道题考察动态规划与记忆化搜索。关键是找到状态定义和转移方式。

核心思路:

  1. 每个字符串必须是初始字符串的排列
  2. 相邻字符串之间有"接龙"要求
  3. 使用状态压缩优化存储

定义状态 dp[pos][x][y][z] 表示:在位置 pos,当前字符串字符为 x,y,z 时的方案数。通过编码可以将状态压缩为 dp[pos][state]

时间复杂度:,其中 k 为字符组合数(常数)。 空间复杂度:

参考代码

  • Python
def calc_ways(txt, num):
    # 字符映射
    ch_map = {}
    idx = 0
    for c in txt:
        if c not in ch_map:
            ch_map[c] = idx
            idx += 1
    
    # 缓存数组
    memo = [{} for _ in range(num+1)]
    
    def count_seq(pos, c1, c2, c3):
        if pos == 1:
            return 1
            
        # 状态编码
        state = c1 + c2*3 + c3*9
        
        if state in memo[pos]:
            return memo[pos][state]
        
        # 计算方案数
        total = 0
        if c1 != c2:
            total = (count_seq(pos-1, c3, c1, c2) +
                     count_seq(pos-1, c3, c2, c1)) % MOD
        else:
            total = count_seq(pos-1, c3, c1, c2)
            
        memo[pos][state] = total
        return total
    
    # 初始状态
    return count_seq(num, ch_map[txt[0]], ch_map[txt[1]], ch_map[txt[2]])

def main():
    cases = int(input())
    for _ in range(cases):
        txt, num = input().split()
        print(calc_ways(txt, int(num)))

if __name__ == "__main__":
    MOD = 10**9 + 7
    main()
  • Cpp
#include <bits/stdc++.h>
using namespace std;

const int MOD = 1e9 + 7;

// 状态编码
inline int encode(int a, int b, int c) {
    return a + (b << 2) + (c << 4);
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int cases;
    cin >> cases;
    
    while(cases--) {
        string txt;
        int num;
        cin >> txt >> num;
        
        // 字符映射
        unordered_map<char, int> ch_map;
        int next_id = 0;
        
        for(char c : txt) {
            if(ch_map.find(c) == ch_map.end()) {
                ch_map[c] = next_id++;
            }
        }
        
        // 状态缓存
        vector<unordered_map<int, int>> memo(num + 1);
        
        // 递归计算
        function<int(int, int, int, int)> calc = [&](int pos, int c1, int c2, int c3) -> int {
            if(pos == 1) 
                return 1;
                
            int key = encode(c1, c2, c3);
            
            if(memo[pos].count(key)) 
                return memo[pos][key];
            
            int res;
            if(c1 == c2) {
                res = calc(pos - 1, c3, c1, c2);
            } else {
                res = calc(pos - 1, c3, c1, c2);
                res = (res + calc(pos - 1, c3, c2, c1)) % MOD;
            }
            
            memo[pos][key] = res;
            return res;
        };
        
        // 计算结果
        cout << calc(num, ch_map[txt[0]], ch_map[txt[1]], ch_map[txt[2]]) << endl;
    }
    
    return 0;
}
  • Java
import java.util.*;

public class Main {
    static final int MOD = 1000000007;
    
    // 状态编码
    private static int encode(int a, int b, int c) {
        return a | (b << 4) | (c << 8);
    }
    
    private static int calcWays(String txt, int num) {
        // 字符映射
        Map<Character, Integer> chMap = new HashMap<>();
        int nextId = 0;
        
        for(char c : txt.toCharArray()) {
            if(!chMap.containsKey(c)) {
                chMap.put(c, nextId++);
            }
        }
        
        // 状态缓存
        List<Map<Integer, Integer>> memo = new ArrayList<>(num + 1);
        for(int i = 0; i <= num; i++) {
            memo.add(new HashMap<>());
        }
        
        // 递归计算
        return countSeq(num, 
                      chMap.get(txt.charAt(0)), 
                      chMap.get(txt.charAt(1)), 
                      chMap.get(txt.charAt(2)), 
                      memo);
    }
    
    private static int countSeq(int pos, int c1, int c2, int c3, 
                               List<Map<Integer, Integer>> memo) {
        if(pos == 1) {
            return 1;
        }
       

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

互联网刷题笔试宝典 文章被收录于专栏

互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力

全部评论

相关推荐

04-11 21:31
四川大学 Java
野猪不是猪🐗:(ja)va学弟这招太狠了
点赞 评论 收藏
分享
评论
1
3
分享

创作者周榜

更多
牛客网
牛客企业服务