思维类型的 OJ 题篇1

1、移动零

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序

示例
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]

说明:必须在原数组上操作,不能拷贝额外的数组。尽量减少操作次数

方法一 :覆盖法

定义两个指针 i,j 如果前面指针不等于0则后面的值覆盖前面的值,最后再把 0 补回去

    def moveZeroes(self, nums: List[int]) -> None:
        j = 0
        for i in range(len(nums)):
            if nums[i] !=0:
                nums[j] = nums[i]
                j+=1
        while j< len(nums):
            nums[j] = 0
            j+=1

方法二:对方法一进行优化,但本质依然是两个指针

    void moveZeroes(vector<int>& nums) {
   
        int i = 0;
        int count = 0;
        for(;i<nums.size();++i){
   
            if(nums[i] !=0){
   
                swap(nums[count++],nums[i]);
            }
        }   
    }

方法三:python 版本,利用删除和尾加

def moveZeroes(self, nums):
	n = nums.count(0)
    for i in range(n):
    	nums.remove(0)
    	nums.append(0)

2、寻找重复数

给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。

示例 1:
输入: [1,3,4,2,2]
输出: 2

示例 2:
输入: [3,1,3,4,2]
输出: 3

说明:
(1)不能更改原数组(假设数组是只读的)
(2)只能使用额外的 O(1) 的空间
(3)时间复杂度小于 O(n2)
(4)数组中只有一个重复的数字,但它可能不止重复出现一次

方法一:首先利用库函数进行排序,然后利用判断前一个数字和后一个是否相等,如果相等则返回它

    def findDuplicate(self, nums: List[int]) -> int:
        nums.sort()
        n = len(nums)
        for i in range(1,n):
            if nums[i] == nums[i-1]:
                return nums[i]

方法二:直接利用 sum 求和函数和 set 去重函数

return (sum(nums)-sum(set(nums))) // (len(nums)-len(set(nums)))

方法三:可以用 O(N) 的时间复杂度完成

思路:遍历数组,如果发现下标对应的数据和当前数据相等,则返回这个数字,如果不相等,则把该数字和它对应的下标数字进行交换.

    def findDuplicate(self, nums: List[int]) -> int:
        n = len(nums)
        i = 0
        while i<n:
            if nums[i] != i:
                if nums[nums[i]] == nums[i]:                  
                    return nums[i]
                else:
                    nums[nums[i]], nums[i] =  nums[i], nums[nums[i]]
            else:
                i += 1

方法四:始终和第一个数字进行交换判断,因为数组中没有 0 元素,所以不用害怕在 0 的位置上有 0 元素

int findDuplicate(vector<int>& nums) {
   
	while(1){
   
      	int num = nums[0];
        if(nums[num]==num){
   
        	return num;
		}   
        nums[
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿的温柔香

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值