【C】137 只出现一次的数字

给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。

你必须设计并实现线性时间复杂度的算法且使用常数级空间来解决此问题。

解法一

c 复制代码
#include <stdio.h>

int singleNumber(int* nums, int numsSize) {
    unsigned int result = 0;
    // 统计每个位上出现的次数
    for (int i = 0; i < 32; i++) {
        int count = 0;
        for (int j = 0; j < numsSize; j++) {
            if ((nums[j] >> i) & 1) {
                count++;
            }
        }
        // 如果某位上出现的次数不能被 3 整除,说明只出现一次的数在该位上为 1
        if (count % 3 != 0) {
            result |= (1u << i);
        }
    }
    return (int)result; // 将结果强制转换为有符号整数类型
}

int main() {
    int nums[] = {2, 2, 3, 2};
    int numsSize = sizeof(nums) / sizeof(nums[0]);
    printf("The single number is: %d\n", singleNumber(nums, numsSize));
    return 0;
}

tips:

后缀 u 表示将整数字面值(常量)指定为无符号整数。通常,如果不带后缀的整数常量在程序中出现,并且与无符号整数类型进行运算,那么这个整数常量会被默认为有符号整数类型。因此,当我们需要确保一个整数常量被视为无符号整数时,可以在其后面添加 u 后缀来明确指定。

这里,我们使用 (1u << i) 来表示将无符号整数 1 左移 i 位,确保不会出现符号位的影响。通过使用无符号整数,我们可以避免在进行位运算时出现意外的结果,尤其是涉及到位移操作时更需要注意这一点。

解法二

c 复制代码
int singleNumber(int* nums, int numsSize) {
    int ones = 0, twos = 0;
    for (int i = 0; i < numsSize; i++) {
        ones = (ones ^ nums[i]) & ~twos;
        twos = (twos ^ nums[i]) & ~ones;
    }
    return ones;
}

使用两个变量 ones 和 twos,分别记录每个位上出现一次和两次的数字。通过适当的位运算更新这两个变量,最终得到只出现一次的数字。

相关推荐
ACP广源盛1392462567311 分钟前
(ACP广源盛)GSV6172---MIPI/LVDS 信号转换为 Type-C/DisplayPort 1.4/HDMI 2.0 并集成嵌入式 MCU
c语言·开发语言·单片机·嵌入式硬件·音视频
im_AMBER1 小时前
算法笔记 09
c语言·数据结构·c++·笔记·学习·算法·排序算法
凯芸呢1 小时前
Java中的数组(续)
java·开发语言·数据结构·算法·青少年编程·排序算法·idea
寂静山林2 小时前
UVa 1030 Image Is Everything
算法
AI柠檬2 小时前
几种排序算法的实现和性能比较
数据结构·算法·c#·排序算法
weixin_429630262 小时前
第6章 支持向量机
算法·机器学习·支持向量机
SweetCode2 小时前
C++ 实现大数加法
开发语言·c++·算法
王哈哈^_^2 小时前
【数据集】【YOLO】【目标检测】共享单车数据集,共享单车识别数据集 3596 张,YOLO自行车识别算法实战训推教程。
人工智能·算法·yolo·目标检测·计算机视觉·视觉检测·毕业设计
CodeWizard~3 小时前
AtCoder Beginner Contest 430赛后补题
c++·算法·图论
大大dxy大大3 小时前
机器学习-KNN算法示例
人工智能·算法·机器学习