华为OD笔试机试 - 求幸存数之和 (Java 2024年C卷D卷真题算法)

华为OD机试(C卷+D卷)2024真题目录(Java & c++ & python)

题目描述

给一个正整数数列 nums,一个跳数 jump,及幸存数量 left。

运算过程为:从索引0的位置开始向后跳,中间跳过 J 个数字,命中索引为 J+1 的数字,该数被敲出,并从该点起跳,以此类推,直到幸存 left 个数为止,然后返回幸存数之和。

约束:

0是第一个起跳点
起跳点和命中点之间间隔 jump 个数字,已被敲出的数字不计入在内。
跳到末尾时无缝从头开始(循环查找),并可以多次循环。
若起始时 left > len(nums) 则无需跳数处理过程。
方法设计:

/**

  • @param nums 正整数数列,长度范围 [1, 10000]
  • @param jump 跳数,范围 [1, 10000]
  • @param left 幸存数量,范围 [0, 10000]
  • @return 幸存数之和
    */
    int sumOfLeft(int[] nums, int jump, int left)

输入描述

第一行输入正整数数列

第二行输入跳数

第三行输入幸存数量

输出描述

输出幸存数之和

示例1

输入

1,2,3,4,5,6,7,8,9
4
3

输出

13

说明:从1(索引为0)开始起跳,中间跳过 4 个数字,因此依次删除 6,2,8,5,4,7。剩余1,3,9,返回和为13

解题思路

示例1中删点过程如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过上面图示我们可以发现,被删除节点其实是作为起跳点,因此基于普通数组来操作的话,既要实现节点删除,又要实现基于删除点进行下次的起跳。
那么可以通过模拟实现。

参考代码

import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;

public class Main {
    public int sumOfLeft(int[] nums, int jump, int left) {
        List<Integer> list = 
            new LinkedList<>(Arrays.stream(nums).boxed().collect(Collectors.toList()));

        // 从起跳点下一个节点开始, 初始时起跳点为索引0,因此下一个节点为索引1
        int start = 1;

        // 如果剩余节点数 > 幸存数量,则还需要继续删除节点
        while (list.size() > left) {
            // 跳 jump 次
            start += jump;
            // 为了避免越界,新起跳点索引位置对剩余节点数取余
            start %= list.size();
            list.remove(start);
        }

        // 使用 mapToInt 和 sum 来计算总和
        return list.stream().mapToInt(Integer::intValue).sum();
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        // 示例用法
        int[] nums = {1, 2, 3, 4, 5, 6, 7};
        int jump = 2;
        int left = 3;
        
        Main main = new Main();
        System.out.println(main.sumOfLeft(nums, jump, left));
    }
}

  • 18
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值