二刷 leetcode(1)

26删除排序数组中的重复项

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

不要使用额外的数组空间,你必须在原地修改输入数组并在使用 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]);
}

思路是:有几种方式做这个题目,一开始我就想着怎么用python的特性,也就是前两种方法,但是都没有通过了。后面两种方法通过了。

代码:

class Solution:
    def removeDuplicates(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        #### the first method
        # nums = set(nums)
        # return len(list(nums))
       
        #### the second
        # res = []
        # for i in nums:
        #     if i not in res:
        #         res.append(i)
        # print(res)
        # return len(res)
        
        #### the third method
#         i = 0
#         while i < len(nums) -1:
#             if nums[i] == nums[i+1]:
#                 nums.remove(nums[i])
#             else:
#                  i = i +1
#         return len(nums)
        
        #### the last one 
        size = len(nums)
        if size == 0:
            return 0
        j = 0
        for i in range(1, size):
            if nums[j] != nums[i]:
                nums[j+1] = nums[i]
                j += 1
        return j+1
    

122买卖股票的最佳时机 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
        """
        #### the first method
        # sum = 0
        # for i in range(0, len(prices) -1):
        #     if prices[i] < prices[i+1]:
        #         sum += prices[i+1] - prices[i]
        # return sum
        
        #### the second method
        sum = 0
        for i in range(1, len(prices)):
            # if prices[i] - prices[i-1] > 0:
            #     sum +=  prices[i] - prices[i-1]
            sum += max((prices[i] - prices[i-1]), 0)
        return sum
    

121买卖股票的最佳时机


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

如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。

注意你不能在买入股票前卖出股票。

示例 1:

输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
     注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。

示例 2:

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

代码如下:

class Solution:
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        #### 第一种方法超时了,不过自己设置的测试小案例是通过的,只是方法需要改进
        # max_profit = 0
        # for i in range(0, len(prices)):
        #     for j in range(i, len(prices)):
        #         max_profit = max(prices[j] - prices[i], max_profit)
        # return max_profit

        #### the second method
        #### 思想就是找到数组中最大数以及最小数,同时也要考虑数组元素的顺序,
        #### 特殊情况是给定的数组元素是逆序的,那么返回值为0
        # if len(prices) < 2:
        #     return 0
        # min_price = prices[0]
        # max_profit = 0
        # for cur_price in prices:
        #     min_price = min(cur_price, min_price)
        #     max_profit = max(max_profit, (cur_price - min_price))
        # return max_profit
    
        ####最优的时间效率是下面这个,其实上面的做法很类似
        if len(prices) < 2:
            return 0
        min_price = prices[0]
        max_profit = 0
        for price in prices:
            if price < min_price:
                min_price = price
            if price - min_price > max_profit:
                max_profit = price - min_price
        return max_profit

189旋转数组

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

示例 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) 的原地算法。

代码中包含思路:

class Solution4:
    def rotate(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: void Do not return anything, modify nums in-place instead.
        """
        #### 第一种借助额外空间,但是不符合要求,不能满足题目条件
        # length = len(nums)
        # k = k % length
        # array = [1] * length
        # for i in range(length):
        #     if i + k < length:
        #         array[i+k] = nums[i]
        #     else:
        #         array[i+k-length] = nums[i]
        # return array

        #### 第二种方式,就是借用数组的特性了
        # length = len(nums)
        # k = k % length
        # nums[:] = nums[-k:] + nums[:-k]
        # return nums

        #### 第三种方式, 借助一个临时存放前k个元素的数组
        length = len(nums)
        k = k % length
        temp = nums[(length - k):]
        for i in range(length-k-1, -1, -1):
            nums[(i+k) % length] = nums[i]
        nums[:k] = temp

s = Solution4()
print(s.rotate([1,2,3,4,5,6,7], 3))


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值