leecode刷题初级-数组python版本

Posted AnzyAn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leecode刷题初级-数组python版本相关的知识,希望对你有一定的参考价值。

删除排除数组中的重复项:

给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。

由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。

将最终结果插入 nums 的前 k 个位置后返回 k 。

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

我的回答:

类似于双指针,利用i,j分别指向待交换的位置以及向后比较的位置,当i,j位置两个数相等时,j指针向后移;当j指针位置的数大于i指针位置的数时,与i+1指针的位置进行交换,此时i=i+1,j=j+1,持续比较,直到j指向末端。当然如果整个数组中没有重复数字时,可以判定j-i>1再进行数值交换操作(亲测内存增长,耗时不变)。

class Solution(object):
    def removeDuplicates(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums) < 1:
            return len(nums), nums
        i, j = 0, 1
        while (i < j) and (j<len(nums)):
            if nums[i] == nums[j]:
                j+=1
            elif nums[i] < nums[j]:
                # change num 
                i+=1
                p = nums[i]
                nums[i] = nums[j]
                nums[j] = p
                j+=1
        return i+1
            

 买卖股票的最佳时机 II

给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。

在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。

返回 你能获得的 最大 利润 。

我的回答:

找到所有的涨幅,并相加。

[7, 1, 5, 6, 3] 第二天买入,第四天卖出,收益最大(6-1),所以一般人可能会想,怎么判断不是第三天就卖出了呢? 这里就把问题复杂化了,根据题目的意思,当天卖出以后,当天还可以买入,所以其实可以第三天卖出,第三天买入,第四天又卖出((5-1)+ (6-5) === 6 - 1)。所以算法可以直接简化为只要今天比昨天大,就卖出。

class Solution(object):
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        ans = 0
        for i in range(1, len(prices)):
            if prices[i] > prices[i-1]:
                ans += prices[i] - prices[i-1]
        return ans

 旋转数组

给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

例:

输入: nums = [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]

我的回答:

先将所有的数字进行倒叙,然后将前k个数进行倒叙,k之后的数字进行倒叙;

class Solution(object):
    def rotate(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: None Do not return anything, modify nums in-place instead.
        """
        def ro(ls):
            i,j = 0,len(ls)-1
            while i<j:
                p = ls[i]
                ls[i] = ls[j]
                ls[j] = p
                i+=1
                j-=1
            return ls
        k = k %len(nums)
        nums = ro(nums)
        nums[:k] = ro(nums[:k])
        nums[k:] = ro(nums[k:])
        return nums

 一个比较简单的做法,直接利用python中list的特性:

class Solution(object):
    def rotate(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: None Do not return anything, modify nums in-place instead.
        """
        k = k %len(nums)
        nums[:] = nums[-k:] + nums[:-k]
        return nums

 存在重复元素

给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false 。

我的回答:

第一反应是直接去重之后,比较大小。试一下提交之后的内存消耗及用时

class Solution(object):
    def containsDuplicate(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        return len(nums) != len(set(nums))

想一下,还有没有其他的方法:

1. 排序后,重复的会相邻,可以比较

直接使用sort排序:

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

 2. 插入其他的数组,之后再判定是否在其中;

这里我直接pop出一个元素进行判断,就不新建一个list了。

class Solution(object):
    def containsDuplicate(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        while len(nums):
            d = nums.pop()
            if d in nums:
                return True
        return False

python写的话会超时,同时新建list也会超时

Leecode刷题之旅-C语言/python-26.删除数组中的重复项

/*
 * @lc app=leetcode.cn id=26 lang=c
 *
 * [26] 删除排序数组中的重复项
 *
 * https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/description/
 *
 * algorithms
 * Easy (42.77%)
 * Total Accepted:    89.1K
 * Total Submissions: 208.1K
 * Testcase Example:  ‘[1,1,2]‘
 *
 * 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
 * 
 * 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 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]);
 * }
 * 
 * 
 */
int removeDuplicates(int* nums, int numsSize) {

    if(numsSize==0){ 
        return 0;    
    }    
    int length = 0;    
    for(int i=0;i<numsSize;i++)
    {        
        if(nums[i]!=nums[length])
        {            
            length++;
            nums[length]=nums[i];        
            }    
    }    
    length+=1;
    return length;
}

这里判断如果数组为空,那么返回长度为0.

设置一个length变量为0,用于记录不同值的个数。

在数组中循环,如果循环到的值不等于num[length] 实际上可以理解为 num[length]为数组的第一个数,找到和第一个数不同的数,就把length+1 然后把数存放到num[length+1]中。

之后的以此类推。因为题目中说了不需要管那些超出长度的,所以这种方法会把不一样的数一个个的存放进来,最后得到的length 是数组中可寻址的最大长度,若要返回整个数组的长度就需要把 length+1.

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

python:

#
# @lc app=leetcode.cn id=26 lang=python3
#
# [26] 删除排序数组中的重复项
#
# https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/description/
#
# algorithms
# Easy (42.77%)
# Total Accepted:    89.1K
# Total Submissions: 208.1K
# Testcase Example:  ‘[1,1,2]‘
#
# 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
# 
# 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 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]);
# }
# 
# 
#
class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        if len(nums)<=1:
           return len(nums)
        s=0
        for f in range(1,len(nums)):
            if nums[s]!=nums[f]:
                s+=1
                nums[s]=nums[f]
        return s+1

 

以上是关于leecode刷题初级-数组python版本的主要内容,如果未能解决你的问题,请参考以下文章

Leecode刷题之旅-C语言/python-26.删除数组中的重复项

Leecode刷题之旅-C语言/python-349两个数组的交集

LeeCode刷题记录

python-leecode刷题动态规划类问题----以53. 最大子数组和为例

leecode刷题-- 旋转数组

解题报告Leecode 643. 子数组最大平均数 I——Leecode 刷题系列