191. Number of 1 Bits
计算数字的二进制中有多少个1。原题
1 | Input: 11 |
方法一:常规解法,使用1与n作与运算,如果不是0说明,含有一个1。
1 | def hamming_weight(n): |
1 | def hamming_weigth(n): |
136. Single Number
找出数组中不重复的元素。其它元素出现两次。原题
1 | Input: [4,1,2,1,2] |
1 | def single_num(nums): |
137. Single Number II
找出数组中出现一次的元素,其它元素出现三次。原题
1 | Input: [2,2,3,2] |
方法一:找出单独元素每一位的值。如果把所有数字的二进制每一位加起来,如果某一位可以被3整除,则表示单独元素的该位为0,否则为1。以下使用count
来表示每一位1
的个数。假设count%3!=0
为True,说明该元素i
位为1,然后是用|=
更新ans在第i
个位置的值,这里也可以使用+=
,但是效率稍慢。convert
的作用是因为python中的int是个对象,且没有最大限制,不是在第32位使用1来表示负数。
1 | def singleNumber(self, nums, n=3): |
1 | def singleNumber(self, nums): |
260. Single Number III
找出数组中两个唯一出现一次的元素,其余元素均出现两次。原题
1 | Input: [1,2,1,3,2,5] |
思想:将这两个元素分到两个组,由于这两个数不相等,所以亦或结果不为0,也就是说二进制中至少有一位1,记为第n位。我们以第n位是否为1,把数组分为两个子数组。
1 | def singleNumber(self, nums): |
面试题 17.19. 消失的两个数字
此题和260很像,不同在于是从1~N消失了两个数字。要求在O(N)时间,O(1)空间实现。
方法一:可以使用260的方法,但是这样空间复杂度不符合要求。
1 | def missingTwo(self, nums: List[int]) -> List[int]: |
方法二:以0~n-1中缺失的数字
题为基础来解。写完了发现和方法一不就是同一种方法嘛,只不过用了循环来代替数组产生的空间。
1 | def missingTwo(self, nums: List[int]) -> List[int]: |
1 | def missingTwo(self, nums: List[int]) -> List[int]: |
0~n-1缺失的数字
数学方法。使用两数的平均数来讲原数组分为两部分。这样问题就变成了找到一个缺失的数字。
1 | def missingTwo(self, nums: List[int]) -> List[int]: |
方法五:这个是从评论中学习到的方法,很有意思。将对应索引置为负数,然后最后找正数的索引,就是缺失的两个数字。但是这样空间复杂度貌似不符合要求了。
1 | def missingTwo(self, nums: List[int]) -> List[int]: |
方法六:很快,我想到了生成器islice,但是用了发现不对,为什么?因为我在循环中改变了nums,导致了n出现了-1的情况。所以我们只改变符号,不改变数字,需要用一个abs。
1 | def missingTwo(self, nums: List[int]) -> List[int]: |
371. Sum of Two Integers
不用加减乘除做加法。原题
实际上加法分为三个步骤
- 相加但不进位,1^0=1,1^1=0,0^0=0,所以第一步用异或。
- 只求进位的结果,只有两个1才会进位,所以用
&
,然后左移1位,表示要进的位。 - 把前两步的结果再重复1,2步,直到没有进位产生,即
b=0
。
1 | def getSum(self, a, b): |
190. Reverse Bits
返回一个数的二进制的倒序的十进制。原题
1 | Input: 43261596 |
方法一:使用原生库。ljust
表示在右侧补’0’。或者使用format
来补0。
1 | def reverseBits(self, n): |
方法二:自己实现进制转换,使用位运算优化。
1 | def reverseBits(self, n): |
1 | def reverseBits(self, n): |
389. Find the Difference
s和t两个由小写字母组成的字符串,t是由s打乱顺序并再随机添加一个小写字母组成。原题
方法一:使用Collection。
1 | def findTheDifference(self, s, t): |
1 | def findTheDifference(self, s, t): |
401. Binary Watch
有这样一个二进制的手表,输入一个n,表示有几个亮着的灯,返回所有可能出现的时间。时间范围为12小时制,即hours(0-11),minutes(0-59)。原题
1 | Input: n = 1 |
1 | def readBinaryWatch(self, num): |
方法二:正确的写法。需要分开判断小时和分钟,然后再合并。
1 | def readBinaryWatch(self, num): |
1 | def readBinaryWatch(self, num): |
405. Convert a Number to Hexadecimal
把一个32位有符号的整数转换成16进制。原题
1 | Input: |
1 | def toHex(self, num): |
461. Hamming Distance
求两个正数的原码中不同位的个数。原题
1 | Input: x = 1, y = 4 |
1 | def hammingDistance(self, x, y): |
476. Number Complement
给定一个正数,求其原码的按位取反后的数。原题
1 | Input: 5 |
方法一:暴力的方法。
1 | def findComplement(self, num): |
方法二:其实就是求101
和111
的异或。所以先找到111
。
1 | def findComplement(self, num): |
111
。比如一个8位数,最高代表符号:1000000
,先将其右移1位,使得左边两位都变成1。然后再右移2位,使得左边四位变成1,以此类推,8位数最多移动3次就可以得到1111111
,32位则还需要再移动2次。
1 | def findComplement(self, num): |
693. Binary Number with Alternating Bits
二进制是否是交替的0和1。原题
1 | Input: 5 |
方法一:字符串法。
1 | def hasAlternatingBits(self, n): |
方法二:除2法。
1 | def hasAlternatingBits(self, n): |
1 | def hasAlternatingBits(self, n): |
762. Prime Number of Set Bits in Binary Representation
求某范围的所有自然数中,二进制中1的个数是质数的个数。原题
1 | Input: L = 10, R = 15 |
方法一:direct.
1 | def countPrimeSetBits(self, L: 'int', R: 'int') -> 'int': |
1 | def countPrimeSetBits(self, L: 'int', R: 'int') -> 'int': |
868. Binary Gap
二进制两个1的最大距离。原题
1 | Input: 22 |
方法一:字符串或是位运算都可以。
1 | def binaryGap(self, N: 'int') -> 'int': |
1 | def binaryGap(self, N: 'int') -> 'int': |
268. Missing Number
0~n中缺失的数字。原题
方法一:数学公式。
1 | def missingNumber(self, nums): |
index | 0 | 1 | 2 |
---|---|---|---|
value | 3 | 0 | 1 |
1 | def missingNumber(self, nums: 'List[int]') -> 'int': |
1012. Complement of Base 10 Integer
非负数的反码。原题
1 | def bitwiseComplement(self, N: int) -> int: |
1404. Number of Steps to Reduce a Number in Binary Representation to One
几下操作可以将其变为1。偶数除以2,奇数+1.原题
1 | Input: s = "1101" |
方法一:将其转为数字最简单,但是失去了此题的意义。评论区看到的一个解法
110010
-> 110100
-> 111000
-> 1000000
takes 2(which is count of mid zeros) + 1
moves.1000000
-> 1
takes 6 moves because length of s
increases 1.
1 | def numSteps(self, s: str) -> int: |
201. Bitwise AND of Numbers Range
范围内的数字求与运算和。原题
1 | Input: [5,7] |
1 | def rangeBitwiseAnd(self, m: int, n: int) -> int: |
1442. Count Triplets That Can Form Two Arrays of Equal XOR
数组中找出两段的异或和相等。原题
方法一:此题在竞赛中做出来了,需要找到规律。
1 | def countTriplets(self, arr: List[int]) -> int: |
1238. Circular Permutation in Binary Representation
返回指定为位数的二进制环,每两个数的二进制只有1位不同。原题
1 | Input: n = 2, start = 3 |
方法一:我想了半天这道题,以为和二进制无关,是个数学题,没想到最后还得用异或来解决。这是个 gray code的问题,有一个公式。
1 | def circularPermutation(self, n, start): |
393. UTF-8 Validation
题目描述非常之难懂,母语的人看着都看不明白。此题在Leetcode-cn上看的中文描述。针对一些数,它的二进制必须满足几种形式,如果是0开头,就是一个1字节的字符;如果110开头,说明是2字节的字符,其后面的二进制形式必须是10开头;如果1110开头,说明是3字节字符,后面必须跟两个10开头的字符。原题
1 | data = [197, 130, 1], which represents the octet sequence: 11000101 10000010 00000001. |
方法一:字符串方法。
1 | def validUtf8(self, data: List[int]) -> bool: |
方法二:位运算。
1 | def validUtf8(self, data: List[int]) -> bool: |
318. Maximum Product of Word Lengths
给你一个单词列表,返回最大的两个没有相同字符的单词长度乘积。原题
1 | Input: ["abcw","baz","foo","bar","xtfn","abcdef"] |
方法一:直观解法。
1 | def maxProduct(self, words: List[str]) -> int: |
1 | def maxProduct(self, words: List[str]) -> int: |
1177. Can Make Palindrome from Substring
给定一个 字符串s,进行一些查询,针对s的切片内容能否将其打乱然后重新排列,在替换k个字符内将其变成回文的。返回这些查询结果。原题
1 | Input: s = "abcda", queries = [[3,3,0],[1,2,0],[0,3,1],[0,3,2],[0,4,1]] |
方法一:bit mask。我学会了,开始的时候想用Counter来计算,虽然通过了但是效率很慢。这样只包含字母的题可以用位运算异或来进行。思路和榜一大神不谋而合。
1 | def canMakePaliQueries(self, s: str, queries: List[List[int]]) -> List[bool]: |
1 | def canMakePaliQueries(self, s: str, queries: List[List[int]]) -> List[bool]: |
421. Maximum XOR of Two Numbers in an Array
数组中两个数最大的异或值时多少。线性时间复杂度实现。
1 | Input: [3, 10, 5, 25, 2, 8] |
方法一:Stefan的方法研究了半天。改成循环其实更容易理解。
1 | def findMaximumXOR(self, nums: List[int]) -> int: |
如何实现的呢?首先我们1位1位来更新ans,从最高位开始,尽可能让它为1,那么ans就会越大。
改成循环容易观察。每次我们想尽量获得nxt,然后找是否有另一个q,满足q ^ p = nxt
。所以看到ans^1
就是nxt
。
1 | def findMaximumXOR(self, nums: List[int]) -> int: |
面试题 05.04. 下一个数
找出与其二进制表达式中1的个数相同且大小最接近的那两个数(一个略大,一个略小)
1 | 输入:num = 2(或者0b10) |
方法一:先用字符串来解。较大的数通过翻转最低位的01,然后重排后面的数。
1 | def findClosedNumbers(self, num: int) -> List[int]: |
方法二:位运算,这个方法没怎么看懂。评论区大佬的答案。
1 | def findClosedNumbers(self, num: int) -> List[int]: |
1029. Binary Prefix Divisible By 5
二进制前缀能否被5整除。原题
1 | Input: [0,1,1,1,1,1] |
方法一:首次AC的方法。
1 | def prefixesDivBy5(self, A: List[int]) -> List[bool]: |
1 | def prefixesDivBy5(self, A: List[int]) -> List[bool]: |
645. Set Mismatch
1~n数组中包含一个重复的元素和一个缺失的元素。找出这两个元素。原题
1 | Input: nums = [1,2,2,4] |
Counter
实现,有些愚蠢。
1 | def findErrorNums(self, nums): |
方法二:在原数组元素*-1记录。空间复杂度为常数,但是改变了原数组,时间复杂度稍微高一点,因为迭代两次。
1 | def findErrorNums(self, nums: 'List[int]') -> 'List[int]': |
方法三:XOR。
1734. Decode XORed Permutation
说有个奇数长度的数组是,从1到n的全排列的一种。将每两个相邻的数做异或运算。得到一个新的数组encoded。给你这个encoded,让你还原原数组。
1 | Input: encoded = [6,5,4,6] |
方法一:这题并不算难,只是竞赛没时间做了。首先从题中获取条件,可以得到1~n的异或和,然后考虑奇数条件如何使用。这点没有想到,我们可以跳跃切分来用,比如4^1=5,5^3=6,这样我们可以通过总的异或和求出第一个数是多少。
1 | def decode(self, encoded: List[int]) -> List[int]: |
1178. Number of Valid Words for Each Puzzle
找到每个谜面符合条件的单词数,谜面的第一个字符在单词中,单词的所有字符均在谜面中出现过。
1 | words = ["aaaa","asas","able","ability","actt","actor","access"], |
方法一:状态压缩+哈希。对于每个单词根据是否出现可以压缩成一个26的数字。对于每个puzzle来说,只要puzzle[0] 和puzzle[1:]字符串的一个子集
压缩后时相等的,那么就有一个word是符合条件的。
1 | def findNumOfValidWords(self, words: List[str], puzzles: List[str]) -> List[int]: |
2354. Number of Excellent Pairs
找到优质数对。如果弯转过来了很简单。比赛是忽略了是与运算和或运算的和。所以其实就是统计两个数1的个数。
方法一:Lee的方法。
1 | def countExcellentPairs(self, A: List[int], k: int) -> int: |
779. K-th Symbol in Grammar
我们构建了一个包含 n 行( 索引从 1 开始 )的表。首先在第一行我们写上一个 0。接下来的每一行,将前一行中的0替换为01,1替换为10。
例如,对于 n = 3 ,第 1 行是 0 ,第 2 行是 01 ,第3行是 0110 。
给定行数 n 和序数 k,返回第 n 行中第 k 个字符。( k 从索引 1 开始)
方法一:自己想的递归。规律为每一行新增了上一行的反码。
1 | def kthGrammar(self, n: int, k: int) -> int: |
方法二:位运算,由于k从1开始,我们将它-1.一行中的第 i个字符,会在第 2i和第 2i+1 个位置产生两个字符。如果第 i 个字符是 00,那么在位置2i 和 2i+1 产生的字符分别是 0 和1;如果第 i 个字符是 1,产生的字符是 1和 0。
可以发现,第 2i (偶数位)个字符总是和第 i个字符相同,而第 2i+1 (奇数位)个字符是第 i 个字符的反转。也就是说,奇数位上的字符总是发生了一次反转而来的。反转偶数次,字符不变;反转奇数次,相当于反转了一次。
因此,我们只需要看 k 这个数字是否是奇数,若是,累计一次反转。然后将 k 除以 2,继续判断,并累计反转次数,直至 k 为 0。
最后判断反转的次数是否为奇数,是则答案为 1,否则为 0。
1 | def kthGrammar(self, n: int, k: int) -> int: |