分享一道字节面试算法题:统计数字出现的次数

上次面试字节,碰到一个比较有意思的算法题,记录一下,给各位牛友分享。
题意:
给定一个无序数组,长度为n,每个元素都属于范围[1,n]之间,使用时间复杂度O(n)+空间复杂度O(1)的方法,求得每个元素的出现次数。
比如给定数组[1,2,2,3,5,3],最后的结果就是类似于1:1,2:2,3:2,5:1的形式,表示1出现了1次,2出现了2次,3出现了2次,5出现了1次。

解法:
这里限定了时间复杂度,那么只能用边遍历边替换的思路,力扣有移到类似的题 缺失的第一个正数,可以移步查看。

思想就是遍历数组,通过当前位置的数找到对应的下标位置,如果为正数,说明还没有被访问到,需要交换并置为-1,若为负数,需要减去1,若找到的下标不为自己,则把当前位置设为0,之后继续遍历。

步骤:

       1,2,2,3,5,3
第一步 -1,2,2,3,5,3
第二步 -1,-1,2,3,5,3
第三步 -1,-2,0,3,5,3
第四步 -1,-2,-1,0,5,3
第五步 -1,-2,-1,0,-1,3
第六步 -1,-2,-2,0,-1,0

代码:

public class Main {
    public static void main(String[] args) {
        int[][] nums = {
                {1, 1, 2, 2, 3, 5, 2, 3},
                {2, 3, 2, 3, 1},
                {5, 4, 3, 2, 1}
        };
        for (int[] num : nums) {
            System.out.println(Arrays.toString(count(num)));
        }
        // [-2, -3, -2, 0, -1, 0, 0, 0]
        // [-1, -2, -2, 0, 0]
        // [-1, -1, -1, -1, -1]
    }

    public static int[] count(int[] nums) {
        int n = nums.length;
        int i = 0;
        while (i < n) {
            // 只考虑大于0的元素
            while (nums[i] > 0) {
                // 下一个位置
                int next = nums[i] - 1;
                if (nums[next] > 0) {
                    // 交换元素
                    nums[i] = nums[next];
                    nums[next] = -1;
                } else {
                    nums[i] = 0;
                    nums[next]--;
                }
            }
            ++i;
        }
        return nums;
    }
}
#字节面试##面试题目##字节跳动##内推##秋招##Java##校招##笔记#
全部评论
这个代码有问题哦,试试样例5,4,3,2,1
2 回复 分享
发布于 2021-08-30 00:21
这个代码不对吧,比如当输入为{1,5,2,2,3,5,2,3},按这个代码执行的话在第二步就直接更新num[4]=-1,这样在第五步就丢失3这个数了,会少统计一次3
1 回复 分享
发布于 2021-08-29 22:42
可以直接用一个int数组嘛?n个元素,每个碰到自加
点赞 回复 分享
发布于 2021-09-18 18:46
更新了一下解答,感谢大家的纠错,之前想简单了😅
点赞 回复 分享
发布于 2021-08-30 23:38
不错
点赞 回复 分享
发布于 2021-08-29 21:27

相关推荐

不愿透露姓名的神秘牛友
05-13 16:09
我入职那天分到的mentor是个工作三年的哥们儿,外号杰哥,浙大本硕,技术贼好,人也特别耐心。第一周他手把手带我熟悉项目,下班还带我去公司食堂吃晚饭,跟我讲组里的人际关系、哪个产品好沟通、哪个测试爱挑刺。我当时心里那个踏实啊,心想这mentor是真带我,运气真好。我甚至已经开始幻想转正后跟着他干。周一下午四点多,我正在改一个特别恶心的bug,他飞书突然发我:"小x,跟你说个事儿,我下周一是最后一天,我跳槽了,你之后跟着王哥学。"我当时直接回复了“????”真的以为他在开玩笑。他发了一个尴尬笑的表情,"真的,offer上个月就拿了,一直没说"。我那一瞬间真的不知道说啥。下班的时候我特意去他工位转了一圈,他已经在收拾东西来,看见我笑了一下,说"我请你吃个饭吧"。我们去了公司楼下的麻辣烫。吃饭的时候他跟我说了很多,说大厂这边晋升路径太卷,说他家在外地啊老婆怀孕了啊想离家近点什么的,说新公司虽然小但是给的钱多。我一边吃一边点头,看到一个快到中年研发人的无奈,感觉也看到了未来的我,心里挺不是滋味的。今早上午他飞书里发我一个文档链接,是他这两年攒的项目笔记,模块分工、踩过的坑、谁负责啥都有。他说"这个你留着,遇到问题先看这个再找王哥吧"。说实话,我当时贼感动,工作的这两周,他可能是我在公司里唯一真正把我当回事儿的人了。最后,我想说兄弟们,找实习真的别只看大厂光环,mentor稳定性也是玄学之一。我现在心里有点空,感觉靠山没了
鹿LF:你mt不是才工作三年吗,怎么就中年研发人了
点赞 评论 收藏
分享
评论
3
12
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务