一天一大 leet(两数之和 II - 输入有序数组)难度:简单-Day20200720
时间:2022-07-25
本文章向大家介绍一天一大 leet(两数之和 II - 输入有序数组)难度:简单-Day20200720,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目:
给定一个已按照升序排列的有序数组,找到两个数使得它们相加之和等于目标数。
函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。
说明:
- 返回的下标值(index1 和 index2)不是从零开始的。
- 你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例:
输入: numbers = [2, 7, 11, 15], target = 9
输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
抛砖引玉
看到这道题有点小感触,想到最开始刷 leetcode 就是被这道简单的提劝退的
印象深刻,现在还记得,第一看好简单,马上就用 indexOf 写了,然后肯定没通过,泪目
/**
* @param {number[]} numbers
* @param {number} target
* @return {number[]}
*/
var twoSum = function (numbers, target) {
let index1 = 0,
index2 = -1
while (index1 < numbers.length) {
index2 = numbers.indexOf(target - numbers[index1])
if (index2 === -1) {
index1++
} else {
return index1 < index2
? [index1 + 1, index2 + 1]
: [index2 + 1, index1 + 1]
}
}
return index1 < index2
? [index1 + 1, index2 + 1]
: [index2 + 1, index1 + 1]
}
现在看,那时候不仅没注意复杂度的问题,而且逻辑上也有些问题,没有考虑 target 由 numbers 有两个相同是数组成的情况
来看看原来看到的题解吧,之前一直看不明白,为什么要把差值存起,刷了动态规划的题, 再回来看这个就觉得好简单
- 声明一个数组 a 记录每个 numbers 中的元素与 target 直接的差值
- 如果:x+y=target,那么 target-x=y,target-y=x
- 当遍历到满足要求的值直接返回,不然存贮对应的差值到 a 的对应索引位置
/**
* @param {number[]} numbers
* @param {number} target
* @return {number[]}
*/
var twoSum = function (numbers, target) {
var a = []
for (var i = 0, len = numbers.length; i < len; i++) {
var tmp = target - numbers[i]
if (a[tmp] !== undefined) return [a[tmp] + 1, i + 1]
a[numbers[i]] = i
}
}
- 感觉其实如果数组换成 map 会更好理解
- 毕竟标记数据时哈希比 index 就到的多
- 时间和空间复制度基本差不多
/**
* @param {number[]} numbers
* @param {number} target
* @return {number[]}
*/
var twoSum = function (numbers, target) {
let dp = new map(),
len = numbers.length
for (let i = 0; i < len; i++) {
let tmp = target - numbers[i]
if (dp.has(tmp)) {
return [dp.get(tmp) + 1, i + 1]
}
dp.set(numbers[i], i)
}
}
二分法查找
以上的解法都没有用到升序排列这个条件,其实看到有序最应该想到的就是二分法查找
- 从 numbers 取出一个元素 numbers[i],在 numbers 中 i 之后的元素中查找 target - numbers[i]
- 查找到之间返回,不然依次从 numbers 中取后面一个元素
/**
* @param {number[]} numbers
* @param {number} target
* @return {number[]}
*/
var twoSum = function (numbers, target) {
let len = numbers.length,
left = 0,
right = len - 1,
mid = 0
for (let i = 0; i < len; ++i) {
left = i + 1
while (left <= right) {
mid = parseInt((right - left) / 2) + left
if (numbers[mid] == target - numbers[i]) {
return [i + 1, mid + 1]
} else if (numbers[mid] > target - numbers[i]) {
right = mid - 1
} else {
left = mid + 1
}
}
}
return [-1, -1]
}
双指针
- 从二分法查找中会发现,其实不用查找完二分的节点就已经知道当前这个 i 是否能满足要求
- 那当知道这个 i 不在满足要求时就没有必要接着二分了,直接切换 i 就可以
- 那 left 和 right 就成立两个动态的索引指针了
/**
* @param {number[]} numbers
* @param {number} target
* @return {number[]}
*/
var twoSum = function (numbers, target) {
let left = 0,
right = numbers.length - 1
while (left < right) {
// 当两个指针对应的元素和等于 target直接返回
if (numbers[left] + numbers[right] === target) {
return [left + 1, right + 1]
} else if (numbers[left] + numbers[right] > target) {
// 当和大于target,则右侧减小(较大的值减小)
right--
} else {
// 当和小于target,则左侧增大(较小的值增大)
left++
}
}
}
- Mysql忘记root密码的恢复方法
- 深入剖析Go语言编程中switch语句的使用
- MySQL中DDL、DML、DCL的那些语句
- 如何查看spark与hadoop、kafka、Scala、flume、hive等兼容版本【适用于任何版本】
- golang实现简单的udp协议服务端与客户端示例
- Oracle 12c系列(三)|存储资源隔离 Flex Diskgroup
- Scala的map实现key和value排序及各种排序比较等知识讨论
- crontab执行后发送邮件到指定邮箱
- PHP-魔术变量
- 日志分析实战之清洗日志小实例7:查看样本数据,保存统计数据到文件
- hdu----(1671)Phone List(Trie带标签)
- PHP-数组
- hdu---1506(Largest Rectangle in a Histogram/dp最大子矩阵)
- 日志分析实战之清洗日志小实例6:获取uri点击量排序并得到最高的url
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Flutter基础widgets教程-FlutterLogo篇
- 配置压缩版mysql 5.7以上版本
- nutz 自定义sql的使用
- nutz 中 子模块 参数的使用。
- java向mysql插入数据乱码问题解决
- java向数据库中插入中文出现乱码
- Flutter基础widgets教程-FractionallySizedBox篇
- 关于myeclipse控制台输出中文乱码的问题
- nutz 自定义查询 分页 取值
- jquery-uploadifyv3.2.1 文件上传插件 学习
- Flutter基础widgets教程-Icon篇
- Redis:持久化
- Flutter基础widgets教程-IconButton篇
- Flutter基础widgets教程-Image篇
- Go - 学习 grpc.Dial(target string, opts …DialOption) 的写法