力扣算法刷题记录---day01

力扣的算法题----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) 开辟了一个数组空间
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值