力扣的算法题----day01
力扣–231. 2 的幂
描述
难度简单525收藏分享切换为英文接收动态反馈
给你一个整数 n
,请你判断该整数是否是 2 的幂次方。如果是,返回 true
;否则,返回 false
。
如果存在一个整数 x
使得 n == 2x
,则认为 n
是 2 的幂次方。
示例 1:
输入:n = 1
输出:true
解释:20 = 1
示例 2:
输入:n = 16
输出:true
解释:24 = 16
示例 3:
输入:n = 3
输出:false
示例 4:
输入:n = 4
输出:true
示例 5:
输入:n = 5
输出:false
提示:
-231 <= n <= 231 - 1
**进阶:**你能够不使用循环/递归解决此问题吗?
答案
/**
* @param {number} n
* @return {boolean}
*/
var isPowerOfTwo = function(n) {
return n > 0 && (n&(n-1) === 0);
};
题解
二进制与运算,该算法中可以知道,2的平方的数都是只有一个1,剩余均为0,比如2:10 ,4:100,
每一个二进制数-1都会出现本二进制位为0,其他位数为1的现象,例如: 1:01,3:011,
按位与运算后,其结果就是0。
再加上二的n次方本来就是大于0的。既节省了空间,又节省了时间。
力扣–136. 只出现一次的数字
描述
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
示例 2:
输入: [4,1,2,1,2]
输出: 4
答案
方法1:记录次数
- 遍历数组,同时建立哈希表来记录每个数字在数组中出现的次数
- 遍历哈希表找到只出现一次的数字
- 时间复杂度O(n)
- 空间复杂度O(n)
方法1.5 :记录数字
-
在遍历数组时记录出现过的数字:如果当前数字没有出现过则将数字记下,如果当前数字已经出现过了,则将其从记录表中删去。
-
最后记录中剩下的数字就是只出现一次的数字
-
时间复杂度O(n)
-
空间复杂度O(n)
方法2:异或(XOR)
-
如果我们对0和二进制位做XOR运算,得到的仍然是这个二进制位
-
如果我们对相同的二进制位做XOR运算返回的结果是0
-
XOR满足交换律和结合律
-
时间复杂度O(n),其中 nn 是数组长度。只需要对数组遍历一次。
-
空间复杂度O(1)
/**
* @param {number[]} nums
* @return {number}
*/
var singleNumber = function(nums) {
let ret = 0;
nums.forEach(num=>{
ret ^= num;
});
return ret;
};
力扣- 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(n2) 的算法吗?
答案:
方法一:
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
for(let i=0;i<nums.length;i++){
for(let j=0;j<nums.length;j++){
if(nums[i]+nums[j]===target && i!==j){
return [i,j];
}
}
}
};
复杂度:
- 时间复杂度:O(n^2) 数组长度是n 算法大概执行了多少次
- 空间复杂度: O(1) i和j都是一个普通的数字
方法二:
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
let obj = {}
for(let i=0;i<nums.length;i++){
let num = nums[i]
let n = target - num
if(num in obj){
return [i,obj[num]]
}else{
obj[n] = i
}
}
};
复杂度:
- 时间复杂度:O(n) 数组长度是n 算法大概执行了多少次
- 空间复杂度: O(n) 开辟了一个数组空间