前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python-剑指offer41-62

python-剑指offer41-62

作者头像
西西嘛呦
发布2020-08-26 17:40:32
4160
发布2020-08-26 17:40:32
举报

41、数组

牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?

代码语言:javascript
复制
# -*- coding:utf-8 -*-
class Solution:
    def ReverseSentence(self, s):
        # write code here
        if s is None:
            return ""
        alist = list(s.split(" "))
        return " ".join(alist[::-1])

解题思路:列表的翻转

42、数组

LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子.....LL不高兴了,他想了想,决定大\小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。LL决定去买体育彩票啦。 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何, 如果牌能组成顺子就输出true,否则就输出false。为了方便起见,你可以认为大小王是0。

代码语言:javascript
复制
# -*- coding:utf-8 -*-
class Solution:
    def IsContinuous(self, numbers):
        # write code here
        if len(numbers) == 0:
            return False
        numbers = sorted(numbers)
        count_0 = 0

        for i in range(0,len(numbers)-1):
            if numbers[i] == 0:
                count_0 += 1
            else:
                delta = numbers[i+1] - numbers[i]
                if delta < 1:
                    return False
                elif delta > 1:
                    count_0 = count_0 - delta + 1
                    if count_0 < 0:
                        return False
        return True

解题思路:大小王可以视作0,然后把数组排序。从头开始读数组,统计0的个数,然后读后面的数字,相邻两个数字之间如有间隔差值,则用0的个数来填补,如果后面的数字本来就是连续的则肯定ok,如果中间有不连续且刚好能被0填补,则也是顺子。

43、环、数组

每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去....直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)

代码语言:javascript
复制
# -*- coding:utf-8 -*- (140ms、5724k)
class Solution:
    def LastRemaining_Solution(self, n, m):
        # write code here
        if n == 0 or m == 0:
            return -1
        a = [i for i in range(n)]
        while (len(a) > 1):
            r = int((m - 1) % len(a))
            a.remove(a[r])
            a = a[r:] + a[:r]
        return a[0]

解题思路:我自己的解法就是找到,删除,调整数组。速度有点慢

另一种就是只保存删除的索引,效率较高:

代码语言:javascript
复制
class Solution:
    def LastRemaining_Solution(self, n, m):
        # write code here
        if n < 1:
            return -1
        con = list(range(n))
        final = -1
        start = 0
        while con:
            k = (start + m - 1) % n
            final = con.pop(k)
            n -= 1
            start = k
        return final

44、加法

求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

代码语言:javascript
复制
# -*- coding:utf-8 -*-
class Solution:
    def Sum_Solution(self, n):
        ans = n
        temp = ans and self.Sum_Solution(n-1)
        ans = ans + temp
        return ans

解题思路:递归。注意 python 的写法。当and和or等短路运算符,用作普通值而不是布尔值时,短路运算符的返回值是最后一次评估的参数。也就是说下面的句子中,如果ans为0,则temp为0, 如果ans不为0, 则temp就是递归了之后的值。

通过位运算的方法:

首先看十进制是如何做的: 5+7=12,三步走

第一步:相加各位的值,不算进位,得到2。

第二步:计算进位值,得到10. 如果这一步的进位值为0,那么第一步得到的值就是最终结果。

第三步:重复上述两步,只是相加的值变成上述两步的得到的结果2和10,得到12。

同样我们可以用三步走的方式计算二进制值相加: 5-101,7-111

第一步:相加各位的值,不算进位,得到010,二进制每位相加就相当于各位做异或操作,101^111。

第二步:计算进位值,得到1010,相当于各位做与操作得到101,再向左移一位得到1010,(101&111) << 1。

第三步重复上述两步, 各位相加 010^1010=1000,进位值为100=(010&1010) << 1。 继续重复上述两步:1000^100 = 1100,进位值为0,跳出循环,1100为最终结果。

代码语言:javascript
复制
public class Solution {
    public int Add(int num1,int num2) {
        while (num2!=0) {
            int temp = num1^num2;
            num2 = (num1&num2)<<1;
            num1 = temp;
        }
        return num1;
    }
}

# -*- coding:utf-8 -*-
class Solution:
    def Add(self, a, b):
        while(b):
            a, b = (a^b) & 0xFFFFFFFF,((a&b)<<1) & 0xFFFFFFFF
        return a if a<=0x7FFFFFFF else ~(a^0xFFFFFFFF)

补充一下python位运算:

x >> y # 返回 x 向右移 y 位得到的结果

x << y # 返回 x 向左移 y 位得到的结果

x & y # 与操作,xy对应的每一位,只有都为1时才为1

x | y # 或操作,xy对应的每一位,只有都为0时才为0

~x # 按位取反操作,x的每一位如果为0则变为1,如果为1则变为0,从十进制来看,结果是 -x - 1(例如,~8 = -9)

x ^ y # 异或运算,xy对应的每一位,数字不同则为1,数字相同则为0

45、字符串

将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。

代码语言:javascript
复制
# -*- coding:utf-8 -*-
class Solution:
    def StrToInt(self, s):
        # write code here
        minus = 1
        number = 0
        if not s:
            return number
        if s[0] == '+':
            if len(s) > 1:
                s = s[1:]
            else:
                return 0
        elif s[0] == '-':
            minus = -1
            if len(s) > 1:
                s = s[1:]
            else:
                return 0
        for i in range(0, len(s)):
            if '0' <= s[i] <= '9':
                number = number * 10 + ord(s[i]) - ord('0')
            else:
                return 0
        return number * minus

解题思路:记得ord(‘0’)=48,ord(‘a’)=97,ord(‘A’)=65

46、数组

在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

代码语言:javascript
复制
# -*- coding:utf-8 -*-
class Solution:
    # 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
    # 函数返回True/False
    def duplicate(self, numbers, duplication):
        # write code here
        dis = {}
        for i in list(numbers):
            if i not in dis:
                dis[i] = 1
            else:
                dis[i] += 1
        j = 0
        for i in dis:
            if dis[i] == 1:
                continue
            elif dis[i] > 1:
                j = i
                break
        if j == 0:
            return False 
        else:
            duplication[0] = j
        return True

解题思路:hash表

47、数组

给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。不能使用除法。

代码语言:javascript
复制
class Solution:
def multiply(self, A):
    ifnot A:
        return []
    b = [1] * len(A)
    for i in range(1,len(A)):
        b[i] = b[i] * A[i-1]
    tmp = 1
    for i in range(len(A)-2,1,-1):
        tmp = tmp * A[i+1]
        b[i] = b[i] *tmp
    return b

解题思路:将乘积分为两部分。

48、字符串匹配

请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配

代码语言:javascript
复制
# -*- coding:utf-8 -*-
class Solution:
    # s, pattern都是字符串
    def match(self, s, pattern):
        # 如果s与pattern都为空,则True
        if len(s) == 0 and len(pattern) == 0:
            return True
        # 如果s不为空,而pattern为空,则False
        elif len(s) != 0 and len(pattern) == 0:
            return False
        # 如果s为空,而pattern不为空,则需要判断
        elif len(s) == 0 and len(pattern) != 0:
            # pattern中的第二个字符为*,则pattern后移两位继续比较
            if len(pattern) > 1 and pattern[1] == '*':
                return self.match(s, pattern[2:])
            else:
                return False
        # s与pattern都不为空的情况
        else:
            # pattern的第二个字符为*的情况
            if len(pattern) > 1 and pattern[1] == '*':
                # s与pattern的第一个元素不同,则s不变,pattern后移两位,相当于pattern前两位当成空
                if s[0] != pattern[0] and pattern[0] != '.':
                    return self.match(s, pattern[2:])
                else:
                    # 如果s[0]与pattern[0]相同,且pattern[1]为*,这个时候有三种情况
                    # pattern后移2个,s不变;相当于把pattern前两位当成空,匹配后面的
                    # pattern后移2个,s后移1个;相当于pattern前两位与s[0]匹配
                    # pattern不变,s后移1个;相当于pattern前两位,与s中的多位进行匹配,因为*可以匹配多位
                    return self.match(s, pattern[2:]) or self.match(s[1:], pattern[2:]) or self.match(s[1:], pattern)
            # pattern第二个字符不为*的情况
            else:
                if s[0] == pattern[0] or pattern[0] == '.':
                    return self.match(s[1:], pattern[1:])
                else:
                    return False

49、类似字符串匹配

请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。

代码语言:javascript
复制
# -*- coding:utf-8 -*-
class Solution:
    # s字符串
    def isNumeric(self, s):
        # 标记符号、小数点、e是否出现过
        sign = False
        decimal = False
        has_e = False
        for i in range(len(s)):
            if s[i] == 'e' or s[i] == 'E':
                if i == len(s) - 1:
                    return False  # E后面必须跟数字,E不可以在字符串结尾
                if has_e:
                    return False  # 不可以出现两个E
                has_e = True
            elif s[i] == '+' or s[i] == '-':
                if sign and (s[i-1] != 'e' and s[i-1] != 'E'):
                    return False  # 如果是第二次出现符号,符号必须跟在E之后
                if (not sign) and (i > 0) and (s[i-1] != 'e' and s[i-1] != 'E'):
                    return False  # 如果第一次出现符号,且不是在开头出现,则必须紧跟在E之后
                sign = True
            elif s[i] == '.':
                if has_e or decimal:
                    return False  # E后面不能出现小数点,或小数点不能出现两次
                decimal = True
            elif s[i] < '0' or s[i] > '9':
                return False  # 不合法字符
        return True

50、hash

请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。

代码语言:javascript
复制
class Solution:
    def __init__(self):
        self.stream = []
        self.counter = {}
    # 返回对应char
    def FirstAppearingOnce(self):
        for c in self.stream:
            if self.counter[c] == 1:
                return c
        return '#'
    def Insert(self, char):
        if char in self.counter:
            self.counter[char] += 1
        else:
            self.counter[char] = 1
        self.stream.append(char)

51、环、链表

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

代码语言:javascript
复制
# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def EntryNodeOfLoop(self, pHead):
        # write code here
        if not pHead:
            return None
        slow = pHead
        fast = pHead
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                slow2 = pHead
                while slow2 != slow:
                    slow = slow.next
                    slow2 = slow2.next
                return slow

解题思路:快慢指针法,当slow与fast相遇时,slow走过的就是环的长度。

52、链表

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5

代码语言:javascript
复制
# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def deleteDuplication(self, pHead):
        # write code here
        if (not pHead) or (not pHead.next):
            return pHead
        head = ListNode(0)
        head.next = pHead
        pre = head
        last = head.next
        while last:
            if last.next and last.val == last.next.val:
                while last.next and last.val == last.next.val:
                    last = last.next
                pre.next = last.next
                last = last.next
            else:
                pre = pre.next
                last = last.next
        return head.next    

解题思路:注意构建新的链表。

53、树

给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。

代码语言:javascript
复制
# -*- coding:utf-8 -*-
# class TreeLinkNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#         self.next = None
class Solution:
    def GetNext(self, pNode):
        # write code here
        if not pNode:
            return None
        if pNode.right != None:
            r = pNode.right
            while r and r.left != None:
                r = r.left
        elif pNode.next != None:
            if pNode.left == None:
                if pNode.next.left == pNode:
                    r = pNode.next
                elif pNode.next.next.left != pNode.next:
                    return None
                else:
                    r = pNode.next.next
            else:
                r = pNode.next
        else:
            r = None
        return r

解题思路:要考虑多种情况

54、树

请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。

代码语言:javascript
复制
# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def isSymmetrical(self, pRoot):
        if not pRoot:
            return True
        else:
            return self.check(pRoot.left, pRoot.right)
    def check(self, left, right):
        if (not left) and (not right):
            return True
        elif not(left and right):
            return False
        if left.val != right.val:
            return False
        return self.check(left.left, right.right) and self.check(right.left, left.right)

解题思路:递归加判断。

55、树

请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。

代码语言:javascript
复制
# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def Print(self, pRoot):
        # write code here
        if not pRoot:
            return []
        stack = [pRoot]
        res = []
        while stack:
            tmp = []
            for i in range(len(stack)):
                t = stack.pop(0)
                tmp.append(t.val)
                if t.left != None:
                    stack.append(t.left)
                if t.right != None:
                    stack.append(t.right)
            res.append(tmp)
        for i in range(len(res)):
            if i & 1 == 1:
                res[i] = res[i][::-1]
        return res

解题思路:先层次遍历,再转换。

56、树

从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。

代码语言:javascript
复制
# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回二维列表[[1,2],[4,5]]
    def Print(self, pRoot):
        # write code here
        if not pRoot:
            return []
        stack = [pRoot]
        res = []
        while stack:
            tmp = []
            for i in range(len(stack)):
                t = stack.pop(0)
                tmp.append(t.val)
                if t.left != None:
                    stack.append(t.left)
                if t.right != None:
                    stack.append(t.right)
            res.append(tmp)
        return res

解题思路:就是层次遍历。

57、树

请实现两个函数,分别用来序列化和反序列化二叉树

代码语言:javascript
复制
# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def __init__(self):
        self.flag = -1
    def Serialize(self, root):
        # write code here
        if not root:
            return '#,'
        return str(root.val)+','+self.Serialize(root.left)+self.Serialize(root.right)
    def Deserialize(self, s):
        # write code here
        self.flag += 1
        l = s.split(',')
        if self.flag >= len(s):
            return None
        root = None
        if l[self.flag] != '#':
            root = TreeNode(int(l[self.flag]))
            root.left = self.Deserialize(s)
            root.right = self.Deserialize(s)
        return root

解题思路:递归前序遍历二叉树,对每个节点的孩子如果遇到空就以#来代替,最终得到一个字符串。读取字符串,当前字符作为根,下一个字符作为当前的左孩子,依此递归进行前序遍历,恢复树结构。

58、二叉排序树

给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。

代码语言:javascript
复制
# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回对应节点TreeNode
    def __init__(self):
        self.cur = 0
    def KthNode(self, pRoot, k):
        # write code here
        if k <= 0:
            return None
        if pRoot == None:
            return None
        left_val = self.KthNode(pRoot.left,k)
        if left_val:
            return left_val
        self.cur += 1
        if self.cur == k:
            return pRoot
        right_val = self.KthNode(pRoot.right, k)
        if right_val:
            return right_val
        return None

解题思路:递归左子树,并判断有无返回节点。如果有,停止递归,返回所要返回的节点;当左子树没有返回节点时,判断当前的根节点是不是第k个遍历到的值(即第k大)。如果是,则返回该节点,停止递归;当左子树和根节点都没有返回节点时,递归右子树,并判断有无返回节点。如果有,停止递归,返回所要返回的节点。

59、堆

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

代码语言:javascript
复制
# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.arr=[]
    def Insert(self, num):
        self.arr.append(num)
        self.arr.sort()
    def GetMedian(self,fuck):
        length=len(self.arr)
        return self.arr[length//2] if length%2==1 else (self.arr[length//2]+self.arr[length//2-1])/2.0

这是一般人的思想,另一种是考虑用堆;

代码语言:javascript
复制
import math
import heapq

class Solution:
    nums = []
    def Insert(self, num):
        heapq.heappush(self.nums, num)

    def GetMedian(self):
        mid = math.ceil(len(self.nums)/2)
        return (heapq.nlargest(mid, self.nums)[-1] + heapq.nsmallest(mid, self.nums)[-1])/2.0

60、数组

给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。

代码语言:javascript
复制
# -*- coding:utf-8 -*-
class Solution:
    def maxInWindows(self, num, size):
        # write code here
        if size <= 0:
            return []
        left = 0
        right = size - 1
        res = []
        while right <= len(num) - 1:
            tmp = num[left:right+1]
            m = max(tmp)
            res.append(m)
            left += 1
            right += 1
        return res

61、递归、回溯、匹配

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。

代码语言:javascript
复制
class Solution:
    def hasPath(self, matrix, rows, cols, path):
        # write code here
        if not matrix and rows <= 0 and cols <= 0 and path == None:
            return False
        # 模拟的字符矩阵
        markmatrix = [0] * (rows * cols)
        pathlength = 0
        # 从第一个开始递归,当然第一二个字符可能并不位于字符串之上,所以有这样一个双层循环找起点用的,一旦找到第一个符合的字符串,就开始进入递归,
        # 返回的第一个return Ture就直接跳出循环了。
        for row in range(rows):
            for col in range(cols):
                if self.hasPathCore(matrix, rows, cols, row, col, path, pathlength, markmatrix):
                    return True
        return False
    def hasPathCore(self, matrix, rows, cols, row, col, path, pathlength, markmatrix):
        # 说明已经找到该路径,可以返回True
        if len(path) == pathlength:
            return True
        hasPath = False
        if row >= 0 and row < rows and col >= 0 and col < cols and matrix[row * cols + col] == path[pathlength] and not \
                markmatrix[row * cols + col]:
            pathlength += 1
            markmatrix[row * cols + col] = True
            # 进行该值上下左右的递归
            hasPath = self.hasPathCore(matrix, rows, cols, row - 1, col, path, pathlength, markmatrix) \
                      or self.hasPathCore(matrix, rows, cols, row, col - 1, path, pathlength, markmatrix) \
                      or self.hasPathCore(matrix, rows, cols, row + 1, col, path, pathlength, markmatrix) \
                      or self.hasPathCore(matrix, rows, cols, row, col + 1, path, pathlength, markmatrix)
            # 对标记矩阵进行布尔值标记
            if not hasPath:
                pathlength -= 1
                markmatrix[row * cols + col] = False
        return hasPath

62、递归、回溯

地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?

代码语言:javascript
复制
# -*- coding:utf-8 -*-
class Solution:
    def movingCount(self, threshold, rows, cols):
        # write code here
        markmatrix = [False] * (rows * cols)
        count = self.GetNum(threshold, rows, cols, 0, 0, markmatrix)
        return count
    def GetNum(self, threshold, rows, cols, row, col, markmatrix):
        count = 0
        if self.GetSum(threshold, rows, cols, row, col, markmatrix):
            markmatrix[row * cols + col] = True
            count = 1 + self.GetNum(threshold, rows, cols, row - 1, col, markmatrix) + \
                    self.GetNum(threshold, rows, cols, row, col - 1, markmatrix) + \
                    self.GetNum(threshold, rows, cols, row + 1, col, markmatrix) + \
                    self.GetNum(threshold, rows, cols, row, col + 1, markmatrix)
        return count
    def GetSum(self, threshold, rows, cols, row, col, markmatrix):
        if row >= 0 and row < rows and col >= 0 and col < cols and self.getDigit(row) + self.getDigit(
                col) <= threshold and not markmatrix[row * cols + col]:
            return True
        return False
    def getDigit(self, number):
        sumNum = 0
        while number > 0:
            sumNum += number % 10
            number = number // 10
        return sumNum

解题思路:回溯法,递归,注意判断条件。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-06-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档