E-跳房子I(100p)

跳房子I

问题描述

跳房子是一种广受欢迎的儿童游戏。游戏参与者需要分多个回合,按顺序从第 1 格跳到房子的最后一格。在跳房子的过程中,可以向前跳,也可以向后跳。

假设房子的总格数是 ,小红每回合可能连续跳的步数都放在数组 中。请判断数组中是否存在一种步数的组合,可以让小红在两个回合内跳到最后一格?

如果存在这样的组合,请输出索引和最小的步数组合。

注意:

  • 数组中的步数可以重复,但数组中的元素不能重复使用。
  • 提供的数据保证存在满足题目要求的组合,且索引和最小的步数组合是唯一的。

输入格式

第一行输入为房子总格数 ,它是 int 整数类型。 第二行输入为每回合可能连续跳的步数,它是 int 整数数组类型。

输出格式

返回索引和最小的满足要求的步数组合(顺序保持 中原有顺序)。

样例输入1

[1,4,5,2,2]
7

样例输出1

[5, 2]

样例输入2

[-1,2,4,9,6]
8

样例输出2

[-1, 9]

样例输入3

[1,2,9,9,9,1,9,9,3,2]
4

样例输出3

[1, 3]

解释说明

样例 解释说明
样例1 小红可以先跳 5 步,再跳 2 步,正好到达第 7 格(最后一格)。
样例2 此样例有多种组合满足两回合跳到最后,例如:[-1,9],[2,6]。其中[-1,9]的索引和为0+3=3,[2,6]的索引和为1+4=5,所以索引和最小的步数组合是[-1,9]。
样例3 小红可以先跳 1 步,再跳 3 步,正好到达第 4 格(最后一格)。

数据范围

题解

哈希表+模拟

这道题目本质上是"两数之和"问题的变种。我们需要在给定的数组 中找到两个数,使它们的和等于目标值 。不同于经典的"两数之和",这里我们还需要考虑索引和最小的组合。

解题思路如下:

  1. 创建一个哈希表(字典),用于存储每个步数及其索引。
  2. 遍历数组 ,对于每个元素
    • 计算补数
    • 如果 在哈希表中,我们找到了一个有效组合
    • 比较当前组合的索引和与之前找到的最小索引和
    • 如果当前索引和更小,更新结果
  3. 如果遍历结束后没有找到有效组合,返回空列表

这种方法的时间复杂度是 ,其中 是数组 的长度。只需要遍历一次数组,而哈希表的查找操作的平均时间复杂度是

参考代码

  • Python
def find_jump_combination(steps, count):
    # 创建一个字典来存储步数和对应的索引
    step_dict = {}
    # 初始化结果列表和最小索引和
    result = []
    min_index_sum = float('inf')
    
    # 遍历步数数组
    for i, step in enumerate(steps):
        # 计算需要的补数
        complement = count - step
        # 如果补数在字典中,说明找到了一个有效组合
        if complement in step_dict:
            # 计算当前组合的索引和
            current_index_sum = i + step_dict[complement]
            # 如果当前索引和小于之前的最小索引和,更新结果
            if current_index_sum < min_index_sum:
                min_index_sum = current_index_sum
                result = [complement, step] if step_dict[complement] < i else [step, complement]
        # 将当前步数和索引加入字典,如果已存在则不更新(保留最小索引)
        if step not in step_dict:
            step_dict[step] = i
    
    return result

# 读取输入
input_steps = eval(input().strip())  # 使用 eval 来解析输入的列表
count = int(input().strip())

# 调用函数并输出结果
result = find_jump_combination(input_steps, count)
print(result)
  • C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

// 定义结构体,用于存储步数及其索引
typedef struct {
    int step;
    int index;
} StepIndex;

// 函数:查找两个步数,使其和为指定值,且索引和最小
int* findJumpCombination(int* steps, int size, int count, int* returnSize) {
    // 创建一个动态数组,用于存储结果
    int* result = (int*)malloc(2 * sizeof(int));
    // 初始化一个很大的索引和,用于比较最小索引和
    int minIndexSum = INT_MAX;
    
    // 创建哈希表,简单使用数组模拟,存储步数及其最小索引
    StepIndex* stepMap = (StepIndex*)malloc(size * sizeof(StepIndex));
    int stepMapSize = 0; // 当前哈希表中元素数量

    // 遍历所有步数
    for (int i = 0; i < size; ++i) {
        int complement = count - steps[i]; // 计算所需补数
        
        // 查找补数是否存在哈希表中
        for (int j = 0; j < stepMapSize; ++j) {
            if (stepMap[j].step == complement) {
                // 找到有效组合,计算当前组合的索引和
                int currentIndexSum = i + stepMap[j].index;
                if (currentIndexSum < minIndexSum) {
                    minIndexSum = currentIndexSum;
                    // 更新结果,确保第一个数较小
                    if (stepMap[j].index < i) {
                        result[0] = complement;
                        result[1] = steps[i];
                    } else {
                        result[0] = steps[i];
                        result[1] = complement;
                    }
                }
                break; // 找到后立即退出查找
            }
        }

        // 将当前步数和索引加入哈希表
        int found = 0; // 是否找到相同的步数
        for (int j = 0; j < stepMapSize; ++j) {
            if (stepMap[j].step == steps[i]) {
                found = 1;
                break;
            }
        }
        if (!found) {
            stepMap[stepMapSize].step = steps[i];
            stepMap[stepMapSize].index = i;
            stepMapSize++;
        }
    }

    // 返回结果大小为2
    *returnSize = 2;
    free(stepMap); // 释放哈希表内存
    return result;
}

// 函数:解析输入字符串为整数数组
int* parseInput(char* input, int* size) {
    int* result = (int*)malloc(100100 * sizeof(int)); 
    *size = 0;
    
    char* token = strtok(input + 1, ","); // 去掉第一个'['
    while (token != NULL && token[0] != ']') {
        result[(*size)++] = atoi(token); // 将字符串转换为整数
        to

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

算法刷题笔记 文章被收录于专栏

本专栏收集并整理了一些刷题笔记

全部评论
有需要的宝子可以订阅专栏哦~
点赞 回复 分享
发布于 10-31 11:56 浙江

相关推荐

刚刚做了华为Java机考,人是懵的。三道题两小时,每道题都看着不难都有思路结果写完过了测试一提交只有10%通过率,最后只有第一题提到了85%,最后算下来135分过不了150线,我愧对期待值拉满的HR,愧对我自己的复习。。。还是没刷够和基础不足,但至少把题目发这里大伙帮我解决一下这个遗憾吧。(不是,哥们。发现十拿九稳的主思路只能过10%,真得懵吧)第一题100:游客参观总时长问游乐园每天开放多久能招待所有游客。游乐园每一段时间能接受任意个数游客。每一行给一个游客的参观时长[1,5],[1,2],&nbsp;[10,11],输出总时长&nbsp;4+1=5.&nbsp;数值全在10^6以下。(确认输入无误)我一开始想做合并时间段最后算累加,结果Arraylist写下来边界判断什么的瞎闹连测试案例都过不了。三道题都写完之后回来检查,改了方法,求出参观时长的最大值,以它为长度建立空数组,再遍历游客时间插入1.最后数1,数到0就断掉算长度累加。通过率到了85%,但是给的反馈是测试用例运行错误,不是超时,我就只能继续检查下一题去了。(没想到后续检查没救得了我)第二题200:字符串集合求交集(这个是我最懵的,教教)(不需要检查输入)题目意思非常简单,给你输入几个字符串集合,{3(长度)&nbsp;123&nbsp;456&nbsp;789}第一个集合.{&nbsp;2&nbsp;456&nbsp;789}第二个集合。输出每个集合交集最大的集合和长度&nbsp;2&nbsp;2&nbsp;\n&nbsp;1&nbsp;2&nbsp;。字符串完全相等就是交集的元素。就这么简单。&nbsp;我Hashmap存集合的输入顺序,也就是集合的序号,value存的是字符串ArrayList。然后按总输出的值遍历这个输入顺序下标获取那个字符串集合,然后和另一个下标对应的字符串集合遍历。四层遍历求个相等的情况+1,记录最长值和最长集合序号。过了测试例以后提交,10%,还是答案错误不是超时,我人懵了,回来检查的时候也还是懵的。各路大神务必教教我这必须查相等的遍历为什么过了基础例子然后只能过10%的测试。有什么优化办法能既考虑边界值也能简化时长的?第三题300:摘水果也蛮直白的,给你个正方形地图,然后每个格子上是水果的数量,如果不能走就是-1.&nbsp;果农要从左上角走到右下角,只能向下或向右。走到右下角以后他再从右下角折回来走(没限制怎么走回来)到左上角,问你他能采摘的最大水果数量。这题我承认肯定是算法没想明白,漏了什么很关键的东西。(应该早点放弃检查的,很烦)这题我一开始想搞个递归往下找记录总数改变地图数字,然后往上找再递归找路最后加起来。但是写出来了向下找路然后发现这个找路和求最大值的路想做复原太诡异了,(现在想想完全可以找到路了记下来再找到最大值,很有可能能避免一些case)就放弃了递归投向动态规划。我累加了一次dp所有值抵达右下角以后,发现这个格子里的值正好是走下去走上来能拿到的最大值,想了一下应该也对,如果从左上角走不下来,那也不可能从那条路折回来,所有通路值加到最后应该就是答案。(难道说!是多个通路,只能取2条最大?!状态转移没这么简单才对!)状态转移方程就是等于非-1的左侧和上侧的格子的值相加再加上本来格子里的值。如果左上都是-1那我直接设为0.(难道该设为-1?复盘才发现槽点太多)(给地图加了一行一列全设为0,从1开始遍历到n。)往回走也不可能走这里。最后得分10%。求解!
牛客141057821号:我用python做的 第一道题记得leetcode有原题,先用开始参观时间sort一下然后指针遍历求set union 第二道题我python暴力解法全过。。 第三道题我是两遍dp,已从从左上到右下一次右下到左上,中间把第一次遍历走过的格子设成0就完了。 话说150是分数线吗?可以问下哪里的消息么
查看3道真题和解析 投递华为等公司10个岗位
点赞 评论 收藏
分享
2 2 评论
分享
牛客网
牛客企业服务