Leetcode每日刷题(day3)

简介: Leetcode每日刷题(day3)

数组中重复的数字


来源:leetcode:剑指offer 03.数组中重复的数字


1、题目描述


找出数组中重复的数字。



在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。


2、示例

1669255774422.jpg

3、排序暴力求解


经历了四数之和的折磨,看到这道题目,我的内心是狂喜的,这算个题?四数之和截取的一部分就能解出来,快排一下,然后去重,so easy!😅

int cmp(const void* x,const void* y)
{
    return *(int*)x-*(int*)y;
}
int findRepeatNumber(int* nums, int numsSize)
{
    //排序后去枝叶
    int ret=0;
    qsort(nums,numsSize,sizeof(int),cmp);
    for(int i=0;i<numsSize;++i)
    {
        if(i>0&&nums[i]==nums[i-1])
        {
            ret=nums[i];
            break;
        }
    }
    return ret;
}

不得不说快排真的爽,我们来分析一下复杂度:


时间复杂度:大O一下就是O(N*logN);


空间复杂度:O(1)


然后呢?跑是跑过去了,但是面试官问:不许用排序,有没有时间复杂度是O(N),空间复杂度是O(1)的解法?果然,没那么简单。


4、交换比较解法


要求是O(N),给我们的是数组,那么只有一种可能,最多遍历一遍数组就能找出重复的数。


我们再来看题目能不能给我们点有利的线索,我们注意到:

1669255803856.jpg

这句话很重要!为什么呢?他告诉我们一个信息:如果数组内是有序的,且没有重复的数字,那么每个数的下标都应该和这个数相等!


大佬已经悟了,像我和各位老铁一样的普通码农可能还不太理解,我们进一步分析:


1669255820616.jpg


对于这一组数,如何操作呢?


1669255830541.jpg


图有点糙...


基本逻辑:


设i为下标遍历,数组为nums。


i=0为下标遍历数组,如果i不等于以nums[i],那么就把以nums[i]为下标的nums[nums[i]]和nums[i]比较,如果相等,就找到了重复的数字,如果不相等就交换,交换过后,继续比较i和nums[i],如果相等,i就++,去查看下一个数,直到找到重复的数!


void Swap(int* x,int*y)
{
    int tmp=*x;
    *x=*y;
    *y=tmp;
}
int findRepeatNumber(int* nums, int numsSize)
{
    //注意数组长度为n,且所有数字都在0~n-1的范围内,所以如果没有重复的数,那么
    //如果排好序,必定每个数的下标都与这个数相等
    int ret=0;
    for(int i=0;i<numsSize;++i)
    {
        int flag=1;
        while(i!=nums[i])
        {
            //nums[nums[i]]和nums[i]比较
            if(nums[nums[i]]==nums[i])
            {
                ret=nums[i];
                flag=0;
                break;
            }
            else//如果不等于
            {
                Swap(&nums[nums[i]],&nums[i]);
            }
        }
        if(flag==0)
            break;
    }


复杂度分析:


代码中尽管有一个双重循环,但是每次交换都为一个数找到了它在有序数组里的正确位置可以减少我们后序循环。


时间复杂度:O(N)


空间复杂度:O(1)

相关文章
|
1月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
41 6
|
1月前
|
Python
【Leetcode刷题Python】剑指 Offer 26. 树的子结构
这篇文章提供了解决LeetCode上"剑指Offer 26. 树的子结构"问题的Python代码实现和解析,判断一棵树B是否是另一棵树A的子结构。
35 4
|
1月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
73 2
|
1月前
|
索引 Python
【Leetcode刷题Python】从列表list中创建一颗二叉树
本文介绍了如何使用Python递归函数从列表中创建二叉树,其中每个节点的左右子节点索引分别是当前节点索引的2倍加1和2倍加2。
36 7
|
1月前
|
Python
【Leetcode刷题Python】剑指 Offer 30. 包含min函数的栈
本文提供了实现一个包含min函数的栈的Python代码,确保min、push和pop操作的时间复杂度为O(1)。
17 4
|
1月前
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
40 5
|
1月前
|
算法 Python
【Leetcode刷题Python】 LeetCode 2038. 如果相邻两个颜色均相同则删除当前颜色
本文介绍了LeetCode 2038题的解法,题目要求在一个由'A'和'B'组成的字符串中,按照特定规则轮流删除颜色片段,判断Alice是否能够获胜,并提供了Python的实现代码。
36 3
|
1月前
|
算法 Python
【Leetcode刷题Python】剑指 Offer 33. 二叉搜索树的后序遍历序列
本文提供了一种Python算法,用以判断给定整数数组是否为某二叉搜索树的后序遍历结果,通过识别根节点并递归验证左右子树的值是否满足二叉搜索树的性质。
15 3
|
1月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - II. 从上到下打印二叉树 II
本文提供了一种Python实现方法,用于层次遍历二叉树并按层打印结果,每层节点按从左到右的顺序排列,每层打印到一行。
28 3
|
1月前
|
Python
【Leetcode刷题Python】剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
Leetcode题目"剑指 Offer 21. 调整数组顺序使奇数位于偶数前面"的两种Python解决方案,一种是使用双端队列调整数组顺序,另一种是使用双指针法将奇数移到数组前半部分,偶数移到后半部分。
21 4