Leetcode——初级部分——数组部分——Python实现

从排序数组中删除重复项

给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

示例 1:

给定数组 nums = [1,1,2], 

函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2

你不需要考虑数组中超出新长度后面的元素。

示例 2:

给定 nums = [0,0,1,1,1,2,2,3,3,4],

函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4

你不需要考虑数组中超出新长度后面的元素。

说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);

// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。
for (int i = 0; i < len; i++) {
    print(nums[i]);
}

我的解答:

方法1:先排序后判断

步骤1:对于已经排序的列表,可以通过对列表进行遍历,若nums[i]与nums[i+1]相同,删除nums[i]。

步骤2:直接此次循环结束,然后将num[i+1]与之后的数据进行比较。

class Solution:
    def removeDuplicates(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        i = 0
        while i < len(nums) - 1:
            if(nums[i] == nums[i+1]):
                nums.remove(nums[i])
            else:
                i = i + 1
        return len(nums)


买卖股票的最佳时机 II

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:

输入: [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
     随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。

示例 2:

输入: [1,2,3,4,5]
输出: 4
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
     注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。
     因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。

示例 3:

输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

我的解答:

采用贪心算法:低价买入,向后判断,高于前一天的价格即可卖出。之后将这一天的价格买入,继续向后判断。

class Solution:
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        if len(prices) < 2:
            return 0
        min_price = prices[0]
        max_profit = 0
        for i in prices:
            if i > min_price:
                max_profit = max_profit + i - min_price
            min_price = i
        return max_profit

旋转数组

给定一个数组,将数组中的元素向右移动 个位置,其中 是非负数。

示例 1:

输入: [1,2,3,4,5,6,7] 和 k = 3输出: [5,6,7,1,2,3,4]
解释:
向右旋转 1 步: [7,1,2,3,4,5,6]
向右旋转 2 步: [6,7,1,2,3,4,5]
向右旋转 3 步: [5,6,7,1,2,3,4]

示例 2:

输入: [-1,-100,3,99] 和 k = 2输出: [3,99,-1,-100]
解释: 
向右旋转 1 步: [99,-1,-100,3]
向右旋转 2 步: [3,99,-1,-100]

说明:

  • 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
  • 要求使用空间复杂度为 O(1) 的原地算法。

我的解答:

方法1:采用列表切片来完成

class Solution:
    def rotate(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: void Do not return anything, modify nums in-place instead.
        """
        l = len(nums)
        nums[:] = nums[l-k:] + nums[:l-k]

存在重复

给定一个整数数组,判断是否存在重复元素。

如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。

示例 1:

输入: [1,2,3,1]
输出: true

示例 2:

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

示例 3:

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

我的解答:

方法1:先用自带的函数把数组进行从小到大的排序,然后进行遍历(如果一个元素和下一个元素相等,就返回True)

class Solution:
    def containsDuplicate(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        nums.sort()
        for i in range(len(nums)-1):
            if(nums[i] == nums[i+1]):
                return True
        return False


只出现一次的数字

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:

你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:

输入: [2,2,1]
输出: 1

示例 2:

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

我的解答:

方法1:先进行从小到大排序,然后前一个和后一个数进行对比(以2为间隔的循环)

class Solution:
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        #先进行从小到大排序,然后前一个和后一个数进行对比(以2为间隔的循环)
        nums.sort()
        for i in range(0,len(nums),2): #range(start,end,step=1)
            if(i == len(nums)-1):
                return nums[i]
            elif(nums[i] != nums[i+1]):
                return nums[i]

方法2:哈希表实现

class Solution:
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """ 
        #哈希表实现?
        numDict = {}
        #建立哈希表
        for i in nums:
            if i in numDict:
                numDict[i] = numDict[i] + 1                
            else:
                numDict[i] = 1
        #检查哈希表,进行判断
        for i in nums:
            if numDict[i] == 1:
                return i


两个数组的交集 II

给定两个数组,写一个方法来计算它们的交集。

例如:
给定 nums1 = [1, 2, 2, 1]nums2 = [2, 2], 返回 [2, 2].

注意:

  •    输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
  •    我们可以不考虑输出结果的顺序。

跟进:

  • 如果给定的数组已经排好序呢?你将如何优化你的算法?
  • 如果 nums1 的大小比 nums2 小很多,哪种方法更优?
  • 如果nums2的元素存储在磁盘上,内存是有限的,你不能一次加载所有的元素到内存中,你该怎么办?

我的解答:

使用哈希表用来存储第一个数组中的内容。再遍历第二个数组,看该数组的数字是否在哈希表中,在则将该数字加入输出的列表中。

class Solution:
    def intersect(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: List[int]
        """
        hashList = {}
        output = []
        # 数组1写入哈希表
        for i in nums1:
            if i in hashList:
                hashList[i] = hashList[i] + 1
            else:
                hashList[i] = 1
        # 判断数组2元素是否在哈希表
        for i in nums2:
            if i in hashList:
                if hashList[i] > 0:
                    output.append(i)
                    hashList[i] = hashList[i] - 1
        return output

加一

给定一个非负整数组成的非空数组,在该数的基础上加一,返回一个新的数组。

最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。

你可以假设除了整数 0 之外,这个整数不会以零开头。

示例 1:

输入: [1,2,3]
输出: [1,2,4]
解释: 输入数组表示数字 123。

示例 2:

输入: [4,3,2,1]
输出: [4,3,2,2]
解释: 输入数组表示数字 4321。

我的解答:

list——>int——>+1、求长度——>list——>list反向操作

class Solution:
    def plusOne(self, digits):
        """
        :type digits: List[int]
        :rtype: List[int]
        """
        number = 0
        length = len(digits) #确定数字位数
        for i in range(length):
            number = number + digits[length - 1 - i] * pow(10,i) #pow(x,y)次方函数; list——>int; 这里需要注意list[0]是最高位,所以需要反一下!!
        
        number = number + 1 #该数的基础上加一
        length = len(str(number)) #int型数据求数据位数
        
        nums = []
        for j in range(length):
            nums.append(number % 10) #list定义+更新
            number = number // 10 #注意:如果这里没有取整就会得到小数!!
        nums.reverse() #list反向处理
            
        return nums
注意:number/10变成浮点数,精度损失了,然后再int得到的数就不正确,需要用整除//


移动零

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

示例:

输入: [0,1,0,3,12]
输出: [1,3,12,0,0]

说明:

  1. 必须在原数组上操作,不能拷贝额外的数组。
  2. 尽量减少操作次数。

我的解答:

class Solution:
    def moveZeroes(self, nums):
        """
        :type nums: List[int]
        :rtype: void Do not return anything, modify nums in-place instead.
        """
        count = 0 #计算0的个数
        i = 0
        while(i < len(nums)-count): #保证操作到已经被搬移过的0为止
            if(nums[i] == 0):
                count = count + 1
                nums[i:len(nums)-1] = nums[i+1:] #这步和下面这步将0搬移到list最后
                nums[len(nums)-1] = 0
                i = i - 1 #零被搬移到最后,这个位置已经被后一个数替代,需要重新检查这个数,所以i=i-1
            i = i + 1 

两数之和

给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。

你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

我的解答:

方法1:两个循环嵌套(时间复杂度O(n^2))

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        i = 0
        j = 0
        while(i < len(nums)-1):
            j = i + 1
            while(j < len(nums)):
                if(nums[i] + nums[j] == target):
                    return [i,j]
                j = j + 1
            i = i + 1

方法2:一个循环,直接在里面查询target-nums[x]是否存在于nums列表中

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        for x in range(len(nums)):
            j = target - nums[x]
            if j in nums:
                y = nums.index(j)
                if(x != y):
                    return x,y

方法3:哈希表(这里是字典!!)

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        # 哈希表(这里是字典!!)
        temp = {}
        for i in range(len(nums)):
            x = target - nums[i]
            #字典temp中存在nums[i]时
            if nums[i] in temp:
                return temp[nums[i]],i
            #字典temp中不存在nums[i],保存 结果:索引 到字典
            else:
                temp[x] = i

有效的数独

判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

上图是一个部分填充的有效的数独。

数独部分空格内已填入了数字,空白格用 '.' 表示。

示例 1:

输入:
[
  ["5","3",".",".","7",".",".",".","."],
  ["6",".",".","1","9","5",".",".","."],
  [".","9","8",".",".",".",".","6","."],
  ["8",".",".",".","6",".",".",".","3"],
  ["4",".",".","8",".","3",".",".","1"],
  ["7",".",".",".","2",".",".",".","6"],
  [".","6",".",".",".",".","2","8","."],
  [".",".",".","4","1","9",".",".","5"],
  [".",".",".",".","8",".",".","7","9"]
]
输出: true

示例 2:

输入:
[
  ["8","3",".",".","7",".",".",".","."],
  ["6",".",".","1","9","5",".",".","."],
  [".","9","8",".",".",".",".","6","."],
  ["8",".",".",".","6",".",".",".","3"],
  ["4",".",".","8",".","3",".",".","1"],
  ["7",".",".",".","2",".",".",".","6"],
  [".","6",".",".",".",".","2","8","."],
  [".",".",".","4","1","9",".",".","5"],
  [".",".",".",".","8",".",".","7","9"]
]
输出: false
解释: 除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。
     但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。

说明:

  • 一个有效的数独(部分已被填充)不一定是可解的。
  • 只需要根据以上规则,验证已经填入的数字是否有效即可。
  • 给定数独序列只包含数字 1-9 和字符 '.' 。
  • 给定数独永远是 9x9 形式的。

我的解答:

class Solution:
    def isValidSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: bool
        """
        
        row = [{},{},{},{},{},{},{},{},{}]
        col = [{},{},{},{},{},{},{},{},{}]
        block = [{},{},{},{},{},{},{},{},{}]
        
        for i in range(9):
            for j in range(9):
                num = 3*(i//3)+(j//3) #块 #" / "就表示 浮点数除法,返回浮点结果;" // "表示整数除法
                if(board[i][j] != '.'):
                    if board[i][j] not in row[i] and board[i][j] not in col[j] and board[i][j] not in block[num]:
                        row[i][board[i][j]] = 1
                        col[j][board[i][j]] = 1
                        block[num][board[i][j]] = 1
                    else:
                        return False
        return True

旋转图像

给定一个 × n 的二维矩阵表示一个图像。

将图像顺时针旋转 90 度。

说明:

你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。

示例 1:

给定 matrix = 
[
  [1,2,3],
  [4,5,6],
  [7,8,9]
],

原地旋转输入矩阵,使其变为:
[
  [7,4,1],
  [8,5,2],
  [9,6,3]
]

示例 2:

给定 matrix =
[
  [ 5, 1, 9,11],
  [ 2, 4, 8,10],
  [13, 3, 6, 7],
  [15,14,12,16]
], 

原地旋转输入矩阵,使其变为:
[
  [15,13, 2, 5],
  [14, 3, 4, 1],
  [12, 6, 8, 9],
  [16, 7,10,11]
]

我的解答:

旋转90度是个套路:转置后反转每列

class Solution:
    def rotate(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: void Do not return anything, modify matrix in-place instead.
        """       
        n = len(matrix) #求取二维数组的长度(列数)
        
        #转置操作
        for i in range(n):
            for j in range(i+1,n): #注意这里只需要上三角的数进行转置就可以!
                temp = matrix[i][j]
                matrix[i][j] = matrix[j][i]
                matrix[j][i] = temp
        #反转列操作
        for k in range(n):
            matrix[k] = matrix[k][::-1]


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值