《剑指offer》(5)搜索算法、位运算、模拟

这篇具有很好参考价值的文章主要介绍了《剑指offer》(5)搜索算法、位运算、模拟。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

《剑指offer》(5)搜索算法、位运算、模拟,python,leetcode,算法

方法一:

class Solution:

    def GetNumberOfK(self , nums: List[int], k: int) -> int:

        #从两边开始找,找到之后记录当前位置

        left = 0

        right = len(nums) - 1

        if k not in nums:

            return 0

        start = len(nums) - 1

        end = 0

        while left <= right:

            if nums[left] < k:

                left += 1

            if nums[left] == k:

                start = min(left,start)

                left += 1

            if nums[right] > k :

                right -= 1

            if nums[right] == k:

                end = max(right,end)

                right -= 1

        return end - start + 1

方法二:

class Solution:

    def divice(self,nums,k):

        left = 0

        right = len(nums) - 1

        while left <= right:

            mid = (right + left)//2

            if nums[mid] < k:

                left = mid + 1

            elif nums[mid] > k:

                right = mid - 1

        return left

    def GetNumberOfK(self , nums: List[int], k: int) -> int:

        #二分法查找k+0.5和k-0.5的位置,中间部分就是k

        return self.divice(nums,k+0.5) - self.divice(nums,k-0.5)

《剑指offer》(5)搜索算法、位运算、模拟,python,leetcode,算法

#线性搜索:首先从数组左下角搜索,如果当前数字大于target,那么查找往上移一位,如果当前数字小于target,那么查找往右移一位。查找到target,返回true; 如果越界,返回false; 

class Solution:

    def Find(self , target: int, array: List[List[int]]) -> bool:

        if len(array) == 0:

            return False

        row = len(array)

        col = len(array[0])

        c,r = 0,row - 1 #从左下角开始搜索

        while c < col and r >= 0:

            temp = array[r][c]

            if temp < target:#往右移动

                c += 1

            if temp > target: #往上移动

                r -= 1

            if temp == target:

                return True

        return False

《剑指offer》(5)搜索算法、位运算、模拟,python,leetcode,算法

# 旋转之后,前半段和后半段都是升序,所以要确定最小值在后半段

#二分法,如果mid比right大,那mid在前半段中,让left = mid+1;如果mid比right小,mid在后半段,让right=mid,如果等无法判断是前半段还是后半段,right-=1,缩小判断范围。

class Solution:

    def minNumberInRotateArray(self , nums: List[int]) -> int:

        left = 0

        right = len(nums) - 1

        if len(nums) == 0:

            return 0

        while left < right:

            mid = (right+left)//2

            if nums[mid] > nums[right]:

                left = mid + 1

            elif nums[mid] < nums[right]:

                right = mid

            elif nums[mid] == nums[right]:

                right -= 1

        return nums[left]

《剑指offer》(5)搜索算法、位运算、模拟,python,leetcode,算法

全排列,递归回溯,每次将递归的层数和字符串下传,在[h,size-1]中的元素互换,然后递归,递归回来恢复现场

class Solution:

    def Permutation(self , s: str) -> List[str]:

        ans = []

        s = list(s)

        def dfs(h,string):

            if h == len(s) - 1:

                nonlocal ans

                ans.append(''.join(s))

                return

            for i in range(h,len(s)):

                s[i],s[h] = s[h],s[i]

                dfs(h+1,s)

                s[i],s[h] = s[h],s[i] #恢复现场

        dfs(0,s)

        ans = list(set(ans)) #因为没有在递归的时候拦住相等的元素重排列, 所以最后要去重

        return ans

《剑指offer》(5)搜索算法、位运算、模拟,python,leetcode,算法

class Solution:

    def findNthDigit(self , n: int) -> int:

        #1~9 9*1=9个数字

        #10~99 9*10*2=180个数字

        #100~999 9*100*3=2700个数字

        weishu = 1 #当前数字一共有多少位

        start = 1 #当前数字起始区间的一个数字是多少

        Sum = 9 #该区间一共多少个数字

        while n > Sum:

            n -= Sum

            weishu += 1

            start *= 10

            Sum = 9*weishu*start

        num = start+(n-1)//weishu #确定是哪个数字

        index = (n-1)%weishu #确定数字在哪一位

        return int(str(num)[index])

《剑指offer》(5)搜索算法、位运算、模拟,python,leetcode,算法

《剑指offer》(5)搜索算法、位运算、模拟,python,leetcode,算法

class Solution:

    def add(self, a: int, b: int) -> int:

        #要考虑负数的情况,python是用补码存储

        x = 0xffffffff

        a,b = a & x,b & x #获取补码

        while b != 0:

            a,b = a ^ b, (a & b)<<1 & x #可能超32位的也要补码

        return a if a <= 0x7fffffff else ~(a^x) #按位取反后将整个数字取反

《剑指offer》(5)搜索算法、位运算、模拟,python,leetcode,算法

class Solution:

    def NumberOf1(self , n: int) -> int:

        #考虑移位运算,每次移动一位;遍历二进制的32位,通过移位0-31次实现

        #将移位后的1与数字进行位与运算,结果为1就记录一次。

        res = 0

        for i in range(32):

            if n & (1 << i) != 0:

                res += 1

        return res

《剑指offer》(5)搜索算法、位运算、模拟,python,leetcode,算法

 用递归来累加

class Solution:

    def Sum_Solution(self, n):

        if n == 1:

            return 1

        return self.Sum_Solution(n-1)+n

《剑指offer》(5)搜索算法、位运算、模拟,python,leetcode,算法

方法一:使用哈希表,遍历数组,如果数组中的元素在key中,就删除掉这个元素。如果不在key中,就将其值置为1.最后排序一下哈希表,输出key。

class Solution:

    def FindNumsAppearOnce(self , nums: List[int]) -> List[int]:

        #第一种,使用哈希表

        dict_data = {}

        for i in nums:

            if i not in dict_data:

                dict_data[i] = 1

            else:

                dict_data.pop(i)

        res = [i for i in sorted(dict_data.keys())]

        return res

#第二种,位运算

class Solution:

    def FindNumsAppearOnce(self , nums: List[int]) -> List[int]:       

 #先将全部进行异或运算,得到的是两个不同的数的异或结果

        temp = 0

        for i in nums:

            temp ^= i

        #分组,每组求出一个异或结果;从最低位开始找到这两个数不同的那个二进制1

        mask = 1

        while temp & mask == 0:

            mask = mask << 1

        #根据mask的分组结果,将两组数据进行异或

        a = 0

        b = 0

        for i in nums:

            if i & mask == 0:

                a ^= i

            else:

                b ^= i

        return [a,b] if a < b else [b,a]

《剑指offer》(5)搜索算法、位运算、模拟,python,leetcode,算法

class Solution:

    def Power(self , base: float, exponent: int) -> float:

        #如果两个通时是0就判错返回

        if base == 0 and exponent == 0:

            return False

        #特别处理负次幂

        if exponent < 0:

            base = 1/base

            exponent = -exponent

        #根据幂指数累乘

        res = 1

        for i in range(exponent):

            res *= base

        return res

《剑指offer》(5)搜索算法、位运算、模拟,python,leetcode,算法

class Solution:

    def printMatrix(self, matrix):

        #顺时针就是先向右移动,到底后向下,然后向左,再向上。设置四个边界,每次遍历之后就更新边界,遇到边界后退出。

        res = []

        if len(matrix) == 0:

            return []

        left,right,down,up = 0, len(matrix[0]) - 1, len(matrix) - 1, 0

        #直到边界重合

        while left <= right and up <= down:

            #先从左到右

            for i in range(left,right+1):

                res.append(matrix[up][i])

            up += 1 #重置行数

            if up > down: #重置之后要判断当前是否已经没有剩余行了

                break

            #从上到下

            for i in range(up,down+1):

                res.append(matrix[i][right])

            right -= 1 #重置列

            if right < left: #重置之后查看当前是否已经没有剩余列了

                break

            #从右往左

            for i in range(right,left-1,-1):

                res.append(matrix[down][i])

            down -= 1 #重置行

            #从下往上

            for i in range(down,up-1,-1):

                res.append(matrix[i][left])

            left += 1 #重置列

        return res

《剑指offer》(5)搜索算法、位运算、模拟,python,leetcode,算法

给数组排序, 然后计算0的个数,找到第一个不是0的数,计算两两之间的差值;如果出现了两个相同的不为0的数,就一定不是顺子;0的个数大于累加和就是顺子。

class Solution:

    def IsContinuous(self , numbers: List[int]) -> bool:

        #将数组排序,计算0的个数,超过4就返回FALSE,找到第一个不为0的数,计算两两差值,累加和0比较。

        num_0 = 0

        sum_0 = 0

        numbers = sorted(numbers)

        for i in range(len(numbers)-1):

            if numbers[i] == 0:

                num_0 += 1

            else:

                sum_0 += numbers[i+1] - numbers[i] - 1 if numbers[i+1] > numbers[i] else 1000 #保证sum_0在不是顺子的时候大于num_0.

        if num_0 > 4:

            return False

        else:

            if num_0 >= sum_0:

                return True

            else:

                return False

《剑指offer》(5)搜索算法、位运算、模拟,python,leetcode,算法

class Solution:

    def StrToInt(self , s: str) -> int:

        #首先去掉字符串的首位空格,然后判断数字的符号位,然后开始遍历字符串,遇到非数字就跳过,最后做范围判断

        #去空格

        s = s.strip()

        #长度判断

        if len(s) == 0:

            return 0

        #确定符号位后去掉符号位

        sign = -1 if s[0] == '-' else 1

        s = s[1:] if s[0] == '+' or s[0] == '-' else s

        #拼接res,如果去掉符号位后是空,那最后也能返回0,首字符是0不影响结果

        res = ['0']

        for i in range(len(s)):

            j = i

            while j < len(s) and '0' <= s[j] <= '9':

                res.append(s[j])

                j += 1

            break #出循环之后就直接break

        # 确定边界值

        MAX = 2**31 - 1

        MIN = -2**31

        #计算整数,并根据边界值输出

        ans = sign*int(''.join(res))

        if MIN <= ans <= MAX:

            return ans

        if ans < MIN:

            return MIN

        if ans > MAX:

            return MAX

《剑指offer》(5)搜索算法、位运算、模拟,python,leetcode,算法

class Solution:

    #判断是否是整数(带符号)

    def isInt(self,num):

        if len(num) == 0 or (len(num) == 1 and num[0] in ['+','-']):

            return False

        ans = [i for i in num if not '0' <= i <= '9']

        return len(ans) == 0 or (len(ans) == 1 and num[0] in ['+','-'])

    #判断是否是小数(带符号)

    def isFloat(self,num):

        if len(num) == 0 or '.' not in num :

            return False

        #去掉符号位

        num = num[1:] if num[0] in ['+','-'] else num

        #获得小数点的下标

        ind = num.index('.')

        #判断是否是小数

        a = self.isInt(num[:ind]) #前半段可以是带符号整数

        b = self.isInt(num[ind+1:]) and '+' not in num[ind+1:] and '-' not in num[ind+1:] #后半段不可以带符号

        if len(num[:ind]) == 0 : return b #如果前半段为空,后边必须成立

        elif len(num[ind+1:]) == 0 : return a #如果后半段是空,前面必须成立

        else: return a and b #都不空的时候,都得成立

#判断字符串

    def isNumeric(self , s ):

        #去空格

        s = s.strip()

        #判断长度

        if len(s) == 0:

            return False

        #分类判断

        for i in range(len(s)):

            if '0' <= s[i] <= '9':

                continue #数字就跳过

            elif s[i] in ['e','E']: #遇到e之后,判断两段

                a = self.isFloat(s[:i]) or self.isInt(s[:i]) #前半段整数或小数

                b = self.isInt(s[i+1:]) #后半段必须整数

                return a and b

            elif s[i] == '.': #遇到.

                if 'e' in s or 'E' in s: #如果有e,就先跳过

                    continue

                else: #否则判断是否是小数

                    return self.isFloat(s)

            elif s[i] in ['+','-']: #遇到符号位如果是最开始或者e后面,跳过

                if i == 0 or s[i-1] in ['e','E']:

                    continue

                else: #否则就是错误的

                    return False

            else: #遇到其他字符直接报错

                return False

        return '0' <= s[-1] <= '9' #出循环后要保证最后跳过的是数字

 文章来源地址https://www.toymoban.com/news/detail-634894.html

 

 

到了这里,关于《剑指offer》(5)搜索算法、位运算、模拟的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • (搜索) 剑指 Offer 38. 字符串的排列 ——【Leetcode每日一题】

    难度:中等 输入一个字符串,打印出该字符串中字符的所有排列。 你可以以任意顺序返回这个字符串数组,但里面 不能有重复元素 。 示例: 输入:s = “abc” 输出:[“abc”,“acb”,“bac”,“bca”,“cab”,“cba”] 限制 : 1 = s 的长度 = 8 💡思路:回溯 可以直接 暴力穷举 ,但

    2024年02月12日
    浏览(39)
  • 剑指 Offer 15. 二进制中1的个数 / LeetCode 191. 位1的个数(位运算)

    链接:剑指 Offer 15. 二进制中1的个数;LeetCode 191. 位1的个数 难度:简单 编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。 提示: 请注意,在某些语言(如 Java)中,没有无符号整数类型。

    2024年02月12日
    浏览(27)
  • 【LeetCode-中等】剑指 Offer 36. 二叉搜索树与双向链表

    剑指 Offer 36. 二叉搜索树与双向链表 后序遍历、二叉搜索树 二叉搜索树中的任一节点的 直接前驱为其左子树的最右侧节点,直接后继为其右子树的最左侧节点 。因此,可以通过这个关系来操作原来的二叉树。 为了不影响深度较大的节点的判断,使用后序遍历。 Step1. 后序遍

    2024年02月13日
    浏览(30)
  • (搜索) 剑指 Offer 13. 机器人的运动范围 ——【Leetcode每日一题】

    难度:中等 地上有一个 m 行 n 列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于 k 的格子。例如,当 k 为18时,机器人能够进入方格

    2024年02月11日
    浏览(43)
  • 剑指 Offer 31. 栈的压入、弹出序列 / LeetCode 946. 验证栈序列(栈模拟)

    链接:剑指 Offer 31. 栈的压入、弹出序列;LeetCode 946. 验证栈序列 难度:中等 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的 所有数字均不相等 。例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是该压栈序

    2024年02月16日
    浏览(34)
  • 【LeetCode: 剑指 Offer II 089. 房屋偷盗(打家窃舍) | 暴力递归=>记忆化搜索=>动态规划】

    🍎作者简介:硕风和炜,CSDN-Java领域新星创作者🏆,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文|经验分享|好用的网站工具分享💎💎💎 🍎座右铭:人生如棋,我愿为卒,行动虽慢,可谁曾见我后退一步?🎯🎯🎯 剑指 Offer II 089. 房屋偷盗

    2024年02月02日
    浏览(37)
  • 【LeetCode: 剑指 Offer 60. n个骰子的点数 | 数学+ 暴力递归=>记忆化搜索=>动态规划】

    🍎作者简介:硕风和炜,CSDN-Java领域新星创作者🏆,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文|经验分享|好用的网站工具分享💎💎💎 🍎座右铭:人生如棋,我愿为卒,行动虽慢,可谁曾见我后退一步?🎯🎯🎯 剑指 Offer 60. n个骰子的点

    2023年04月19日
    浏览(45)
  • 剑指offer(C++)-JZ64:求1+2+3+...+n(算法-位运算)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等及条件判断语句(A?B:C)。 数据范围: 0n≤200 进阶: 空间复杂度 O(1) ,时间复杂

    2024年02月09日
    浏览(34)
  • 【LeetCode: 剑指 Offer II 090. 环形房屋偷盗(打家窃舍) | 暴力递归=>记忆化搜索=>动态规划】

    🍎作者简介:硕风和炜,CSDN-Java领域新星创作者🏆,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文|经验分享|好用的网站工具分享💎💎💎 🍎座右铭:人生如棋,我愿为卒,行动虽慢,可谁曾见我后退一步?🎯🎯🎯 大家再看这道题目之前,

    2023年04月14日
    浏览(32)
  • 剑指offer(C++)-JZ29:顺时针打印矩阵(算法-模拟)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 则依次打印出数字 数据范围: 0 = matrix.length = 100 0 = ma

    2024年02月10日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包