算法之旅:LeetCode中的两数之和挑战

前言

在计算机编程的世界里,LeetCode已经成为了一个不可或缺的训练场所,每一个挑战都是一次思维的较量,一次算法的角逐。其中,「两数之和」题目一直是许多刷题者入门的第一道门槛,看似简单,却蕴含着丰富的解题思路和算法技巧。本文将带您踏上一场探索之旅,深入解析LeetCode中「两数之和」题目的多种解法,带您领略编程世界中的智慧风景。

随着我们的步伐,让我们一起探索这些算法的奥秘,揭示出它们背后的逻辑,以及如何在实际编程中运用它们。无论您是刚刚入门的新手,还是经验丰富的老手,本文都将为您呈现出新的思路和启发,让您在LeetCode之路上更加游刃有余,挑战更高难度的问题。

现在,让我们开始这段关于「两数之和」多种解法的探索之旅吧!

正文

  • 我们正在开始解题前先来聊聊JavaScript中的几种简单数据类型
js 复制代码
    var str = 'hello world' //String
var n = 123 // Number
var flag = false|| true //Boolean
var u = undefined 
var nu = null

var obj = {
    a: 1,
    b:'abc'
}
obj.c = 2

这些类型包括字符串(String)、数字(Number)、布尔值(Boolean)、未定义(Undefined)和空(Null)。 obj 是一个对象,包含了三个属性:abca 的值为 1b 的值为 'abc',而 c 是在代码的最后赋值的,其值为 2

  • 我们再来了解一下JavaScript中数组的中的一些操作
js 复制代码
    var arr = []
arr.push('hello')
arr.unshift(123)
arr.pop()
arr.shift()//头部删除

console.log(arr);

这段代码操作了一个空数组 arr

  1. arr.push('hello') 将字符串 'hello' 添加到数组的末尾。
  2. arr.unshift(123) 将数字 123 添加到数组的开头。
  3. arr.pop() 移除数组的最后一个元素。
  4. arr.shift() 移除数组的第一个元素。

最后,通过 console.log(arr) 打印出数组 arr 的内容,由于先后进行了 pop 和 shift 操作,数组最终为空。

  • 然后我们来看看这一道两数之和的题目,并分析下它的解法:
  1. 暴力法: 遍历数组,对于每一个元素,再遍历其后的元素,判断它们的和是否等于目标值。时间复杂度为 O(n^2),空间复杂度为 O(1)。

2.indexOf方法 来在数组中查找目标值的索引。indexOf 方法是 JavaScript 数组原型对象上的一个方法,它用于查找给定元素在数组中第一次出现的位置,并返回其索引。如果数组中不存在该元素,则返回 -1。
解法一

js 复制代码
    
for(var i = 0; i < nums.length; i++){
         for(var j = i + 1; j < nums.length; j++ ){
             if(nums[i] + nums[j] == target){
                 return [i,j]
            }
        }
     }

这段代码使用了暴力法解决了"两数之和"问题。它通过两层嵌套的循环来遍历数组,对于每对不同的元素,检查它们的和是否等于目标值,如果找到了符合条件的两个数,则返回它们的索引。

  • 外层循环从数组的第一个元素开始遍历,直到倒数第二个元素。
  • 内层循环从外层循环的当前元素的下一个元素开始遍历,直到数组的最后一个元素。
  • 在每次遍历中,检查两个元素的和是否等于目标值,如果是,则返回它们的索引。 虽然这种方法简单直观,但在数组较大时效率较低,因为需要进行大量的重复计算。相比之下,使用哈希表的方法能够将时间复杂度降低到 O(n),更加高效。

既然第一种解法不够高效,那我们去思考一下是否有更高效的解法呢?我们来看看第二种解法吧!

js 复制代码
    for(var i =0; i < nums.length -1; i++){

         var res = target - nums[i]
         var index = nums.indexOf(res, i+1)

        if(index !== -1){
            return [i,index]
         }

     }

这段代码也是一种解决"两数之和"问题的方法,但是它在内部循环中使用了 indexOf 方法来查找数组中是否存在满足条件的数。

  • 外层循环遍历数组中的每个元素,直到倒数第二个元素。
  • 在每次外层循环中,计算目标值与当前元素的差值 res
  • 使用 indexOf 方法从当前元素的下一个位置开始查找差值 res 在数组中的索引,如果找到,则返回当前元素的索引和差值 res 的索引。
  • 如果未找到,则继续下一次循环。

解法三:使用了一个对象 diff 来存储每个数字与目标值的差值及其对应的索引。通过在每次循环中检查对象中是否存在某个值

js 复制代码
       var diff = {}

     for (var i = 0; i < nums.length; i++) {
        if (diff[nums[i]] !== undefined) {  // 查找对象中是否存在值,是不需要循环的
             return [diff[nums[i]], i]
         }
         diff[target - nums[i]] = i
     }
  • 首先,创建一个空对象 diff,用于存储数字与目标值的差值及其对应的索引。
  • 然后,使用一个循环遍历数组中的每个元素。
  • 在每次循环中,检查对象 diff 中是否已经存在当前元素对应的差值。如果存在,则说明找到了两个数,它们的和等于目标值,直接返回它们的索引;如果不存在,则将当前元素的差值及其索引存入对象 diff 中。
  • 如果遍历完整个数组都未找到符合条件的两个数,则返回空数组。

总结

在解决"两数之和"问题时,我们探讨了三种不同的解决方法:暴力法、使用 indexOf 方法的线性搜索和利用差值存储的优化方法。

首先,我们介绍了暴力法,它通过双重循环遍历数组,逐个检查所有可能的数对,直到找到满足条件的数对。虽然这种方法简单直接,但时间复杂度为 O(n^2),效率较低。

其次,我们讨论了使用 indexOf 方法的方法,它在内部循环中使用了 indexOf 方法来查找目标值的索引。尽管代码简洁,但由于 indexOf 方法的时间复杂度为 O(n),因此整体效率仍然较低。

最后,我们介绍了利用差值存储的优化方法,通过一个对象存储每个数字与目标值之间的差值及其索引,避免了多次遍历数组或线性搜索,提高了算法的效率。这种方法的时间复杂度为 O(n),空间复杂度为 O(n),是解决"两数之和"问题的较优解法之一。

总的来说,选择合适的解法取决于具体的情况和需求。在面对大规模数据时,我们应该选择效率更高的算法,以提高程序的运行效率和性能。通过学习和掌握不同的解法,我们可以更好地理解算法设计和优化的原理,提高自己的编程能力和解决问题的能力。

最后,希望本文能够对您有所启发,让您在解决类似问题时更加游刃有余。让我们一起努力,不断进步,成为更优秀的程序员

相关推荐
燃先生._.10 分钟前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
XH华31 分钟前
初识C语言之二维数组(下)
c语言·算法
南宫生1 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
不想当程序猿_1 小时前
【蓝桥杯每日一题】求和——前缀和
算法·前缀和·蓝桥杯
高山我梦口香糖1 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
落魄君子1 小时前
GA-BP分类-遗传算法(Genetic Algorithm)和反向传播算法(Backpropagation)
算法·分类·数据挖掘
菜鸡中的奋斗鸡→挣扎鸡1 小时前
滑动窗口 + 算法复习
数据结构·算法
Lenyiin2 小时前
第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ
c++·算法·leetcode·周赛·lenyiin
郭wes代码2 小时前
Cmd命令大全(万字详细版)
python·算法·小程序