力扣 数组 第一轮1

1. 两数之和

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

你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。

你可以按任意顺序返回答案。

第一题就好难,我们要考虑重复的元素的情况,所以在遍历的时候将Visited的存入一个字典中。

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 []

26. 删除有序数组中的重复项

1.先是想着一个一个看然后删掉

2.然后想着构建新列表再复制回去

看官方解答,又是双指针,已经学过了,又忘了。

class Solution:

    def removeDuplicates(self, nums: List[int]) -> int:

        i,j=0,1

        while j<len(nums):

            if nums[j]!=nums[i]:

                i+=1

                nums[i]=nums[j]      

            j+=1

        return i+1

还有一个龟兔赛跑的fast slow算法,这算法真是太猎奇了

class Solution:

    def removeDuplicates(self, nums: List[int]) -> int:

        if not nums:

            return 0

       

        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

88. 合并两个有序数组

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。

请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

精髓:利用nums1的空闲位置从后向前遍历

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.

        """

        i=m-1

        j=n-1

        k=m+n-1

        while i>=0 or j>=0:

            if i>=0 and j>=0:

                if nums1[i]>nums2[j]:

                    nums1[k]=nums1[i]

                    i-=1

                else:

                    nums1[k]=nums2[j]

                    j-=1

            else:

                if i>=0:

                    nums1[k]=nums1[i]

                    i-=1

                else:

                    nums1[k]=nums2[j]

                    j-=1

            k-=1      

官方其中一个解法,笑死

class Solution:

    def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:

        nums1[m:]=nums2

        nums1.sort()

还是有进步的,最起码知道用双指针

121. 买卖股票的最佳时机

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

我使用双层循环会超出时间限制,思考怎么一次遍历

记录历史最低点,然后在每一天考虑这么一个问题:如果我是在历史最低点买进的,那么我今天卖出能赚多少钱?

class Solution:

    def maxProfit(self, prices: List[int]) -> int:

        minprice = int(1e9)

        maxprofit = 0

        for price in prices:

            maxprofit=max(maxprofit,price-minprice)

            minprice = min(minprice,price)

        return maxprofit

136. 只出现一次的数字

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

你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。

思考了很多O(n) 的空间的方法,如何只使用常数额外空间?

使用位运算,异或运算

异或运算的性质:

所以全部异或得到的值就是结果

class Solution:

    def singleNumber(self, nums: List[int]) -> int:

        return reduce(lambda x,y:x^y,nums)

303. 区域和检索 - 数组不可变

第一次碰到自己写类的题,写不了一点,学习一下。

class NumArray:

    def __init__(self, nums: List[int]):

        self.sums = [0]

        for num in nums:

            self.nums.append(self.nums[-1] + num)

    def sumRange(self, i: int, j: int) -> int:

        return self.sums[j + 1] - self.sums[i]

448. 找到所有数组中消失的数字

进阶:你能在不使用额外空间且时间复杂度为 O(n) 的情况下解决这个问题吗? 你可以假定返回的数组不算在额外空间内。

不产生额外空间该怎么做?

·原来enumerate的是一个迭代对象,只是引用

class Solution:

    def findDisappearedNumbers(self, nums: List[int]) -> List[int]:

        n = len(nums)

        for num in nums:

            x=(num-1)%n

            nums[x]+=n

        return [i+1 for i,value in enumerate(nums) if value<=n]

在分析算法的空间复杂度时,我们通常只关心“除了输入和输出之外”算法本身需要的额外存储空间。返回值(output)是题目要求的“结果”,它不被视为算法的“额外开销”。

用自己来存储,给位置[i]+n,表示数组包含i+1

496. 下一个更大元素 I

我写的内存消耗很大,其实不用搞这么多列表来存储对应索引,我们直接做字典就好。

class Solution:

    def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:

        res=[]

        st=[nums2[-1]]

        index=[]

        larger=[-1]

        dct={num:i for i,num in enumerate(nums2)}

        for num in nums1:

            if num in dct:

                index.append(dct[num])

        for num in reversed(nums2[:-1]):

            if num<st[-1]:

                larger.append(st[-1])

            else:

                while st and num>=st[-1]:

                    st.pop()

                if st:

                    larger.append(st[-1])

                else:

                    larger.append(-1)

            st.append(num)

        larger.reverse()

        for i in index:

            res.append(larger[i])

        return res

官方 方法二:单调栈 + 哈希表

class Solution:

    def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:

        res={}

        stack=[]

        nums2.reverse()

        for num in nums2:

            while stack and num>=stack[-1]:

                stack.pop()

            res[num]=stack[-1] if stack else -1

            stack.append(num)

        return [res[num] for num in nums1]

506. 相对名次

class Solution:

    def findRelativeRanks(self, score: List[int]) -> List[str]:

        desc = ("Gold Medal", "Silver Medal", "Bronze Medal")

        #排序

        ans =['']*len(score)

        arr = sorted(enumerate(score), key=lambda x: x[1],reverse=True)

        for i,(index,_) in enumerate(arr):

            ans[index] = desc[i] if i<3 else str(i+1)

        return ans

要看我们需要的信息是什么,然后储存下来。

数组先这样吧,下篇开始链表

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值