剑指offer---其他记录

目录

56. 从1到n整数中1出现的次数

58. 把数组排成最小的数

59. 把数字翻译成字符串

60. 礼物的最大价值

61. 最长不含重复字符的子字符串

62. 丑数

63. 字符串中第一个只出现一次的字符

64. 字符流中第一个只出现一次的字符

65. 数组中的逆序对

66. 两个链表的第一个公共结点

67. 数字在排序数组中出现的次数

68. 0到n-1中缺失的数字

69. 数组中数值和下标相等的元素

70. 二叉搜索树的第k个结点

71. 二叉树的深度

72. 平衡二叉树

73. 数组中只出现一次的两个数字

74. 数组中唯一只出现一次的数字

75. 和为S的两个数字

76. 和为S的连续正数序列

77. 翻转单词顺序

78. 左旋转字符串

79. 滑动窗口的最大值

80. 骰子的点数

81. 扑克牌的顺子

82. 圆圈中最后剩下的数字

83. 股票的最大利润

84. 求1+2+…+n

85. 不用加减乘除做加法

86. 构建乘积数组



 


56. 从1到n整数中1出现的次数

输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。

例如输入12,从1到12这些整数中包含“1”的数字有1,10,11和12,其中“1”一共出现了5次。

样例

输入: 12
输出: 5

 从1到abcdef,c位1的个数sum分为2部分:

sum += abc * 1000
if c > 1: sum += 1000; if c == 1: sum += def + 1

时间复杂度: O(log(n))
空间复杂度: O(1)

class Solution(object):
    def numberOf1Between1AndN_Solution(self, n):
        """
        :type n: int
        :rtype: int
        """
        ab=n
        c=0
        digital =1
        defg=0
        sum=0
        
        while ab>0:
            c=ab%10
            ab//=10
            sum+=ab*digital
            if c==1:
                sum+=(defg+1)
            elif c>1:
                sum+=digital
            defg+=c*digital
            digital*=10
        return sum

 


58. 把数组排成最小的数

输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。

例如输入数组[3, 32, 321],则打印出这3个数字能排成的最小数字321323。

样例

输入:[3, 32, 321]

输出:321323

注意:输出数字的格式为字符串。

直接引入cmp_to_key()定义比较规则,定义条件是key = cmp_to_key(lambda x,y:int(x+y)-int(y+x))

from functools import cmp_to_key
class Solution(object):
    def printMinNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: str
        """
        if nums==[]:
            return ''
        res=[]
        for  i in nums:
            res.append(str(i))
        res.sort(key = cmp_to_key(lambda x,y:int(x+y)-int(y+x)))
        return ''.join(res)

 


59. 把数字翻译成字符串

给定一个数字,我们按照如下规则把它翻译为字符串:

0翻译成”a”,1翻译成”b”,……,11翻译成”l”,……,25翻译成”z”。

一个数字可能有多个翻译。例如12258有5种不同的翻译,它们分别是”bccfi”、”bwfi”、”bczi”、”mcfi”和”mzi”。

请编程实现一个函数用来计算一个数字有多少种不同的翻译方法。

样例

输入:"12258"

输出:5

问题的核心是动态规划,利用dp[i]表示到i位置所有可能得翻译方法,因此需要考虑s[i-2:i],即i-2位置和i1位置的组合数字,如果数字在‘10’---‘25’之间的话,可能有dp[i-1]+dp[i-2]种翻译方法,否则的话,dp[i]=dp[i-1],例如‘67’这样的数字,只有可能有一种翻译方式

其次考虑初始情况,即dp[0]=1,dp[1]=1,表示到当前位置的可能翻译方法,初始化为(n+1)维,因为n实际上是错开1维的。

class Solution:
    def getTranslationCount(self, s):
        """
        :type s: str
        :rtype: int
        """
        n=len(s)
        dp=[0]*(n+1)
        dp[0]=1;dp[1]=1
        for i in range(2,n+1):
            if '10'<=s[i-2:i]<='25':
                dp[i]=dp[i-2]+dp[i-1]
            else:
                dp[i] = dp[i-1]
        return dp[n]

60. 礼物的最大价值

在一个m×n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于0)。

你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格直到到达棋盘的右下角。

给定一个棋盘及其上面的礼物,请计算你最多能拿到多少价值的礼物?

注意:

  • m,n>0m,n>0

样例:

输入:
[
  [2,3,1],
  [1,7,1],
  [4,6,1]
]

输出:19

解释:沿着路径 2→3→7→6→1 可以得到拿到最大价值礼物。

 动态规划,相当于利用dp数组记录到当前位置的最大价值礼物,因为是相当于对grid的复制,因此初始化为n*m维即可,dp[0][0]中应该存放grid[0][0]的具体数值,第一行和第一列中从左往右,从上往下直接加即可,要注意行走路径只能向右或者向下

class Solution(object):
    def getMaxValue(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: int
        """
        n = len(grid)
        m = len(grid[0])
        dp = [[0]*(m) for _ in range(n)]
        dp[0][0] = grid[0][0]
        
        for i in range(1,n):
            dp[i][0] = dp[i-1][0]+grid[i][0]
        for j in range(1,m):
            dp[0][j] = dp[0][j-1]+grid[0][j]
            
        for i in range(1,n):
            for j in range(1,m):
                dp[i][j] =max(dp[i-1][j],dp[i][j-1]) + grid[i][j]
        return dp[-1][-1]

61. 最长不含重复字符的子字符串

请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。

假设字符串中只包含从’a’到’z’的字符。

样例

输入:"abcabc"

输出:3
class Solution:
    def longestSubstringWithoutDuplication(self, s):
        """
        :type s: str
        :rtype: int
        """
        if not s:
            return 0
        n=len(s)
        d=dict()
        dp=[0]*n
        res=0
        for i in range (0,n):
            if s[i] not in d.keys():
                dp[i] =dp[i-1] + 1
            else:
                dist=i-d[s[i]]
                if dist > dp[i-1]:
                    dp[i] = dp[i-1]+1
                else:
                    dp[i] = dist
            d[s[i]] = i
            res=max(dp[i],res)
          
        return res


62. 丑数

我们把只包含质因子2、3和5的数称作丑数(Ugly Number)。

例如6、8都是丑数,但14不是,因为它包含质因子7。

求第n个丑数的值。

样例

输入:5

输出:5

注意:习惯上我们把1当做第一个丑数。

class Solution(object):
    def getUglyNumber(self, n):
        """
        :type n: int
        :rtype: int
        """
        i=0;j=0;k=0
        q=[1]
        n-=1
        while n:
            n-=1
            t = min(min(q[i]*2,q[j]*3),q[k]*5)
            q.append(t)
            if t==q[i]*2:
                i+=1
            if t==q[j]*3:
                j+=1
            if t==q[k]*5:
                k+=1
    #        print(q)
        return q[-1]

63. 字符串中第一个只出现一次的字符

在字符串中找出第一个只出现一次的字符。

如输入"abaccdeff",则输出b

如果字符串中不存在只出现一次的字符,返回#字符。

样例:

输入:"abaccdeff"

输出:'b'
class Solution:
    def firstNotRepeatingChar(self, s):
        """
        :type s: str
        :rtype: str
        """
        d={}
        
        for i in range(len(s)):
            if s[i] in d:
                d[s[i]]+=1
            else:
                d[s[i]] =1
        for i in range(len(s)):
            if d[s[i]]== 1:
                return s[i]
        return '#'

64. 字符流中第一个只出现一次的字符

请实现一个函数用来找出字符流中第一个只出现一次的字符。

例如,当从字符流中只读出前两个字符”go”时,第一个只出现一次的字符是’g’。

当从该字符流中读出前六个字符”google”时,第一个只出现一次的字符是’l’。

如果当前字符流没有存在出现一次的字符,返回#字符。

样例

输入:"google"

输出:"ggg#ll"

解释:每当字符流读入一个字符,就进行一次判断并输出当前的第一个只出现一次的字符。
class Solution: 
    d=dict()
    res=[]
    def firstAppearingOnce(self):
        """
        :rtype: str
        """
        if self.res :
        #    print(self.res)
            return self.res[0]
        return '#'
        
    def insert(self, char):
        """
        :type char: str
        :rtype: void
        """
        if char not in self.d:
            self.d[char] =1
        else:
            self.d[char] +=1
        #print(self.d[char])
        if self.d[char]>1:
        #print('origial:',self.res)
            while (self.res and self.d[self.res[0]] > 1):
                self.res.pop(0)
        else:
            self.res.append(char)
        #print('last:',self.res)

动态维护,当进来一个新字母中在字典中存储其出现的次数,如果出现超过2次,就要从队头开始依次pop先进来的元素,如果是新出现的字母的话直接push进去就可以了,注意返回的是队列的队头元素,即返回res[0]


65. 数组中的逆序对

在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。

输入一个数组,求出这个数组中的逆序对的总数。

样例

输入:[1,2,3,4,5,6,0]

输出:6

 

class Solution(object):
    count = 0
    def inversePairs(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        self.merge(nums)
        return self.count


    def merge(self, nums):
        if len(nums) <= 1:
            return nums
        else:
            mid = len(nums) // 2
        left = self.merge(nums[:mid])
        right = self.merge(nums[mid:])
        return self.merge_sort(left, right)

    def merge_sort(self, a, b):
        la = len(a)
        lb = len(b)
        c = []
        a.append(float('inf'))
        b.append(float('inf'))
        i, j = 0, 0
        for x in range(0, la + lb):
            if a[i] < b[j]:
                c.append(a[i])
                i += 1
            else:
                c.append(b[j])
                j += 1
                self.count += la - i
        return c


66. 两个链表的第一个公共结点

输入两个链表,找出它们的第一个公共结点。

当不存在公共节点时,返回空节点。

样例

给出两个链表如下所示:
A:        a1 → a2
                   ↘
                     c1 → c2 → c3
                   ↗            
B:     b1 → b2 → b3

输出第一个公共节点c1
# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def findFirstCommonNode(self, headA, headB):
        """
        :type headA, headB: ListNode
        :rtype: ListNode
        """
        i=headA;j=headB
        while i!=j:
            if i:i=i.next
            else:i=headB
            
            if j:j=j.next
            else:j=headA
        return i

A+C+B=B+C+A,要注意判断条件是if i,才能保证没有相交时两个指针都能到达Null如果是if i.next的话。没有相交时二者会陷入死循还


67. 数字在排序数组中出现的次数

统计一个数字在排序数组中出现的次数。

例如输入排序数组[1, 2, 3, 3, 3, 3, 4, 5]和数字3,由于3在这个数组中出现了4次,因此输出4。

样例

输入:[1, 2, 3, 3, 3, 3, 4, 5] ,  3

输出:4
class Solution(object):
    def getNumberOfK(self, nums, k):
        """
        :type nums: list[int]
        :type k: int
        :rtype: int
        """
        if not nums:
            return 0
        l=0;r=len(nums)-1
        while l<r:
            mid=(l+r)//2
            if nums[mid] <k:
                l=mid+1
            else:
                r=mid
        if nums[l] !=k:
            return 0
        left=l
        l=0;r=len(nums)-1
        while l<r:
            mid=(l+r+1)//2
            if nums[mid] <=k:
                l=mid
            else:
                r=mid-1
        return r-left+1

二分查找模板

两种划分模式:中点mid是属于左区间还是右区间的,如果nums[x]<k,则用第一种模板,因为mid属于左区间

                          如果nums[x]<=k,则用第二种模板,因为mid属于右区间

当我们将区间[l, r]划分成[l, mid]和[mid + 1, r]时,其更新操作是r = mid或者l = mid + 1;,计算mid时不需要加1。

int bsearch_1(int l, int r)
{
     while (l < r)

    {

        int mid = l + r >> 1;
        if (check(mid)) r = mid;
        else l = mid + 1;

    }
    return l;
}

二.需要加1的情况

当我们将区间[l, r]划分成[l, mid - 1]和[mid, r]时,其更新操作是r = mid - 1或者l = mid;,此时为了防止死循环,计算mid时需要加1。

int bsearch_2(int l, int r)

{
    while (l < r)
    {
        int mid = l + r + 1 >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }

    return l;
}

 


68. 0到n-1中缺失的数字

一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0到n-1之内。

在范围0到n-1的n个数字中有且只有一个数字不在该数组中,请找出这个数字。

样例

输入:[0,1,2,4]

输出:3
class Solution(object):
    def getMissingNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums:
            return 0
            
        l=0;r=len(nums)-1
        while(l<r):
            mid=l+r>>1
            if nums[mid]==mid:
                l=mid+1
            else:
                r=mid
                
        if nums[r]==r:
            r+=1
        return r

判断划分条件是nums[mid] == mid,左边的均满足这个条件,右边的均不满足此条件,

注意的是当所有的nums[r]==r时,表示此时缺失的是n

 


69. 数组中数值和下标相等的元素

假设一个单调递增的数组里的每个元素都是整数并且是唯一的。

请编程实现一个函数找出数组中任意一个数值等于其下标的元素。

例如,在数组[-3, -1, 1, 3, 5]中,数字3和它的下标相等。

样例

输入:[-3, -1, 1, 3, 5]

输出:3

注意:如果不存在,则返回-1。

class Solution(object):
    def getNumberSameAsIndex(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        l=0;r=len(nums)-1
        while l<r:
            mid = l+r>>1
            if nums[mid]<mid:
                l=mid+1
            else:
                r=mid
        if nums[r]==r:
            return r
        else: 
            return -1

70. 二叉搜索树的第k个结点

给定一棵二叉搜索树,请找出其中的第k小的结点。

你可以假设树和k都存在,并且1≤k≤树的总结点数。

样例

输入:root = [2, 1, 3, null, null, null, null] ,k = 3

    2
   / \
  1   3

输出:3

 

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def kthNode(self, root, k):
        """
        :type root: TreeNode
        :type k: int
        :rtype: TreeNode
        """
        res=[]
        self.flag =k
        def middle_sort(root:TreeNode,k):
            if not root:
                return
            middle_sort(root.left,k)
            #res.append(root)
            self.flag-=1
            if not self.flag:
                res.append(root)
                return 
            middle_sort(root.right,k)
            
        middle_sort(root,k)
        return res[0]

要注意审题,题目中返回节点,所以在res.append()的时候要append(root)


71. 二叉树的深度

输入一棵二叉树的根结点,求该树的深度。

从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

样例

输入:二叉树[8, 12, 2, null, null, 6, 4, null, null, null, null]如下图所示:
    8
   / \
  12  2
     / \
    6   4

输出:3
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def treeDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if not root:
            return 0
        left = self.treeDepth(root.left)
        right = self.treeDepth(root.right)
        
        return max(left,right)+1

72. 平衡二叉树

输入一棵二叉树的根结点,判断该树是不是平衡二叉树。

如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。

注意:

  • 规定空树也是一棵平衡二叉树。

样例

输入:二叉树[5,7,11,null,null,12,9,null,null,null,null]如下所示,
    5
   / \
  7  11
    /  \
   12   9

输出:true
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    flag=True
    def isBalanced(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        def dfs(root):
            if not root:
                return 0
            
            left = dfs(root.left)
            right = dfs(root.right)
        
            if abs(left-right>1):
                self.flag=False
            return max(left,right)+1
            
        dfs(root)
        return self.flag

73. 数组中只出现一次的两个数字

一个整型数组里除了两个数字之外,其他的数字都出现了两次。

请写程序找出这两个只出现一次的数字。

你可以假设这两个数字一定存在。

样例

输入:[1,2,3,3,4,4]

输出:[1,2]
class Solution(object):
    def findNumsAppearOnce(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
 
        diff = 0
        for i in nums:
            diff ^=i
        mask =1
        
        while diff & mask ==0:
            mask<<=1
            
        num1=0;num2=0
        for num in nums:
            if num & mask==0:  #注意是num与mask的与运算将所有数据分成两组
                num1^=num
            else:
                num2^=num
                
        return [num1,num2]
        

74. 数组中唯一只出现一次的数字

在一个数组中除了一个数字只出现一次之外,其他数字都出现了三次。

请找出那个只出现一次的数字。

你可以假设满足条件的数字一定存在。

思考题:

  • 如果要求只使用 O(n)的时间和额外 O(1)的空间,该怎么做呢?

样例

输入:[1,1,1,2,2,2,3,4,4,4]

输出:3
class Solution(object):
    def findNumberAppearingOnce(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        count = [0]*32
       
        
        for num in nums:
            k=0                     #循环的时候每次k的值都要赋值为0
            while k<32:
                count[k]+= num>>k &1
                k+=1
        
        res =0 
        for i in range(32):
            res += count[i] %3 * pow(2,i)
        return res

75. 和为S的两个数字

输入一个数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。

如果有多对数字的和等于s,输出任意一对即可。

你可以认为每组输入中都至少含有一组满足条件的输出。

样例

输入:[1,2,3,4] , sum=7

输出:[3,4]
class Solution(object):
    def findNumbersWithSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        d={}
        for num in nums:
            if num in d.keys():
                return [target-num,num]
            else:
                d[target-num] = num

 


76. 和为S的连续正数序列

输入一个正数s,打印出所有和为s的连续正数序列(至少含有两个数)。

例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续序列1~5、4~6和7~8。

样例

输入:15

输出:[[1,2,3,4,5],[4,5,6],[7,8]]
class Solution(object):
    def findContinuousSequence(self, sum):
        """
        :type sum: int
        :rtype: List[List[int]]
        """
        s=0;j=1;res=[]
        for i in range(1,sum//2+1):
            while s<sum:
                s+=j
                j+=1
            path=[]
            if s==sum and i<j:
                for k in range(i,j):
                    path.append(k)
                res.append(path)
                
            s-=i
        return res


77. 翻转单词顺序

输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。

为简单起见,标点符号和普通字母一样处理。

例如输入字符串"I am a student.",则输出"student. a am I"

样例

输入:"I am a student."

输出:"student. a am I"

 

class Solution(object):
    
    def reverse(self,s):
        start = 0
        end = len(s)-1
        while start<end:
            s[start],s[end] = s[end],s[start]
            start+=1
            end-=1
            
    def reverseWords(self, s):
        """
        :type s: str
        :rtype: str
        """
        s= list(s.split(" "))
        self.reverse(s)
        return " ".join(s)

 


78. 左旋转字符串

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。

请定义一个函数实现字符串左旋转操作的功能。

比如输入字符串"abcdefg"和数字2,该函数将返回左旋转2位得到的结果"cdefgab"

注意:

  • 数据保证n小于等于输入字符串的长度。

样例

输入:"abcdefg" , n=2

输出:"cdefgab"
class Solution(object):
    def reverse (self,s,l,r):
        r-=1                   #要注意r-=1的情况,因为最大下标为r-1,会产生溢出
        while l<r:
            s[l],s[r] = s[r],s[l]
            l+=1
            r-=1
            
    def leftRotateString(self, s, n):
        """
        :type s: str
        :type n: int
        :rtype: str
        """
        s=list(s)
        self.reverse(s,0,len(s))
        self.reverse(s,0,len(s)-n)
        self.reverse(s,len(s)-n,len(s))
        return "".join(s)
        

79. 滑动窗口的最大值

给定一个数组和滑动窗口的大小,请找出所有滑动窗口里的最大值。

例如,如果输入数组[2, 3, 4, 2, 6, 2, 5, 1]及滑动窗口的大小3,那么一共存在6个滑动窗口,它们的最大值分别为[4, 4, 6, 6, 6, 5]。

注意:

  • 数据保证k大于0,且k小于等于数组长度。

样例

输入:[2, 3, 4, 2, 6, 2, 5, 1] , k=3

输出: [4, 4, 6, 6, 6, 5]
from collections import deque
class Solution(object):
    def maxInWindows(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        q = deque([])
        res=[]
        for i in range(len(nums)):
            if i< k-1:
                while q and q[-1]<nums[i]:
                    q.pop()
                q.append(nums[i])
       
            else:
                
                while q and q[-1] <nums[i]:
                    q.pop()
                q.append(nums[i])
                res.append(q[0])
                
                if nums[i-k+1] == q[0]:
                    q.popleft()
                
        return res
                

 


80. 骰子的点数

将一个骰子投掷n次,获得的总点数为s,s的可能范围为n~6n。

掷出某一点数,可能有多种掷法,例如投掷2次,掷出3点,共有[1,2],[2,1]两种掷法。

请求出投掷n次,掷出n~6n点分别有多少种掷法。

样例1

输入:n=1

输出:[1, 1, 1, 1, 1, 1]

解释:投掷1次,可能出现的点数为1-6,共计6种。每种点数都只有1种掷法。所以输出[1, 1, 1, 1, 1, 1]。

样例2

输入:n=2

输出:[1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]

解释:投掷2次,可能出现的点数为2-12,共计11种。每种点数可能掷法数目分别为1,2,3,4,5,6,5,4,3,2,1。

      所以输出[1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]。
class Solution(object):
    def numberOfDice(self, n):
        """
        :type n: int
        :rtype: List[int]
        """
        dp = [[0]*(6*n+1) for _ in range(n+1)]   #初始化---行为所有可能的和,列为投递的次数n
        dp[0][0] = 1
        res=[]
    #dp[i][j]表示投递i次和为sum的总方案数    
        for i in range(1,n+1):
            for j in range(1,(6*i)+1):
                m=min(j,6)
                for k in range(1,m+1):
                    dp[i][j] += dp[i-1][j-k]
                    
        for i in range(n,6*n+1):
            res.append(dp[n][i])
            
        return res

 


81. 扑克牌的顺子

从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。

2~10为数字本身,A为1,J为11,Q为12,K为13,大小王可以看做任意数字。

为了方便,大小王均以0来表示,并且假设这副牌中大小王均有两张。

样例1

输入:[8,9,10,11,12]

输出:true

样例2

输入:[0,8,9,11,12]

输出:true
class Solution(object):
    def isContinuous(self, numbers):
        """
        :type numbers: List[int]
        :rtype: bool
        """
        if len(numbers)<5:
            return False
        numbers.sort()
        
        cnt=0
        for num in numbers:
            if num==0:cnt+=1
            
        for i in range(cnt,len(numbers)-1):
            if numbers[i]==numbers[i+1]:
                return False
            cnt-=numbers[i+1]-numbers[i]-1
        
        if cnt >=0:
            return True
        else: 
            return False

82. 圆圈中最后剩下的数字

0, 1, …, n-1这n个数字(n>0)排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字。

求出这个圆圈里剩下的最后一个数字。

样例

输入:n=5 , m=3

输出:3

题意:让小朋友们围成一个大圈。然后,随机指定一个数 m,让编号为 0 的小朋友开始报数。每次喊到 m-1 的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续 0...m-1 报数 .... 这样下去 .... 直到剩下最后一个小朋友,可以不用表演。

class Solution(object):
    def lastRemaining(self, n, m):
        """
        :type n: int
        :type m: int
        :rtype: int
        """
        return 0 if n == 1 else (self.lastRemaining(n - 1, m) + m) % n

83. 股票的最大利润

假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖 一次 该股票可能获得的利润是多少?

例如一只股票在某些时间节点的价格为[9, 11, 8, 5, 7, 12, 16, 14]。

如果我们能在价格为5的时候买入并在价格为16时卖出,则能收获最大的利润11。

样例

输入:[9, 11, 8, 5, 7, 12, 16, 14]

输出:11
class Solution(object):
    def maxDiff(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        res=0;minv=float("inf")
        
        for num in nums:
            minv = min(minv,num)
            res = max(res,num-minv)
        return res

84. 求1+2+…+n

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

样例

输入:10

输出:55
import functools
class Solution(object):
    def getSum(self, n):
        """
        :type n: int
        :rtype: int
        """
        return functools.reduce(lambda x, y: x+y, range(n+1))


class Solution {
public:
    int getSum(int n) {
       int res = n;
       //if(n>0) res=+getSum(n-1);
       n>0 && (res += getSum(n-1));  //与运算起到if语句的作用
       return res;
    }
};

85. 不用加减乘除做加法

写一个函数,求两个整数之和,要求在函数体内不得使用+、-、×、÷ 四则运算符号。

样例

输入:num1 = 1 , num2 = 2

输出:3
class Solution {
    //异或又叫无进位加法    D=A^B  计算机里数电的基础实现
    //进位 可以用与操作实现 C=A&B   多位数并行计算分成两步 先不考虑进位 再加上所有的进位 (A&B)<<1左移一位
public:
    int add(int num1, int num2){
        //假设num2末尾有k个0,num1&num2左移之后就会有k+1个0,因此最多循环32次,因为是32位数
        while(num2) {
        int sum = num1 ^ num2;     //更新将得到的sum值与上一次的异或值继续做异或,直到进位为0
        int carry =(num1 & num2) << 1;
        num1 = sum;
        num2 =carry;
        }
        return num1;
    }
};

#python里面会爆栈,递归不能太多层

86. 构建乘积数组

给定一个数组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]

不能使用除法。

样例

输入:[1, 2, 3, 4, 5]

输出:[120, 60, 40, 30, 24]

思考题

  • 能不能只使用常数空间?(除了输出的数组之外)
class Solution(object):
    def multiply(self, A):
        """
        :type A: List[int]
        :rtype: List[int]
        """
        if not A or len(A) == 0:
            return []
        tmp = 1
        res = []
        B = [0 for _ in range(len(A))]
        B[0] = 1
        for i in range(1, len(A)):
            B[i] = B[i - 1] * A[i - 1]
        # 得到的是A[0]乘到A[i - 1]
        for j in range(len(A) - 2, -1, -1):
            tmp *= A[j + 1]
            B[j] *= tmp
        # 乘上去的是A[n - 1]到A[i + 1] 
        return B

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值