zoukankan      html  css  js  c++  java
  • leecode练习--476、961、500

    力扣题目(476、数字的补数)

    题目:

    给定一个正整数,输出它的补数。补数是对该数的二进制表示取反。

    注意:

    1. 给定的整数保证在32位带符号整数的范围内。
    2. 你可以假定二进制数不包含前导零位。

    示例1:

    输入: 5
    输出: 2
    解释: 5的二进制表示为101(没有前导零位),其补数为010。所以你需要输出2。
    

    注意:

    每个输入参数的边界满足 1 <= left <= right <= 10000

    示例2:

    输入: 1
    输出: 0
    解释: 1的二进制表示为1(没有前导零位),其补数为0。所以你需要输出0。
    

    解题思路:

    先将正整数转化为二进制数的形式

    将二进制数取反

    将二进制数转化为整数形式

    熟练掌握:1、十进制数除二取余,直到为零,然后余数倒过来就是它的二进制数。

    2、列表倒置的具体实现方法:就是在循环中,以索引位置的比较来完成第一个和最后一个互换、第二个与倒数第二个互换、。。。。

    3、二进制转十进制:将它每个二进制位上的数乘以2的指数幂,其中2的指数幂根据二进制位来确定

    代码实现:

    class Solution:
        def findComplement(self, num: int) -> int:
            a = num
            l=[]
            s = 0
            '''将十进制数取余,每取出一个余数就放入列表,直到为零,==特别注意此时余数是正着放进去的,不是该十进制数的二进制形式,因此还需要在下面进行倒转,才能得到这个十进制的二进制数形式=='''
            while a > 0:
                x = a%2    #除二取余
                l.append(x)  #将余数追加进列表
                a //=2
            '''将二进制数翻转回来,就是原十进制数的二进制形式,我们通过比较索引位置来实现(也就是列表中的倒置方法reverse())'''
            for ind in range(len(l)):
                lind = len(l)-1-ind
                if ind < lind:
                    l[ind],l[lind] = l[lind],l[ind]
            #将二进制位上的每一个数取反
            for r in range(len(l)):
                if l[r] == 1:
                    l[r] = 0
                else:
                    l[r] = 1
            #二进制转换为十进制:将二进制位上的数乘以2的指数幂(“个位”上的数是2的0次方,“十位”上的数是2的1次方。。。。。。)
            for i in range(len(l)):
                s += l[i]*(2**(len(l)-1-i))
            return s
    

    方法二:

    也可以用bin()函数来完成,bin()函数会将十进制数转换位二进制,并以字符串的形式输出,格式为:"0b"+"二进制数"

    我们可以通过字符串内置方法replace(),来将"0b"用空字符串""替换

    代码实现:

    class Solution:
        def findComplement(self, num: int) -> int:
            a=bin(num)
            b=a.replace('0b','')
            s = ''
            c = 0
            for i in b:
                if i == '1':
                    s += '0'   
                else:
                    s += '1'
            for i in range(len(s)):
                c += int(s[i])*(2**(len(s)-1-i))
            return c
    

    力扣题目(961、重复 N 次的元素)

    题目:

    在大小为 2N 的数组 A 中有 N+1 个不同的元素,其中有一个元素重复了 N

    返回重复了 N 次的那个元素

    示例:

    #示例1
    输入:[1,2,3,3]
    输出:3
    
    #示例2
    输入:[2,1,2,5,3,2]
    输出:2
    
    #示例3
    输入:[5,1,5,2,5,3,5,4]
    输出:5
    

    提示:

    1. 4 <= A.length <= 10000
    2. 0 <= A[i] < 10000
    3. A.length 为偶数

    解题思路:

    暴力算法:遍历元素,有相同的元素即返回该元素

    代码实现:

    class Solution:
        def repeatedNTimes(self, A: List[int]) -> int:
            s = 1
            for i in range(len(A)):
                for j in range(i+1,len(A)):
                    if A[i] == A[j]:
                        return A[i]
    

    方法2:

    通过实例分析:在有2n个元素的列表中,其中有n+1个不同元素,而有n个相同元素,那么相同的元素最大可能相隔的距离是3,再不可能有比这个距离更大的了

    通过判断相邻、隔1个位置、隔2个位置的元素是否相同即可

    class Solution:
        def repeatedNTimes(self, A: List[int]) -> int:
            i = 0
            while i < len(A):
                if (i+3)<len(A) and (A[i]==A[i+3] or A[i]==A[i+2] or A[i]==A[i+1]):
                    return A[i]
                elif (i+2)<len(A) and (A[i]==A[i+2] or A[i]==A[i+1]):
                    return A[i]
                elif (i+1)<len(A) and A[i]==A[i+1]:
                    return A[i]
                else:
                    i += 1
    

    总结:在编写程序的时候,不要形成固定的思路,需要突破惯性思维,打破传统,找到更多更简单的算法,比如这道题,我们一般是通过遍历所有元素来发现有相同的元素,而利用数学思想,可以知道在有一半相同元素且其他元素均不一样的情况下,相同元素的排列必定不可能突破相隔2个不同元素的底线(不相信的可以自己去算)

    力扣(500、键盘行)

    题目:

    给定一个单词列表,只返回可以使用在键盘同一行的字母打印出来的单词

    示例:

    输入: ["Hello", "Alaska", "Dad", "Peace"]
    输出: ["Alaska", "Dad"]
    

    注意:

    1. 你可以重复使用键盘上同一字符。
    2. 你可以假设输入的字符串将只包含字母。

    解题思路:

    碰到判断一堆元素是否相同或来自同一区域的题型,我们一定要先将比对对象或比对区域统一格式,用字典将比对区域的所有元素进行归类(归为同一类)

    然后再将判断对象转化为比对区域中的值进行判断(说的比较抽象,可以通过下面的代码进行思考、总结)

    代码实现:

    class Solution:
        def findWords(self, words: List[str]) -> List[str]:
            new_words = []
            #将比对对象进行统一的归类
            dic = {'q':0,'w':0,'e':0,'r':0,'t':0,'y':0,'u':0,'i':0,'o':0,'p':0,'Q':0,'W':0,'E':0,'R':0,'T':0,'Y':0,'U':0,'I':0,'O':0,'P':0,'a':1,'s':1,'d':1,'f':1,'g':1,'h':1,'j':1,'k':1,'l':1,'A':1,'S':1,'D':1,'F':1,'G':1,'H':1,'J':1,'K':1,'L':1,'z':2,'x':2,'c':2,'v':2,'b':2,'n':2,'m':2,'Z':2,'X':2,'C':2,'V':2,'B':2,'N':2,'M':2}
            for s in words:
                #将字符串s中的每一个字符都进行比较
                for i in range(len(s)-1):
                    for j in range(i+1,len(s)):
                        if dic[s[i]] != dic[s[j]]:
                            new_words.append(s)
                            break     #只要有不一样的字符就终止s中第一个元素与后续元素的比较
                    break    #终止s中所有元素的相互比较
            #删除有不同领域元素的字符串
            for x in new_words:
                words.remove(x)
            return words
    
  • 相关阅读:
    洛谷P1072 Hankson 的趣味题(题解)
    18.3.19晚听韩明睿大佬讲题收获
    题解+新技巧--一本通1282:最大子矩阵
    题解-洛谷P1303 A*B Problem(高精)
    Java重载和覆盖
    propagation属性的7个传播行为
    脏读、不可重复读、幻读
    RSA 数据加密和数字签名算法
    大型互联网站解决高并发的常见策略
    死锁和活锁
  • 原文地址:https://www.cnblogs.com/itboy-newking/p/10914782.html
Copyright © 2011-2022 走看看