数组 leetcode

主要方法:二分查找 | 滑动窗口 (滑动窗口不会)

就写了几个数组的题,感觉数组没必要单独开一篇文章,因为数组这一类包含了二分查找,回溯,贪心甚至二叉树。

1. 两数之和 

class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        dic = {}
        for i in range(len(nums)):
            another_num = target - nums[i]
            if another_num in dic:
                return [dic[another_num], i]
            else:
                dic[nums[i]] = i

 4. 寻找两个正序数组的中位数 (困难)

class Solution(object):
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        nums1.extend(nums2)
        nums1.sort()
 
        # 判断合并后列表的长度是奇数还是偶数,然后根据中位数计算规则计算出中位数
        length = len(nums1)
        if length % 2 == 0:
            return (nums1[int(length/2 - 1)] + nums1[int(length/2)]) / 2.0
        else:
            return nums1[int((length+1)/2 - 1)]

 11. 盛最多水的容器 (中等)

class Solution(object):
    def maxArea(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        left = 0
        right = len(height)-1
        if not height or len(height) == 1 :
            return 0
        if height[left] < height[right]:
            res = (right-left)*height[left]
        else:
            res = (right-left)*height[right]
        
        while left < right:
            if height[left] < height[right]:
                if res > (right-left)*height[left]:
                    res = res
                else:
                    res = (right-left)*height[left]
                left += 1
            else :
                if res > (right-left)*height[right]:
                    res = res
                else:
                    res = (right-left)*height[right]
                right -=1
        return res

15. 三数之和 (中等)

class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        nums = sorted(nums)
        res = []
        for i in range(len(nums)):
            if nums[i] > 0:
                break
            if i > 0 and nums[i] == nums[i-1]:
                continue
            left = i+1
            right = len(nums)-1
            while left < right:
                if nums[i] + nums[left] + nums[right] > 0:
                    right -=1
                elif nums[i] + nums[left] + nums[right] < 0:
                    left += 1
                else:
                    res.append([nums[i], nums[left], nums[right]])
                    while left < right and nums[left] == nums[left+1]:
                        left += 1
                    while left < right and nums[right] == nums[right-1]:
                        right -= 1
                    left += 1
                    right -= 1
        return res

16. 最接近的三数之和 (中等 自己写的)

class Solution(object):
    def threeSumClosest(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        nums.sort()
        mins = 2**32
        res = 0
        for i in range(len(nums)):
            left = i+1
            right = len(nums) - 1
            
            while left < right:
                if nums[i] + nums[left] + nums[right] > target:
                    if nums[i] + nums[left] + nums[right] - target < mins:
                        res = nums[i] + nums[left] + nums[right]
                        mins = nums[i] + nums[left] + nums[right] - target
                    right -= 1
                elif nums[i] + nums[left] + nums[right] < target:
                    if target - (nums[i] + nums[left] + nums[right]) < mins:
                        res = nums[i] + nums[left] + nums[right]
                        mins = target - (nums[i] + nums[left] + nums[right])
                    left += 1
                else:
                    return target
        return res

18. 四数之和

class Solution(object):
    def fourSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        nums = sorted(nums)
        res = []
        for i in range(len(nums)):
            if i > 0 and nums[i] == nums[i-1]:
                continue
            for j in range(i+1, len(nums)):
                if j > i+ 1 and nums[j] == nums[j-1]:
                    continue
                left = j+1
                right = len(nums)-1
                while left < right:
                    if nums[left] + nums[right] +nums[i]+nums[j]>target:
                        right -= 1
                    elif nums[left] + nums[right] +nums[i]+nums[j]<target:
                        left += 1
                    else:
                        res.append([nums[i], nums[j], nums[left], nums[right]])
                        while left < right and nums[left] == nums[left+1]:
                            left += 1
                        while left < right and nums[right] == nums[right-1]:
                            right -= 1
                        left += 1
                        right -= 1
        return res

26. 删除有序数组中的重复项 (简单)

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

 27. 移除元素 (简单)

class Solution(object):
    def removeElement(self, nums, val):
        """
        :type nums: List[int]
        :type val: int
        :rtype: int
        """
        i = 0
        while i < len(nums):
            if nums[i] == val:
                del nums[i]
            else:
                i+=1
        return len(nums)

31. 下一个排列 (不会)

扫描二维码关注公众号,回复: 14857808 查看本文章

力扣

33. 搜索旋转排序数组

class Solution(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        n = len(nums)
        left, right = 0, n-1
        while left<right:
            mid = (left+right)//2
            if nums[mid] == target: 
                return mid
            if nums[left] <= nums[mid]: #说明mid在旋转的前半部分
                if nums[left] <= target <= nums[mid]:
                    right = mid
                else:
                    left = mid + 1
            else: #left 大于 mid 说明mid已经在旋转的后半部分
                if nums[mid] <= target <= nums[right]: #如果target在旋转的后半部分的mid和right之间
                    left = mid + 1
                else:
                    right = mid

        if nums and nums[left]==target:
            return left 
        else:
            return -1

 34. 在排序数组中查找元素的第一个和最后一个位置 (中等 自己写的 就是注意细节 要改来改去)

class Solution(object):
    def searchRange(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        start = -1
        end = -1
        left = 0
        right = len(nums) - 1
        while left <= right:
            mid = (left + right) // 2
            if nums[mid] == target:
                start = mid
                end = mid
                break
            elif nums[mid] > target:
                right = mid-1
            else:
                left = mid+1
        if start != -1:
            while start > 0 and nums[start-1] == target:
                start -= 1
            while end < len(nums)-1 and nums[end+1] == target:
                end += 1

        return [start, end] 

35. 搜索插入位置 (简单)

class Solution(object):
    def searchInsert(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        left = 0
        right = len(nums) - 1
        while left <= right:
            mid = (left+right) // 2
            if nums[mid] == target:
                return mid
            elif nums[mid] > target:
                right = mid -1
            else:
                left = mid + 1
        return left

36. 有效的数独 (不会 再看)

https://segmentfault.com/a/1190000023277543 

class Solution(object):
    def isValidSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: bool
        """
        # 定义哈希表存储数字出现在每行,每列,每个 3x3 的宫格的次数
        # 题目中说明,给定的数独一定是 9x9 的
        rows = [{} for _ in range(9)]
        cols = [{} for _ in range(9)]
        boxes = [{} for _ in range(9)]

        for i in range(9):
            for j in range(9):
                # 题目中要验证是已经填入的数字,如果出现 '.' 表示留空,不作处理
                if board[i][j] != '.':
                    # 取出数字,存入哈希表中(需要转换,给定的二维数组数字是字符串格式)
                    num = int(board[i][j])

                    rows[i][num] = rows[i].get(num, 0) + 1
                    cols[j][num] = cols[j].get(num, 0) + 1
                    # 代入枚举 3x3 宫格的公式
                    boxes[(i // 3) * 3 + j // 3][num] = boxes[(i // 3) * 3 + j // 3].get(num, 0) + 1

                    # 行,列,3x3 宫格,任意一个如果出现数字重复,则返回 False
                    if rows[i][num] > 1 or cols[j][num] > 1 or boxes[(i // 3) * 3 + j // 3][num] > 1:
                        return False
        return True

37. 解数独 (困难 不会)

41. 缺失的第一个正数 (困难题,看到困难我就怕了,确实是我想不起来的巧妙的解法)

 https://segmentfault.com/a/1190000023030256

class Solution(object):
    def firstMissingPositive(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        length = len(nums)

        for i in range(length):
            # 这里判断元素是否落在 [1, n],判断是否落在正确的位置
            # 注意:防止进入死循环,当元素刚好落在正确位置,直接跳过,判断下个元素
            while 1 <= nums[i] <= length and nums[i] != nums[nums[i] - 1]:
                # 交换
                nums[nums[i] - 1], nums[i] = nums[i], nums[nums[i] - 1]
        
        # 将数组的元素恢复到正确的位置后,
        # 再次遍历,当某个元素不在正确的位置时,就是要找的第一个缺失的正数,直接返回
        for i in range(length):
            if nums[i] != i + 1:
                return i + 1
        # 如果元素都在正确位置,那么缺失的就是 n+1(length+1)
        return length + 1

42. 接雨水 (困难) (困难在思路吧)

class Solution(object):
    def trap(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        max_h = 0
        max_h_index = 0
        res = 0
        #找到最高的柱子以及位置
        for i in range(len(height)): 
            if height[i] >= max_h:
                max_h = height[i]
                max_h_index = i 
        #从最高位置向左查找
        tmp = height[0]
        for i in range(max_h_index):
            if height[i] <= tmp:
                res += (tmp - height[i])
            else:
                tmp = height[i]
        #从最高位置向右查找
        tmp = height[-1]
        for j in reversed(range(max_h_index+1, len(height))):
            if height[j] <= tmp:
                res += (tmp - height[j])
            else:
                tmp = height[j]

        return res

45. 跳跃游戏 II (不懂)

class Solution(object):
    def jump(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums) == 1: 
            return 0
        ans = 0
        curDistance = 0
        nextDistance = 0
        for i in range(len(nums)):
            nextDistance = max(i + nums[i], nextDistance)
            if i == curDistance: 
                if curDistance != len(nums) - 1:
                    ans += 1
                    curDistance = nextDistance
                    if nextDistance >= len(nums) - 1:
                        break
        return ans

猜你喜欢

转载自blog.csdn.net/weixin_39915444/article/details/121650440