Letcode 两数之和

news2025/3/12 1:05:29

 

1. 两数之和

给定一个整数数组 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
  • 只会存在一个有效答案

进阶:你可以想出一个时间复杂度小于 O(n^2) 的算法吗?

我的答案:

暴力破解法:

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

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

int main(){
    int nums[] = {2, 7, 11, 15};
    int target = 9;
    int numsSize = sizeof(nums) / sizeof(nums[0]);
    int returnSize = 0;
    int* result = twoSum(nums, numsSize, target, &returnSize);
    if(result != NULL){
        printf("[%d, %d]\n", result[0], result[1]);
        free(result);
    }
    return 0;
}


​

哈希表解法:

C语言解法

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

struct hash_node {
    int key;
    int val;
    struct hash_node* next;
};

struct hash_table {
    struct hash_node** nodes;
    int size;
};

struct hash_table* create_hash_table(int size) {
    struct hash_table* table = (struct hash_table*)malloc(sizeof(struct hash_table));
    table->nodes = (struct hash_node**)calloc(size, sizeof(struct hash_node*));
    table->size = size;
    return table;
}

void destroy_hash_table(struct hash_table* table) {
    for (int i = 0; i < table->size; i++) {
        struct hash_node* node = table->nodes[i];
        while (node != NULL) {
            struct hash_node* next = node->next;
            free(node);
            node = next;
        }
    }
    free(table->nodes);
    free(table);
}

int hash(int key, int size) {
    return (key % size + size) % size;
}

void hash_table_put(struct hash_table* table, int key, int val) {
    int idx = hash(key, table->size);
    struct hash_node* node = table->nodes[idx];
    while (node != NULL) {
        if (node->key == key) {
            node->val = val;
            return;
        }
        node = node->next;
    }
    struct hash_node* new_node = (struct hash_node*)malloc(sizeof(struct hash_node));
    new_node->key = key;
    new_node->val = val;
    new_node->next = table->nodes[idx];
    table->nodes[idx] = new_node;
}

int hash_table_get(struct hash_table* table, int key) {
    int idx = hash(key, table->size);
    struct hash_node* node = table->nodes[idx];
    while (node != NULL) {
        if (node->key == key) {
            return node->val;
        }
        node = node->next;
    }
    return -1;
}

int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
    struct hash_table* table = create_hash_table(numsSize);
    for (int i = 0; i < numsSize; i++) {
        int complement = target - nums[i];
        int j = hash_table_get(table, complement);
        if (j != -1) {
            int* result = (int*)malloc(2 * sizeof(int));
            result[0] = j;
            result[1] = i;
            destroy_hash_table(table);
            *returnSize = 2;
            return result;
        }
        hash_table_put(table, nums[i], i);
    }
    destroy_hash_table(table);
    *returnSize = 0;
    return NULL;
}

int main() {
    int nums[] = {2, 7, 11, 15};
    int target = 9;
    int returnSize;
    int* result = twoSum(nums, 4, target, &returnSize);
    if (result != NULL) {
        printf("[%d, %d]\n", result[0], result[1]);
        free(result);
    }
    return 0;
}

C++解法:

#include <iostream>
#include <vector>
#include <unordered_map>

using namespace std;

vector<int> twoSum(vector<int>& nums, int target) {
    unordered_map<int, int> hashTable;
    for (int i = 0; i < nums.size(); i++) {
        int complement = target - nums[i];
        if (hashTable.count(complement)) {
            return {hashTable[complement], i};
        }
        hashTable[nums[i]] = i;
    }
    return {};
}

int main() {
    vector<int> nums = {2, 7, 11, 15};
    int target = 9;
    vector<int> result = twoSum(nums, target);
    for (int i = 0; i < result.size(); i++) {
        cout << result[i] << " ";
    }
    cout << endl;
    return 0;
}

C和C++实现时的区别:

 该代码与之前使用C语言实现的代码类似,也是通过遍历数组和使用哈希表来查找两个数之和等于目标值的下标。不同的是,该代码使用了C++的vector和unordered_map来实现,更加方便和易读。

什么是哈希表?

哈希表(Hash Table)是一种基于哈希函数(Hash Function)实现的数据结构,用于支持快速的插入、删除、查找操作。它的核心思想是通过将元素的关键字映射为一个索引(即哈希值),将元素存储在数组中对应索引的位置上,从而实现快速查找的目的。

哈希表包括两个基本操作:插入和查找。对于插入操作,我们首先计算出待插入元素的哈希值,然后将元素存储在哈希值对应的位置上;对于查找操作,我们先计算出目标元素的哈希值,然后在哈希表中查找是否存在该元素。

哈希表的优点是可以实现快速的插入、删除、查找操作,时间复杂度为O(1)(在哈希函数的选择、哈希冲突的处理等方面有影响)。缺点是在处理哈希冲突时需要额外的时间和空间成本,并且哈希函数的选择对哈希表的性能影响很大。

解析:

哈希表能够降低这个题目的时间复杂度的原因在于,哈希表的查找操作的时间复杂度为O(1),因此可以通过将每个元素的值作为哈希表的键,将每个元素的下标作为哈希表的值,来加速查找过程。

具体地,对于给定的目标值target和数组nums,我们可以遍历一遍数组nums,在遍历的过程中,对于每个元素nums[i],我们计算出其与目标值的差值complement=target-nums[i],然后在哈希表中查找是否存在该差值。如果存在,说明我们已经找到了两个数之和为目标值target,可以直接返回它们的下标;否则,将当前元素nums[i]插入到哈希表中,继续遍历数组。

由于哈希表的查找操作的时间复杂度为O(1),因此总时间复杂度为O(n)。相比于暴力枚举的O(n^2)时间复杂度,哈希表能够显著地降低时间复杂度,提高程序的效率。

反思总结:

从这个题目我们可以学到以下几个方面的知识和技能:

  1. 数据结构与算法:这个题目涉及到数组的遍历和哈希表的使用,因此需要熟练掌握数组和哈希表的基本操作和相关算法。

  2. 编程语言的基本语法和使用:这个题目需要使用C语言实现,因此需要熟悉C语言的基本语法和常用的函数库。

  3. 问题解决思路的培养:这个题目需要我们思考如何通过一定的数据结构和算法来解决问题,因此需要培养问题解决思路和方法的能力。

  4. 实践能力的提升:这个题目需要我们将理论知识转化为实践能力,因此需要多做练习,提高编程实践能力。

总之,这个题目可以帮助我们加深对数据结构与算法、编程语言和问题解决思路的理解和掌握,提高实践能力和解决实际问题的能力。

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

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

相关文章

Wi-Fi 6(802.11ax)解析12:下行OFDMA接入机制(DL-OFDMA)

序言 在介绍完802.11ax的信道接入以及其触发帧机制后&#xff0c;本文着重介绍下行OFDMA的接入机制&#xff08;即DL-OFDMA&#xff09; 下行OFDMA接入机制&#xff08;DL-OFDMA&#xff09; OFDMA是一种多用户通信机制&#xff0c;其只适用于802.11ax AP和802.11ax用户之间…

ChatGPT 学习 ES lucene 底层写入原理,源码

一直有个疑问“学习最新版lucene 数据写入相关的源码&#xff0c;应该看哪些源码&#xff0c;以什么顺序看&#xff08;先看什么&#xff0c;后看什么&#xff09;&#xff1f;” 对于Lucene的数据写入过程&#xff0c;可以分为以下几个阶段 在学习Lucene的数据写入相关的源码…

FTP服务

一、FTP的简介 FTP是FileTransferProtocol&#xff08;文件传输协议&#xff09;的英文简称&#xff0c;而中文简称为“文传协议”。用于Internet上的控制文件的双向传输。同时&#xff0c;它也是一个应用程序&#xff08;Application&#xff09;。基于不同的操作系统有不同的…

C++笔记——第十四篇 哈希

目录 一、unordered系列关联式容器 1.1 unordered_map 1.1.1 unordered_map的文档介绍 1.1.2 unordered_map的接口说明 二、 底层结构 2.1 哈希概念 2.2 哈希冲突 2.3 哈希函数 2.4 哈希冲突解决 2.4.1 闭散列 1. 线性探测 2. 二次探测 2.4.2 开散列 三、 哈希的应用 …

200万奖金广聚天下算法英雄,第二届广州·琶洲算法大赛要来了!

随着深度学习不断驱动技术创新&#xff0c;人工智能加速与实体经济深度融合发展。作为中国首个自主研发、开源开放的产业级深度学习平台&#xff0c;飞桨与百度自研的产业级知识增强文心大模型&#xff0c;共同构筑了产业智能化基座&#xff0c;并联合产学研用各方生态力量&…

学习风`宇博客用户权限菜单模块

文章目录 用户-角色-菜单-资源 各表关系图菜单 和 路由菜单表及分析分析 /api/admin/user/menus接口MenuServiceImpl#listUserMenus接口返回示例及分析 前端代码分析menu.jsSideBar.vue 接口权限控制资源表 及 分析分析 WebSecurityConfig权限控制整体流程先说登录UserDetailsS…

ChatGPT 有什么新奇的使用方式?

你别说&#xff0c;你还真别说&#xff0c;我对象一般用它谈恋爱&#xff01;&#xff01;&#xff01; 我对象在谈一种很新的恋爱&#xff0c;不建议模仿&#xff0c;因为根本停不下来&#xff01; 事情是这样的&#xff0c;我最近开始对ChatGPT感兴趣&#xff0c;但我这个技…

AppArmor零知识学习十四、实操与实践(2)

本文内容参考&#xff1a; Linux安全模块AppArmor总结-CSDN博客&#xff0c; apparmor首页、文档和下载 - 应用程序访问控制系统 - OSCHINA - 中文开源技术交流社区&#xff0c; AppArmor GitBook&#xff0c; AppArmor配置&#xff08;二&#xff09;_domybest_nsg的博客…

CESM 地球系统模式

详情点击链接&#xff1a;地球系统模式&#xff08;CESM&#xff09; CESM 运行的系统和软件环境 1.CESM需要什么运行环境 2.CESM2.0运行环境的搭建CESM 运行需要掌握的Linux及编译 1.Linux 2.Linux编译 3.基于Make 和CMake的编译体系CESM 的基本结构 1.CESM的几大功能模块 2…

德赛西威上海车展重磅发布Smart Solution 2.0,有哪些革新点?

4月18日&#xff0c;全球瞩目的第二十届上海车展盛大启幕&#xff0c;作为国际领先的移动出行科技公司&#xff0c;德赛西威携智慧出行黑科技产品矩阵亮相&#xff0c;并以“智出行 共创享”为主题&#xff0c;重磅发布最新迭代的智慧出行解决方案——Smart Solution 2.0。 从…

“量子+金融”!摩根大通和QC Ware拓展量子深度对冲

​ &#xff08;图片来源&#xff1a;网络&#xff09; 近日&#xff0c;QC Ware和摩根大通完成了一项关于量子“深度对冲”的研究&#xff0c;为提高未来的金融服务风险应对能力铺平了道路。 利用市场摩擦和交易约束的数据驱动模型&#xff0c;可以降低投资组合的风险。相关论…

Flink学习——基本概述

目录 一、Flink概述 二、单机版安装配置 1.开启hadoop 2.解压Flink压缩包 3.修改文件名 4.开启客户端 5.访问webUI 三、集群配置 1.jobmanager配置 2.master配置 3.workers配置 4.分发配置 5.开启Flink集群 6.访问webUI 7.查看Job Manager 8.查看Task Managers…

不同批次板子采集到的传感器压力值不同

问题描述&#xff1a; M340B空压机主控板在接正常压力气源时&#xff0c;显示屏显示压力值过高并报警。 问题排查&#xff1a; 确认可能的故障点&#xff1a;压力传感器、硬件电路&#xff08;供电电路、分压电路、ADC采样电路等&#xff09;、单片机、软件&#xff1b; 排…

MySQL-----表的约束

文章目录 前言一、空属性二、默认值三、列描述四、zerofil五、主键六、自增长七、唯一键八、外键总结 前言 真正约束字段是数据类型,但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性, 从业务逻辑角度保证数据的正确性.比如有一个字段是email,要求是唯一的…

十八、市场活动备注:修改

功能需求 用户在市场活动明细页面,点击"修改"市场活动备注的图标,弹出修改市场活动备注的模态窗口; 用户在修改市场活动备注的模态窗口,填写表单,点击"更新"按钮,完成修改市场活动备注的功能. *备注内容不能为空 *修改成功之后,关闭模态窗口,刷新备注列表…

VC++ | 编译、运行Debug版本报错-20230419-01

VC++ | 编译、运行Debug版本报错-20230419-01 1.LOG如下 1>------ 已启动生成: 项目: CamManager, 配置: Debug Win32 ------ 1>stdafx.cpp 1>UnicodeLib.cpp 1>MultiLanguage.cpp 1>d:\01_project\02_grain\pdv-tools

DSAI130D 3BSE003127R1在机器视觉系统中主要负责光束调制

DSAI130D 3BSE003127R1在机器视觉系统中主要负责光束调制 如今&#xff0c;随着工业4.0的到来&#xff0c;机器视觉技术在工业自动化中逐渐起着十分重要的地位&#xff0c;机器视觉技术的不断创新&#xff0c;推动了工业自动化、智慧安防以及人工智能等行业的进步&#xff0c;…

Maven打包跳过测试的5种方式

Maven打包跳过测试的5种方式 1、命令行方式跳过测试 我们可以通过使用命令将项目打包&#xff0c;添加跳过测试的命令就可以了&#xff0c;可以用两种命令来跳过测试&#xff1a; -DskipTeststrue mvn package -DskipTeststrue-DskipTeststrue&#xff0c;不执行测试用例&a…

SpringCloud网关——GateWay

GateWay 本专栏学习内容来自尚硅谷周阳老师的视频 有兴趣的小伙伴可以点击视频地址观看 概述 SpringCloud Gateway 是 Spring Cloud 的一个全新项目&#xff0c;基于 Spring 5.0Spring Boot 2.0 和 Project Reactor 等技术开发的网关&#xff0c;它旨在为微服务架构提供一种简…

c++11 标准模板(STL)(std::queue)(三)

定义于头文件 <queue> template< class T, class Container std::deque<T> > class queue; std::queue 类是容器适配器&#xff0c;它给予程序员队列的功能——尤其是 FIFO &#xff08;先进先出&#xff09;数据结构。 类模板表现为底层容器的包…