提交 ab37a5ab 编写于 作者: L luzhipeng

feat: 位操作相关题目

上级 44a0fdf8
/*
* @lc app=leetcode id=231 lang=javascript
*
* [231] Power of Two
*
* https://leetcode.com/problems/power-of-two/description/
*
* algorithms
* Easy (41.66%)
* Total Accepted: 218.3K
* Total Submissions: 523.1K
* Testcase Example: '1'
*
* Given an integer, write a function to determine if it is a power of two.
*
* Example 1:
*
*
* Input: 1
* Output: true
* Explanation: 2^0 = 1
*
*
* Example 2:
*
*
* Input: 16
* Output: true
* Explanation: 2^4 = 16
*
* Example 3:
*
*
* Input: 218
* Output: false
*
*/
/**
* @param {number} n
* @return {boolean}
*/
var isPowerOfTwo = function(n) {
if (n <= 0) return false;
while (n > 2) {
n = n / 2;
}
return Number.isInteger(n);
// return Number.isInteger(Math.log2(n));
};
/*
* @lc app=leetcode id=322 lang=javascript
*
* [322] Coin Change
*
* https://leetcode.com/problems/coin-change/description/
*
* algorithms
* Medium (29.25%)
* Total Accepted: 175K
* Total Submissions: 591.9K
* Testcase Example: '[1,2,5]\n11'
*
* You are given coins of different denominations and a total amount of money
* amount. Write a function to compute the fewest number of coins that you need
* to make up that amount. If that amount of money cannot be made up by any
* combination of the coins, return -1.
*
* Example 1:
*
*
* Input: coins = [1, 2, 5], amount = 11
* Output: 3
* Explanation: 11 = 5 + 5 + 1
*
* Example 2:
*
*
* Input: coins = [2], amount = 3
* Output: -1
*
*
* Note:
* You may assume that you have an infinite number of each kind of coin.
*
*/
/**
* @param {number[]} coins
* @param {number} amount
* @return {number}
*/
// coinChange([1,2,5], 11) =
// (coinChange([1,2], 6) + 1, coinChange([1,2], 1) + 2)
var coinChange = function(coins, amount) {
// if (amount === 0) {
// return 0;
// }
// if (amount < Math.min(...coins)) return -1;
// const dp = Array(amount + 1);
// for (let i = 0; i < dp.length; i++) {
// dp[i] = Number.MAX_VALUE;
// }
// dp[0] = 0;
// for (let i = 1; i < dp.length; i++) {
// for (let j = 0; j < coins.length; j++) {
// if (i - coins[j] >= 0) {
// dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);
// }
// }
// }
// return dp[dp.length - 1] === Number.MAX_VALUE ? -1 : dp[dp.length - 1];
// [186,419,83,408]\n6249
if (amount === 0) return 0;
const sortedCoins = coins.sort((a, b) => b - a);
if (sortedCoins[sortedCoins.length - 1] > amount) return -1;
const count = Math.floor(amount / sortedCoins[0]);
const result = coinChange(
sortedCoins.slice(1),
amount - count * sortedCoins[0]
);
return count + (result === -1 ? 0 : result);
};
/*
* @lc app=leetcode id=900 lang=javascript
*
* [900] RLE Iterator
*
* https://leetcode.com/problems/rle-iterator/description/
*
* algorithms
* Medium (49.03%)
* Total Accepted: 11.6K
* Total Submissions: 23.5K
* Testcase Example: '["RLEIterator","next","next","next","next"]\n[[[3,8,0,9,2,5]],[2],[1],[1],[2]]'
*
* Write an iterator that iterates through a run-length encoded sequence.
*
* The iterator is initialized by RLEIterator(int[] A), where A is a run-length
* encoding of some sequence.  More specifically, for all even i, A[i] tells us
* the number of times that the non-negative integer value A[i+1] is repeated
* in the sequence.
*
* The iterator supports one function: next(int n), which exhausts the next n
* elements (n >= 1) and returns the last element exhausted in this way.  If
* there is no element left to exhaust, next returns -1 instead.
*
* For example, we start with A = [3,8,0,9,2,5], which is a run-length encoding
* of the sequence [8,8,8,5,5].  This is because the sequence can be read as
* "three eights, zero nines, two fives".
*
*
*
* Example 1:
*
*
* Input: ["RLEIterator","next","next","next","next"],
* [[[3,8,0,9,2,5]],[2],[1],[1],[2]]
* Output: [null,8,8,5,-1]
* Explanation:
* RLEIterator is initialized with RLEIterator([3,8,0,9,2,5]).
* This maps to the sequence [8,8,8,5,5].
* RLEIterator.next is then called 4 times:
*
* .next(2) exhausts 2 terms of the sequence, returning 8. The remaining
* sequence is now [8, 5, 5].
*
* .next(1) exhausts 1 term of the sequence, returning 8. The remaining
* sequence is now [5, 5].
*
* .next(1) exhausts 1 term of the sequence, returning 5. The remaining
* sequence is now [5].
*
* .next(2) exhausts 2 terms, returning -1. This is because the first term
* exhausted was 5,
* but the second term did not exist. Since the last term exhausted does not
* exist, we return -1.
*
*
*
* Note:
*
*
* 0 <= A.length <= 1000
* A.length is an even integer.
* 0 <= A[i] <= 10^9
* There are at most 1000 calls to RLEIterator.next(int n) per test case.
* Each call to RLEIterator.next(int n) will have 1 <= n <= 10^9.
*
*
*/
/**
* @param {number[]} A
*/
var RLEIterator = function(A) {
};
/**
* @param {number} n
* @return {number}
*/
RLEIterator.prototype.next = function(n) {
};
/**
* Your RLEIterator object will be instantiated and called as such:
* var obj = new RLEIterator(A)
* var param_1 = obj.next(n)
*/
......@@ -29,6 +29,8 @@ leetcode 题解,记录自己的 leecode 解题之路。
- [219.contains-duplicate-ii](./problems/219.contains-duplicate-ii.md)
- [283.move-zeroes](./problems/283.move-zeroes.md)
- [349.intersection-of-two-arrays](./problems/349.intersection-of-two-arrays.md)
- [190.reverse-bits](./problems/190.reverse-bits.md)
- [191.number-of-1-bits](./problems/191.number-of-1-bits.md)
#### 中等难度
......@@ -50,6 +52,7 @@ leetcode 题解,记录自己的 leecode 解题之路。
- [877.stone-game](./problems/877.stone-game.md)
- [279.perfect-squares](./problems/279.perfect-squares.md)
- [199.binary-tree-right-side-view](./problems/199.binary-tree-right-side-view.md)
- [201.bitwise-and-of-numbers-range](./problems/201.bitwise-and-of-numbers-range.md)
- [209.minimum-size-subarray-sum](./problems/209.minimum-size-subarray-sum.md)
#### 困难难度
......
## 题目地址
https://leetcode.com/problems/reverse-bits/description/
## 题目描述
```
Reverse bits of a given 32 bits unsigned integer.
Example 1:
Input: 00000010100101000001111010011100
Output: 00111001011110000010100101000000
Explanation: The input binary string 00000010100101000001111010011100 represents the unsigned integer 43261596, so return 964176192 which its binary representation is 00111001011110000010100101000000.
Example 2:
Input: 11111111111111111111111111111101
Output: 10111111111111111111111111111111
Explanation: The input binary string 11111111111111111111111111111101 represents the unsigned integer 4294967293, so return 3221225471 which its binary representation is 10101111110010110010011101101001.
Note:
Note that in some languages such as Java, there is no unsigned integer type. In this case, both input and output will be given as signed integer type and should not affect your implementation, as the internal binary representation of the integer is the same whether it is signed or unsigned.
In Java, the compiler represents the signed integers using 2's complement notation. Therefore, in Example 2 above the input represents the signed integer -3 and the output represents the signed integer -1073741825.
```
## 思路
这道题是给定一个32位的无符号整型,让你按位翻转, 第一位变成最后一位, 第二位变成倒数第二位。。。
那么思路就是`双指针`
> 这个指针可以加引号
- n从高位开始逐步左, res从低位(0)开始逐步右移
- 逐步判断,如果该位是1,就res + 1 , 如果是该位是0, 就res + 0
- 32位全部遍历完,则遍历结束
## 关键点解析
1. 可以用任何数字和1进行位运算的结果都取决于该数字最后一位的特性简化操作和提高性能
eg :
- n & 1 === 1, 说明n的最后一位是1
- n & 1 === 0, 说明n的最后一位是0
2. 对于JS,ES规范在之前很多版本都是没有无符号整形的, 转化为无符号,可以用一个trick`n >>> 0 `
3. 双"指针" 模型
## 代码
```js
/*
* @lc app=leetcode id=190 lang=javascript
*
* [190] Reverse Bits
*
* https://leetcode.com/problems/reverse-bits/description/
*
* algorithms
* Easy (30.30%)
* Total Accepted: 173.7K
* Total Submissions: 568.2K
* Testcase Example: '00000010100101000001111010011100'
*
* Reverse bits of a given 32 bits unsigned integer.
*
*
*
* Example 1:
*
*
* Input: 00000010100101000001111010011100
* Output: 00111001011110000010100101000000
* Explanation: The input binary string 00000010100101000001111010011100
* represents the unsigned integer 43261596, so return 964176192 which its
* binary representation is 00111001011110000010100101000000.
*
*
* Example 2:
*
*
* Input: 11111111111111111111111111111101
* Output: 10111111111111111111111111111111
* Explanation: The input binary string 11111111111111111111111111111101
* represents the unsigned integer 4294967293, so return 3221225471 which its
* binary representation is 10101111110010110010011101101001.
*
*
*
* Note:
*
*
* Note that in some languages such as Java, there is no unsigned integer type.
* In this case, both input and output will be given as signed integer type and
* should not affect your implementation, as the internal binary representation
* of the integer is the same whether it is signed or unsigned.
* In Java, the compiler represents the signed integers using 2's complement
* notation. Therefore, in Example 2 above the input represents the signed
* integer -3 and the output represents the signed integer -1073741825.
*
*
*
*
* Follow up:
*
* If this function is called many times, how would you optimize it?
*
*/
/**
* @param {number} n - a positive integer
* @return {number} - a positive integer
*/
var reverseBits = function(n) {
let res = 0;
for (let i = 0; i < 32; i++) {
res = (res << 1) + (n & 1);
n = n >>> 1;
}
return res >>> 0;
};
```
## 题目地址
https://leetcode.com/problems/number-of-1-bits/description/
## 题目描述
```
Write a function that takes an unsigned integer and return the number of '1' bits it has (also known as the Hamming weight).
Example 1:
Input: 00000000000000000000000000001011
Output: 3
Explanation: The input binary string 00000000000000000000000000001011 has a total of three '1' bits.
Example 2:
Input: 00000000000000000000000010000000
Output: 1
Explanation: The input binary string 00000000000000000000000010000000 has a total of one '1' bit.
Example 3:
Input: 11111111111111111111111111111101
Output: 31
Explanation: The input binary string 11111111111111111111111111111101 has a total of thirty one '1' bits.
Note:
Note that in some languages such as Java, there is no unsigned integer type. In this case, the input will be given as signed integer type and should not affect your implementation, as the internal binary representation of the integer is the same whether it is signed or unsigned.
In Java, the compiler represents the signed integers using 2's complement notation. Therefore, in Example 3 above the input represents the signed integer -3.
```
## 思路
这个题目的大意是: 给定一个无符号的整数, 返回其用二进制表式的时候的1的个数。
这里用一个trick, 可以轻松求出。 就是`n & (n - 1)` 可以`消除` n 最后的一个1的原理。
> 为什么能消除最后一个1, 其实也比较简单,大家自己想一下
这样我们可以不断进行`n = n & (n - 1)`直到n === 0 , 说明没有一个1了。
这个时候`我们消除了多少1变成一个1都没有了, 就说明n有多少个1了`
## 关键点解析
1. `n & (n - 1)` 可以`消除` n 最后的一个1的原理 简化操作
## 代码
```js
/*
* @lc app=leetcode id=191 lang=javascript
*
* [191] Number of 1 Bits
*
* https://leetcode.com/problems/number-of-1-bits/description/
*
* algorithms
* Easy (42.10%)
* Total Accepted: 247.4K
* Total Submissions: 583.3K
* Testcase Example: '00000000000000000000000000001011'
*
* Write a function that takes an unsigned integer and return the number of '1'
* bits it has (also known as the Hamming weight).
*
*
*
* Example 1:
*
*
* Input: 00000000000000000000000000001011
* Output: 3
* Explanation: The input binary string 00000000000000000000000000001011 has a
* total of three '1' bits.
*
*
* Example 2:
*
*
* Input: 00000000000000000000000010000000
* Output: 1
* Explanation: The input binary string 00000000000000000000000010000000 has a
* total of one '1' bit.
*
*
* Example 3:
*
*
* Input: 11111111111111111111111111111101
* Output: 31
* Explanation: The input binary string 11111111111111111111111111111101 has a
* total of thirty one '1' bits.
*
*
*
* Note:
*
*
* Note that in some languages such as Java, there is no unsigned integer type.
* In this case, the input will be given as signed integer type and should not
* affect your implementation, as the internal binary representation of the
* integer is the same whether it is signed or unsigned.
* In Java, the compiler represents the signed integers using 2's complement
* notation. Therefore, in Example 3 above the input represents the signed
* integer -3.
*
*
*
*
* Follow up:
*
* If this function is called many times, how would you optimize it?
*
*/
/**
* @param {number} n - a positive integer
* @return {number}
*/
var hammingWeight = function(n) {
let count = 0;
while (n !== 0) {
n = n & (n - 1);
count++;
}
return count;
};
```
\ No newline at end of file
## 题目地址
https://leetcode.com/problems/bitwise-and-of-numbers-range/description/
## 题目描述
```
Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers in this range, inclusive.
Example 1:
Input: [5,7]
Output: 4
Example 2:
Input: [0,1]
Output: 0
```
## 思路
一个显而易见的解法是, 从m到n依次进行`求与`的操作。
```js
let res = m;
for (let i = m + 1; i <= n; i++) {
res = res & i;
}
return res;
```
但是, 如果你把这个solution提交的话,很显然不会通过, 会超时。
我们依旧还是用trick来简化操作。 我们利用的性质是, n个连续数字求与的时候,前m位都是1.
举题目给的例子:[5,7] 共 5, 6,7三个数字, 用二进制表示 101, 110,111,
这三个数字特点是第一位都是1,后面几位求与一定是0.
再来一个明显的例子:[20, 24], 共 20, 21, 22, 23,24五个数字,二进制表示就是
```
0001 0100
0001 0101
0001 0110
0001 0111
0001 1000
```
这五个数字特点是第四位都是1,后面几位求与一定是0.
因此我们的思路就是, 求出这个数字区间的数字前多少位都是1了,那么他们求与的结果一定是前几位数字,然后后面都是0.
## 关键点解析
- n个连续数字求与的时候,前m位都是1
- 可以用递归实现, 个人认为比较难想到
代码:
```js
(n > m) ? (rangeBitwiseAnd(m/2, n/2) << 1) : m;
```
> 每次问题规模缩小一半, 这是二分法吗?
## 代码
```js
/*
* @lc app=leetcode id=201 lang=javascript
*
* [201] Bitwise AND of Numbers Range
*
* https://leetcode.com/problems/bitwise-and-of-numbers-range/description/
*
* algorithms
* Medium (35.58%)
* Total Accepted: 78.9K
* Total Submissions: 221.3K
* Testcase Example: '5\n7'
*
* Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND
* of all numbers in this range, inclusive.
*
* Example 1:
*
*
* Input: [5,7]
* Output: 4
*
*
* Example 2:
*
*
* Input: [0,1]
* Output: 0
*/
/**
* @param {number} m
* @param {number} n
* @return {number}
*/
var rangeBitwiseAnd = function(m, n) {
let count = 0;
while (m !== n) {
m = m >> 1;
n = n >> 1;
count++;
}
return n << count;
};
```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册