力扣|找出和所对应的两数的下标

news2024/12/23 5:48:41

从零开始刷力扣(bushi

题目放在这:

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为目标值target的两个整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

示例 2:

输入:nums = [3,2,4], target = 6
输出:[1,2]

示例 3:

输入:nums = [3,3], target = 6
输出:[0,1]

提示:

2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109

只会存在一个有效答案

放一个分割线在这:


我自己也是C语言复建,没有系统学习过数据结构,所以第一反应真就是暴力破解(见笑了)

也就是依次将数组的两个元素相加,和目标数做对比

因为只有一个有效答案,那么就可以在检索到和等于目标数数,直接输出对应的坐标

如果遍历结束没有得到结果,则输出NULL

借一下leecode的标准答案,这边我自己加上了前期的输入输出语句,这样方便看到结果:

#include <stdio.h>
#include <stdlib.h>

int *twoSum(int *nums, int numsSize, int target, int *returnSize);

int main() {
	int *p, *returnSize;
	int nums[10];
	int numsSize = 0, target = 0;
	*returnSize = 2;

	printf("找出数组中和为目标数的两个元素的下标:\n请输入数组的长度(不超过十)\n");
	scanf("%d", &numsSize);
	printf("请输入数组的内容,并用回车分隔\n");
	for (int i = 0; i < numsSize; i++) {
		scanf("%d", &nums[i]);
	}
	printf("您输入的数组内容为:nums[]=");
	for (int i = 0; i < numsSize; i++) {
		printf("%d ", nums[i]);
	}
	printf("请输入您的目标数:\n");
	scanf("%d", &target);
	p = twoSum(nums, numsSize, target, returnSize);
	if (p != NULL) {
		printf("您的目标数对应的坐标下标为:");
		printf("%d ", p[0]);
		printf("%d", p[1]);
	} else
		printf("您的目标数不能被数组中的任何两个数相加得到。");

	return 0;
}

int *twoSum(int *nums, int numsSize, int target, int *returnSize) {
	for (int i = 0; i < numsSize; ++i) {
		for (int j = i + 1; j < numsSize; ++j) {
			if (nums[i] + nums[j] == target) {
				int *ret = (int *)malloc(sizeof(int) * 2);
				ret[0] = i, ret[1] = j;
				*returnSize = 2;
				return ret;
			}
		}
	}
	*returnSize = 0;
	return NULL;
}

 简单讲一点:

1、<stdio.h>头文件,翻译为standard input output

程序中用到的scanf、printf,都需要使用标准的输入输出库

2、<stdlib.h>头文件,和存储、空间分配密切相关的一个函数

程序中用到的malloc函数,用来分配内存空间,出自于这个头文件

类似的还有calloc、free、realloc函数等,感兴趣的可以看一看

3、malloc函数:

函数原型:void * malloc(unsigned size);

功能是分配size字节的存储区。程序中需要两个int的空间所以乘2

默认的类型是void*,由于我设定了ret为int*类型,所以这里强制类型转换为int*

(leecode标准答案是没有这个强制转换的,其实我也有印象这一步可以自动转换,但是我用的Dev C++报错)

再放一个分割线:


那么肯定不可能就到此为止了,在今年校招(2024届校招)中,不知道大家有没有关注腾讯的招聘,直播间提到的就是这个问题。

不过大佬显然指的是用哈希表

什么是哈希表?

哈希表是一种数据结构,提供了快速的插入操作和查找操作

不管哈希表有多少数据,插入和查找的时间复杂度都是O(1),查找速度非常快

不过,哈希表基于数组,一旦数组被填满,性能就大不如前。

关于哈希表,推荐一个视频:

『教程』哈希表是个啥?_哔哩哔哩_bilibiliicon-default.png?t=N7T8https://www.bilibili.com/video/BV1qR4y1V7g6/?spm_id_from=333.337.search-card.all.click&vd_source=86629babf8e8eb6ebc7b7475ab3f61a2简单理解为:用时间换空间

先放代码(后面有详细解释,这里方便想自学的大佬):

struct hashTable {
    int key;
    int val;
    UT_hash_handle hh;
};

struct hashTable* hashtable;

struct hashTable* find(int ikey) {
    struct hashTable* tmp;
    HASH_FIND_INT(hashtable, &ikey, tmp);
    return tmp;
}

void insert(int ikey, int ival) {
    struct hashTable* it = find(ikey);
    if (it == NULL) {
        struct hashTable* tmp = malloc(sizeof(struct hashTable));
        tmp->key = ikey, tmp->val = ival;
        HASH_ADD_INT(hashtable, key, tmp);
    } else {
        it->val = ival;
    }
}

int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
    hashtable = NULL;
    for (int i = 0; i < numsSize; i++) {
        struct hashTable* it = find(target - nums[i]);
        if (it != NULL) {
            int* ret = malloc(sizeof(int) * 2);
            ret[0] = it->val, ret[1] = i;
            *returnSize = 2;
            return ret;
        }
        insert(nums[i], i);
    }
    *returnSize = 0;
    return NULL;
}

然后咱们就来详细解释这个代码。

已知,用哈希表查询,首先将要查找的东西作为参数进入一个函数,得到一个确定的数字

该数字就是哈希表中,查询结果的地址。

这样,本来我们需要一个个查询、比较的,现在只需要经过一次函数计算,一次查找。

将目光回到代码上:

struct hashTable {
    int key;
    int val;
    UT_hash_handle hh;
};

给出哈希表的结构,这个在哈希表的使用中是确定的,一般第一个是数值,第二个是位置(原本数组中的位置),第三个是一个句柄,链接前一个和后一个哈希表 

struct hashTable* hashtable;

struct hashTable* find(int ikey) {
    struct hashTable* tmp;
    HASH_FIND_INT(hashtable, &ikey, tmp);
    return tmp;
}

建立一个哈希表的指针,并且设置一个寻找函数

输入参数是我们要找的结果,并内置了HASH_FIND_INT函数

这个是头文件中包含的函数,主要参数有三个,

第一个就当默认参数,第二个是要找的值,第三个是哈希表的指针(做返回值用)

该函数的意义是:

找到ikey对应的值,如果哈希表中没有,tmp=NULL

如果找到了对应的值,tmp的第一个值为ikey,第二个是ikey对应的哈希表的val

简单来说就是一个查询操作,如果没有返回NULL,如果有返回对应的数值和位置

void insert(int ikey, int ival) {
    struct hashTable* it = find(ikey);
    if (it == NULL) {
        struct hashTable* tmp = malloc(sizeof(struct hashTable));
        tmp->key = ikey, tmp->val = ival;
        HASH_ADD_INT(hashtable, key, tmp);
    } else {
        it->val = ival;
    }
}

定义一个插入函数

find函数就是我们上面提到的寻找函数,会返回一个哈希表的指针,

如果返回的指针为NULL,也就是哈希表中没有我们要找的值,会再次定义一个分配了一个哈希表空间的指针tmp,并将对应的数值,以及数值在原本数组中的数值赋值给新建的哈希表

运用HASH_ADD_INT函数将这个新建的数据增加到哈希表中

如果返回的指针有数值,也就是哈希表中已经存在对应的结果了,找到了,那就更方便,直接记录

int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
    hashtable = NULL;
    for (int i = 0; i < numsSize; i++) {
        struct hashTable* it = find(target - nums[i]);
        if (it != NULL) {
            int* ret = malloc(sizeof(int) * 2);
            ret[0] = it->val, ret[1] = i;
            *returnSize = 2;
            return ret;
        }
        insert(nums[i], i);
    }
    *returnSize = 0;
    return NULL;
}

这是函数的主体

按照原始数组的顺序循环,依次查找target-nums[i]的结果,刚开始都是向哈希表内添加数,直到找到对应的结果

因为这里假设只存在唯一解,所以就没有必要考虑多种情况

简单画一个执行的逻辑吧:
 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/973036.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数电发票开票接口

全电发票&#xff0c;也叫数电发票&#xff0c;全称为全面数字化的电子发票。数电发票是依托可信身份体系和电子发票服务平台&#xff1b;以去介质、去版式、标签化、要素化、授信制、赋码制为基本特征&#xff1b;覆盖全领域、全环节、全要素的全新发票。与纸质发票具有同等法…

tkinter控件样式

文章目录 以按钮为例共有参数动态属性 tkinter系列&#xff1a; GUI初步&#x1f48e;布局&#x1f48e;绑定变量&#x1f48e;绑定事件&#x1f48e;消息框&#x1f48e;文件对话框&#x1f48e;控件样式扫雷小游戏&#x1f48e;强行表白神器 以按钮为例 tkinter对控件的诸…

05-Redis

1、Redis为什么快&#xff1f; 1、纯内存操作 2、单线程可以省去多线程时CPU上下文会切换的时间 3、渐进式ReHash、缓存时间戳 数组需要扩容的时候&#xff0c;他会维护两张hash表&#xff0c;比如第一张的数组长度为6&#xff0c;另一张的数组长度为12&#xff0c;在set和g…

JavaScript中的事件循环(event loop)机制

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 调用栈&#xff08;Call Stack&#xff09;⭐ 消息队列&#xff08;Message Queue&#xff09;⭐ 事件循环&#xff08;Event Loop&#xff09;⭐ 宏任务和微任务⭐ 示例⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇…

如何取消KEIL-MDK工程中出现的CMSIS绿色图标

如何取消KEIL-MDK工程中出现的CMSIS绿色图标&#xff1f;我以前经常遇到&#xff0c;不知道怎么搞&#xff0c;好像也不影响编译结果。以前问过其他人&#xff0c;但是不知道怎么搞&#xff0c;相信很多人也遇到过。水平有限&#xff0c;表达不清楚&#xff0c;见下图&#xff…

Java 反射调用自己写的对象方法

一、java 反射的定义 定义&#xff1a;JAVA反射机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b;对于任意一个对象&#xff0c;都能够调用它的任意一个方法&#xff0c;这种动态获取、调用对象方法的功能称为java语言的…

JavaScript 中的原型到底该如何理解?

JavaScript作为一个基于原型的OOP&#xff0c;和我们熟知的基于类的面向对象编程语言有很大的差异。如果不理解其中的本质含义&#xff0c;则无法深入理解JavaScript的诸多特性&#xff0c;以及由此产生的诸多“坑”。在讨论“原型”的概念之前&#xff0c;我们先来讨论一下“类…

APS系统设计经验分享(时间推导II - 2023.09)

在前一篇关于APS系统设计分享文章(《APS系统设计经验分享(时间推导 - 2023.03)》)中&#xff0c;我们提到将会分享使用OptaPlanner作为规划引擎开发APS系统过程中&#xff0c;遇到的一些时间相关的设计建议与异常情况分析。后来一直忙于项目工作&#xff0c;直到现在才想起仍欠…

CSS---flex布局

主要记录flex布局的要点以及实例 flex flex父标签的6个属性flex-direction: flex布局的方向flex-wrap: 是否可以换行flex-flow: flex-direction 和 flex-wrap 一起写justify-content&#xff1a;横向对齐方式align-items: 纵向对齐方式align-content: 有换行情况下的纵向对齐方…

DR IP-SoC China 2023 Day演讲预告 | 龙智Perforce专家解析芯片开发中的数字资产管理

2023年9月6日&#xff08;周三&#xff09;&#xff0c;龙智即将亮相于上海举行的D&R IP-SoC China 2023 Day&#xff0c;呈现集成了Perforce与Atlassian产品的芯片开发解决方案&#xff0c;助力企业更好、更快地进行芯片开发。 D&R IP-SoC China 2023 Day 是中国首个…

[论文笔记]ESIM

引言 这是经典论文Enhanced LSTM for Natural Language Inference的笔记。 本篇论文文是建立在自然语言推理(Natural Language Inference,NLI)任务上的。提出了简单的通过基于LSTM的序列推理模型效果到达了当时的SOTA水平。同时基于该模型,在局部推理建模层和推理组合层使用了…

三维模型OBJ格式轻量化压缩在大规模场景的加载和渲染的作用分析

三维模型OBJ格式轻量化压缩在大规模场景的加载和渲染的作用分析 OBJ格式是一种常用的三维模型文件格式&#xff0c;它存储了三维模型的几何信息和纹理坐标等相关属性。在大规模场景中加载和渲染三维模型时&#xff0c;OBJ格式的轻量化压缩对于提高性能和效率起到了重要的作用。…

Java多线程(Thread)详解之启动与中断

在我的前一篇博客中直接介绍了Thread的”五种“打开方式&#xff1a;Thread的”五种“打开方式https://blog.csdn.net/qq_45875349/article/details/132644717?spm1001.2014.3001.5501 但是还没有详细的对Thread类进行说明&#xff0c;这篇博客主要对Thread类进行介绍&#x…

软件产品选型测试POC测试怎么做?

软件poc测试 一、基本概述 软件选型测试是在软件采购的前提或采购过程中&#xff0c;通过对待选软件进行测试比对&#xff0c;筛选出适合的软件。通过对候选的软件进行量化或非量化的横向比对测试&#xff0c;为建设单位选择产品、供货方参加投标提供较直接的依据。 二、测试…

现在的校招面试,管你是不是应届生

作者&#xff1a;小傅哥 博客&#xff1a;https://bugstack.cn 沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01;&#x1f604; 一、他&#xff0c;上来打我&#xff01; 【字节】除了MQ解耦发奖&#xff0c;是否还有比MQ更优的解决方案&#xff1f;【字节】…

算法通关村16关 | 堆与滑动窗口问题结合

1. 堆与滑动窗口问题结合 题目 LeetCode239 给你一个整数数组nums&#xff0c;有一个大小为k的滑动窗口从数组的最左侧移动到数组的最右侧&#xff0c;你可以看到在滑动窗口内的k个数字&#xff0c;滑动窗口每次只向右移动一位&#xff0c;返回滑动窗口中的最大值。 思路 对于…

css 文字单行多行超出长度后显示 ...

0.超出… 1、单行文本超出 <div class"content">测试数据&#xff1a;css单行文本超出显示省略号--------</div><style> .content{width: 200px;height: 200px;overflow:hidden;white-space: nowrap;text-overflow: ellipsis;-o-text-overflow:el…

linux信号量

通过学习linux的信号量&#xff0c;对linux的信号量进行了编程。

QT(9.4)tcp通信,数据库,opencv,

作业&#xff1a; 1.服务器 头文件&#xff1a; #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpSocket>//客户端头文件 #include <QMessageBox>//消息对话框头文件 #include <QTcpServer>//服务器头文件 #include <list>…

docker报错解决方法

ERROR: readlink /var/lib/docker/overlay2/l: invalid argument 注意&#xff1a;会清空已有安装 sudo service docker stop sudo rm -rf /var/lib/docker sudo service docker start