两数之和(10 月 9 日)
题目描述
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
解法一
时间复杂度: O(n^2)
本解法的思路主要是利用差值来查找需要的值,步骤如下:
- 循环数组,从后往前遍历
- 用 pop 取出数组的最后一个数(目的是为了防止同一个元素使用两遍),用 target 减这个数得到要查找的目标数,在原数组中用 indexOf 查找目标数
- 如果有对应的值,那么两个索引值就是数组的长度和 indexOf
具体实现如下:
var twoSum = function (nums, target) {
let i = nums.length;
while (i > 1) {
let num = nums.pop();
let findIndex = nums.indexOf(target - num);
if (findIndex > -1) {
return [nums.length, findIndex];
}
i--;
}
};
解法二
时间复杂度:
本解法的思路是新建一个 hasMap,遍历数组,如果能找到 taget-nums[i] 的值就返回,找不到就 set
- 创建一个 Map,并循环数组
- 用与循环到的值对应的目标值做 key,其对应的下标做 value
- 遍历值的时候,如果能在 map 中找到其对应的目标值,就把目标值 get 出来(因为 map.get 是用键名找对应的键值),而另一个对应的下标值就是当前的下标。
var twoSum = function (nums, target) {
let indexMap = new Map();
let i = 0;
while (i < nums.length) {
if (indexMap.has(nums[i])) {
return [indexMap.get(nums[i]), i]
} else {
indexMap.set(target - nums[i], i);
}
i++;
}
};
整数反转(10 月 9 日)
题目描述
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
前提思路: 从题目中的提示我们可以知道,超出数值范围限制的整数翻转后返回为 0(超出限制表示整数转换结果不等于自身),假设我们需要返回的值为 result,从提示可以得到:如果 result 超出了,那么 result|0 === 0 否则:result|0 === result
解法一
思路:
从给定的值得末位开始取值,一步步依次拼接到目标值上(取余的方法):
- 首先给定 result = 0,
每一次取余的结果 + (上一次取余的结果 * 10) = 当前拼接好的值,上一次取余的结果* 10 是表示进位,如果直接进行字符串拼接会导致最后的正负号不好区分,直接进行数字相加会导致结果错误。 - 用 x / 10 去除末位,| 0 强制转换为32位有符号整数,取出末位后,把剩下的数字再进行取余拼接,
- 通过 | 0 取整,无论正负,只移除小数点部分(正数向下取整,负数向上取整)。
- result | 0 超过32位的整数转换结果不等于自身,可用作溢出判断。
var reverse = function (x) {
let result = 0;
while (x !== 0) {
result = result * 10 + x % 10;
x = (x / 10) | 0;
}
return (result | 0) === result ? result : 0;
};
回文数(10 月 10)
题目描述
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
解法一
暴力破解,由于回文数是翻转后的数和翻转前相同,所以直接使用字符串翻转就可以实现
var isPalindrome = function(x) {
return x.toString() === x.toString().split("").reverse().join("");
};