leetcode初级算法——数组

(题目源自leetcode,方法都是自(cai)己(ji)写的,可能比较符合菜鸡们的思路)

1.删除排序数组中的重复项

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

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

示例 1:

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

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

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

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        a=0
        b=1
        amount = 1
        if len(nums)==0:
            return 0
        while b<len(nums):
            if nums[a]==nums[b]:
                b=b+1
            else:
                a=a+1
                nums[a]=nums[b]
                b=b+1
                amount += 1
        return amount

使用双指针,a记录重复的需要更改的位置。b后移,遇到不同的元素,则对a位置的重复元素进行覆盖。

2.买卖股票的最佳时机 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 。

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        profit = 0
        for i in range(1,len(prices)):
            profit += max(0,prices[i]-prices[i-1])
        return profit

每一天比前一天高的价格均为利润

3.旋转数组

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

示例 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]

class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        k = k%len(nums)
        while k > 0:
            nums.insert(0,nums.pop())
            k = k - 1

数组每pop一个,就insert到前面。

4.存在重复元素

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

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

示例 1:

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

class Solution:
    def containsDuplicate(self, nums: List[int]) -> bool:
        return len(nums)!=len(set(nums))

转set去掉重复元素,与原列表长度不想等,说明重复了

5.只出现一次的数字

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

说明:

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

示例 1:

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

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        nums.sort()
        for i in range(len(nums)//2+1):
            if 2*i==len(nums)-1:
                return nums[2*i]
            if nums[2*i]!=nums[2*i+1]:
                return nums[2*i]

排序后,第一个奇数位与后位不相同的,即为只出现一次的数字。

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
		return sum(set(nums))*2-sum(nums)

一行代码,转set的和双倍减去原列表的和

6.两个数组的交集 II

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

示例 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]

class Solution:
    def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
        small = nums1 if len(nums1)<len(nums2) else nums2
        big = nums2 if len(nums1)<len(nums2) else nums1
        out = []
        for i in range(len(small)):
            if small[i] in big:
                out.append(small[i])
                big.remove(small[i])
        return out

先找出较小的列表small,然后拿small的元素去big比较,重复则在输出里加入该元素,并把big中的删除,避免重复。

7.加一

给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。

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

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

示例 1:

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

class Solution:
    def plusOne(self, digits: List[int]) -> List[int]:
        digits[-1] += 1
        for i in range(len(digits)-1,0,-1):
            if digits[i]==10:
                digits[i]=0
                digits[i-1]+=1
        
        if digits[0]==10:
            digits[0]=0
            digits.insert(0,1)
        
        return digits

挨位判断加一是否为10,10则转0进位
最后看第一位是不是10,是的话,补位。

8.移动零

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

示例:

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

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        num = 0
        while num in nums:
            nums.remove(0)
            num = num + 1
        while num > 0:
            nums.append(0)
            num = num-1
        return nums

先检查0,有的话就remove并记录次数,最后在列表末尾补上。
也可以双指针,后面不为0的和前面为0的互换。

9.两数之和

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

示例:

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

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

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        #nums.sort()
        for num in nums:
            if (target-num) in nums and (idx1:=nums.index(num))!= (idx2:=nums.index(target-num)):
                return [idx1,idx2]

遍历列表中的元素num,如果num和target-num都在列表中,且两者的index不同,则返回。

10.有效的数独

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

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

在这里插入图片描述

class Solution:
    def isValidSudoku(self, board: List[List[str]]) -> bool:
        rows, columns, boxes = defaultdict(set), defaultdict(set), defaultdict(set)
        for row in range(9):
            for col in range(9):
                if board[row][col]=='.':
                    continue
                if board[row][col] in rows[row]:
                    return False
                if board[row][col] in columns[col]:
                    return False
                if board[row][col] in boxes[(row//3)*3+col//3]:
                    return False
                rows[row].add(board[row][col])
                columns[col].add(board[row][col])
                boxes[(row//3)*3+col//3].add(board[row][col])
        return True

defaultdict(set)???待补充
遍历元素,检查是否符合条件,不符合条件则返回False

11.旋转图像

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

将图像顺时针旋转 90 度。

说明:

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

示例 1:

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

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

class Solution:
    def rotate(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        n = len(matrix[0])
        col = defaultdict(list)
        for i in range(n):
            for j in range(n):
                col[j].append(matrix[i][j])
        for r in range(n):
            for c in range(n):
                matrix[r][n-c-1]=col[r][c]

两次遍历,第一次复制列,第二次遍历,根据规律在原列表上赋值。

class Solution:
    def rotate(self, matrix: List[List[int]]) -> None:
        matrix[:] = zip(*reversed(matrix))

大佬一行解法,reversed???待补充

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值