数组力扣(持续更新)

两数之和(7.21)

在这里插入图片描述
执行用时:3148ms
自己写的代码:

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        n = len(nums)
        for i in range(n):
            for j in range(i+1,n):
                if nums[i] + nums[j] == target:
                    return [i,j]

官方代码:

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        hashtable = dict()
        for i, num in enumerate(nums):
            if target - num in hashtable:
                return [hashtable[target - num], i]
            hashtable[nums[i]] = i
        return []

盛最多水的容器(7.22 难度中等)

在这里插入图片描述
面积取决于短板。①因此即使长板往内移动时遇到更长的板,矩形的面积也不会改变;遇到更短的板时,面积会变小。②因此想要面积变大,只能让短板往内移动(因为移动方向固定了),当然也有可能让面积变得更小,但只有这样才存在让面积变大的可能性

class Solution:
    def maxArea(self, height: List[int]) -> int:
        l, r = 0, len(height) - 1
        ans = 0
        
        while l < r:
            area = min(height[l], height[r]) * (r - l)
            ans = max(ans, area)
            if height[l] <= height[r]:
                l += 1
            else:
                r -= 1
      
        return ans

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

在这里插入图片描述
在这里插入图片描述
思考:
还是利用双指针

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        n = len(nums)
        fast = slow = 1
        while fast < n:
            if nums[fast] != nums[fast - 1]:
                nums[slow] = nums[fast]
                slow += 1
            fast += 1
        
        return slow

搜索插入位置(7.23)

在这里插入图片描述
这道题比较简单
自己写的代码:

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        n = len(nums)
        minq = min(nums)
        maxq = max(nums)
        if target < minq:
            return 0
        if target > maxq:
            return n
        for i in range(n):
            if nums[i] == target:
                return i
            if i < n-1 and nums[i] < target and target < nums[i+1]:
                return i+1

官方代码:二分法
在这里插入图片描述

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

移除元素(7.24 简单)

在这里插入图片描述
在这里插入图片描述
思考:
这道数组题目也是利用双指针

自己

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        n = len(nums)
        j = 0
        for i in range(n):
            if nums[i] != val:
                nums[j] = nums[i]
                j = j + 1
        return j

加一(7.24 简单)

在这里插入图片描述
思考1:
考虑到最后一位是9的情况了,但是没有考虑到列表最后几位都是9的情况。

思考2:
当末尾几位都是9的时候,只需要找出第一位不为9的数字,将其加1,后面的数字全部变成0即可。
当全部都是9的时候,列表第一个数字为1,其他均为0。
在这里插入图片描述
不能用转换成数字然后加了1之后再转换成数组的想法,会溢出的。

官方代码:

class Solution:
    def plusOne(self, digits: List[int]) -> List[int]:
        n = len(digits)
        for i in range(n - 1, -1, -1):
            if digits[i] != 9:
                digits[i] += 1
                for j in range(i + 1, n):
                    digits[j] = 0
                return digits

        # digits 中所有的元素均为 9
        return [1] + [0] * n

合并两个有序数组(7.25)

在这里插入图片描述
思考:
官方算法
在这里插入图片描述

class Solution:
    def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
        """
        Do not return anything, modify nums1 in-place instead.
        """
        sorted = []
        p1, p2 = 0, 0
        while p1 < m or p2 < n:
            if p1 == m:
                sorted.append(nums2[p2])
                p2 += 1
            elif p2 == n:
                sorted.append(nums1[p1])
                p1 += 1
            elif nums1[p1] < nums2[p2]:
                sorted.append(nums1[p1])
                p1 += 1
            else:
                sorted.append(nums2[p2])
                p2 += 1
        nums1[:] = sorted

存在重复元素(7.25)

在这里插入图片描述
思考1:
比较去重之后和去重之前的两个列表长度

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

思考2:
先排序,后判断相邻位置的元素是否相等。

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

存在重复数据2(7.25)

在这里插入图片描述
思考:
前面排序的方法就用不了了。
在这里插入图片描述

class Solution:
    def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:
        s = set()
        for i, num in enumerate(nums):
            if i > k:
                s.remove(nums[i - k - 1])
            if num in s:
                return True
            s.add(num)
        return False

只出现一次的数字(7.26)

在这里插入图片描述
思考:
看到这道题,第一反应想起来的是字典。

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
       dict = {}
       for key in nums:
           dict[key] = dict.get(key, 0) + 1
       for key in nums:
           if dict[key] == 1:
               return key

官方思路:
异或运算?!
任何数与0异或为任何数;
一个数与它本身进行异或运算等于 0

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        sum = 0
        for i in nums:
            sum^=i
        return sum

多数元素(7.26)

在这里插入图片描述
自己用的方法:

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        n = len(nums)
        dic = dict()
        for key in nums:
            dic[key] = dic.get(key,0) + 1
        for key in nums:
            if dic[key] > n/2:
                return key

官方:(摩尔投票法)

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        count = 0
        candidate = None

        for num in nums:
            if count == 0:
                candidate = num
            count += (1 if num == candidate else -1)

        return candidate

汇总区间(7.27d)

在这里插入图片描述

class Solution {
public:
    vector<string> summaryRanges(vector<int>& nums) {
        vector<string> ret;
        int i = 0;
        int n = nums.size();
        while (i < n) {
            int low = i;
            i++;
            while (i < n && nums[i] == nums[i - 1] + 1) {
                i++;
            }
            int high = i - 1;
            string temp = to_string(nums[low]);
            if (low < high) {
                temp.append("->");
                temp.append(to_string(nums[high]));
            }
            ret.push_back(move(temp));
        }
        return ret;
    }
};

丢失的数字(7.28)

在这里插入图片描述
看到题目就想起来的做法:(但是执行用时久)

class Solution:
    def missingNumber(self, nums: List[int]) -> int:
        n = len(nums)
        for i in range(n+1):
            if i not in nums:
                return i

官方方法一(排序):

class Solution:
    def missingNumber(self, nums: List[int]) -> int:
        n = len(nums)
        nums.sort()
        for i in range(n):
            if nums[i] != i:
                print(i)
                return i
        return n

官方方法二(位运算):

class Solution:
    def missingNumber(self, nums: List[int]) -> int:
        xor = 0
        for i, num in enumerate(nums):
            xor ^= i ^ num
        return xor ^ len(nums)

移动零(7.29)

在这里插入图片描述
官方(双指针):

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        n = len(nums)
        left = right = 0
        while right < n:
            if nums[right] != 0:
                nums[left], nums[right] = nums[right], nums[left]
                left += 1
            right += 1

但是官方的答案我不是很懂,后面去看了B站一个up的讲解,说跟去重复项元素的思路是一样的,回过头一看,果然,差不多。
自己的代码:

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        n = len(nums)
        fast = slow = 0
        while fast < n:
            if nums[fast] == 0:
                fast += 1
            else:
                nums[slow] = nums[fast]
                fast += 1
                slow += 1
        for i in range(slow,n):
            nums[i] = 0

区域和检索 - 数组不可变(7.29)

在这里插入图片描述

class NumArray {
    vector<int> sums;
public:
    NumArray(vector<int>& nums) {
        int n = nums.size();
        sums.resize(n+1);
        for(int i = 0; i < n; i++){
            sums[i+1] = sums[i] + nums[i];
        }
    }
    
    int sumRange(int i, int j) {
        return sums[j+1] - sums[i];
    }
};

/**
 * Your NumArray object will be instantiated and called as such:
 * NumArray* obj = new NumArray(nums);
 * int param_1 = obj->sumRange(left,right);
 */

两个数组的交集(7.30)

在这里插入图片描述

代码(自己):

class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        nums3 = []
        for i in list(set(nums1)):
            if i in nums2:
                nums3.append(i)
        return nums3

官方代码(两个集合):

class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        set1 = set(nums1)
        set2 = set(nums2)
        return self.set_intersection(set1, set2)

    def set_intersection(self, set1, set2):
        if len(set1) > len(set2):
            return self.set_intersection(set2, set1)
        return [x for x in set1 if x in set2]

官方代码(排序+双指针):

class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        nums1.sort()
        nums2.sort()
        length1, length2 = len(nums1), len(nums2)
        intersection = list()
        index1 = index2 = 0
        
        while index1 < length1 and index2 < length2:
            num1 = nums1[index1]
            num2 = nums2[index2]
            if num1 == num2:
                # 保证加入元素的唯一性
                if not intersection or num1 != intersection[-1]:
                    intersection.append(num1)
                index1 += 1
                index2 += 1
            elif num1 < num2:
                index1 += 1
            else:
                index2 += 1
                
        return intersection

第三大的数(简单 8.8)

在这里插入图片描述
代码:

class Solution:
    def thirdMax(self, nums: List[int]) -> int:

        nums = list(set(nums))
        n = len(nums)
        if n < 3:
            return max(nums)
        nums.sort()
        return nums[-3]

找到所有数组中消失的数字(8.8)

在这里插入图片描述

class Solution:
    def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
        n = len(nums)
        nums2 = [i for i in range(1,n+1)]
        nums3 = set(nums2) - set(nums)
        return list(nums3)

官方代码:

class Solution:
    def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
        n = len(nums)
        for num in nums:
            x = (num - 1) % n
            nums[x] += n
        
        ret = [i + 1 for i, num in enumerate(nums) if num <= n]
        return ret

分发饼干(8.16)

在这里插入图片描述
官方代码:

class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        g.sort()
        s.sort()
        n, m = len(g), len(s)
        i = j = count = 0

        while i < n and j < m:
            while j < m and g[i] > s[j]:
                j += 1
            if j < m:
                count += 1
            i += 1
            j += 1
        
        return count

三数之和(8.16)

在这里插入图片描述
官方代码:

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        n = len(nums)
        nums.sort()
        ans = list()
        
        # 枚举 a
        for first in range(n):
            # 需要和上一次枚举的数不相同
            if first > 0 and nums[first] == nums[first - 1]:
                continue
            # c 对应的指针初始指向数组的最右端
            third = n - 1
            target = -nums[first]
            # 枚举 b
            for second in range(first + 1, n):
                # 需要和上一次枚举的数不相同
                if second > first + 1 and nums[second] == nums[second - 1]:
                    continue
                # 需要保证 b 的指针在 c 的指针的左侧
                while second < third and nums[second] + nums[third] > target:
                    third -= 1
                # 如果指针重合,随着 b 后续的增加
                # 就不会有满足 a+b+c=0 并且 b<c 的 c 了,可以退出循环
                if second == third:
                    break
                if nums[second] + nums[third] == target:
                    ans.append([nums[first], nums[second], nums[third]])
        
        return ans

最接近的三数之和(8.17)

在这里插入图片描述
代码:

class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        nums.sort()
        n = len(nums)
        best = 10**7
        
        # 根据差值的绝对值来更新答案
        def update(cur):
            nonlocal best
            if abs(cur - target) < abs(best - target):
                best = cur
        
        # 枚举 a
        for i in range(n):
            # 保证和上一次枚举的元素不相等
            if i > 0 and nums[i] == nums[i - 1]:
                continue
            # 使用双指针枚举 b 和 c
            j, k = i + 1, n - 1
            while j < k:
                s = nums[i] + nums[j] + nums[k]
                # 如果和为 target 直接返回答案
                if s == target:
                    return target
                update(s)
                if s > target:
                    # 如果和大于 target,移动 c 对应的指针
                    k0 = k - 1
                    # 移动到下一个不相等的元素
                    while j < k0 and nums[k0] == nums[k]:
                        k0 -= 1
                    k = k0
                else:
                    # 如果和小于 target,移动 b 对应的指针
                    j0 = j + 1
                    # 移动到下一个不相等的元素
                    while j0 < k and nums[j0] == nums[j]:
                        j0 += 1
                    j = j0

        return best

四数之和(8.19)

在这里插入图片描述


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值