Single Number 系列

本文介绍如何在数组中找到只出现一次的元素,其他元素均出现两次或三次。通过位操作实现线性时间和常数空间复杂度的算法。

Single Number

 

Given an array of integers, every element appears twice except for one. Find that single one.

Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

注:时间复杂度需要O(n),空间复杂度O(1)

题目有点坑,正常人想不到,不正常的人才想的到。关键点在于学会位上的异或运算方式,异或既不同为真,相同为假。

1 )假设a = 10101,则有 a ^ a = 00000,0 ^ a = a,a ^ 0 = a。

2 )  异或运算符满足交换律和结合律:a ^ b = b ^ a ,( a ^ b ) ^ c = a ^ ( b ^ c )

3 )假设数组为 a b b c e a c d d,那么 a ^ b ^ b ^ c ^ e ^ a ^ c ^ d ^ d = ( a ^ a ) ^ ( b ^ b ) ^ ( c ^ c ) ^ e = 0 ^ 0 ^ 0 ^ e = e

那么e就是题目所求的答案,代码如下:

class Solution {
public:
	int singleNumber(int A[], int n) {
	    int ans = 0;
		for (int i=0; i<n; i++) {
			ans ^= A[i];
		}
		return ans;
	}
};


Single Number II

 

Given an array of integers, every element appears three times except for one. Find that single one.

Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

这题与上题有些不同,可以用普遍意义的方法来解决。由于数组中有且仅有一个数出现1次,其他数字均出现了3次,那么要找出仅出现1次的数,最笨的就是扫一遍,统计,在扫一遍发现统计次数为1次的数,这样时间复杂度为O(n + n),空间复杂度至少也是O( n ),这样就不符合题目要求。

那么可以参照Single Number I,从位上来考虑,直接看例子:
假设数组A元素整型且为4位的二进制,数组元素为 1101,0111,1101,1101四个二进制数

A[0]                                   1 1 0 1

A[1]                                   0 1 1 1

A[2]                                   1 1 0 1

A[3]                                   1 1 0 1

统计每一位上1的个数       3 4 1 4

将每一位上1的个数mod3  0 1 1 1,0111二进制数结果就是题目所要求的。

基本思想:由于数出现3次,那么在第i位上1出现的个数也为3的倍数,而仅出现1次的数,在第i位上1出现的次数便是多余的1次。

代码如下:

class Solution {
public:
    int singleNumber(int A[], int n) {
        const int LEN = 32;             //int型在32位机器里面为32位
        int cnt[LEN];                   //用来统计每位上1的个数
        int res = 0;
        memset(cnt, 0, sizeof(cnt));
        for(int i=0; i<LEN; ++i) {
            for(int j=0; j<n; ++j) {    //遍历数组,判断第i位上是否为1
                if( A[j]>>i & 1 )
                    ++cnt[i];
            }
            res |= (cnt[i]%3)<<i;       //第i位上1的个数mod3后结果即为仅出现1次的元素的第i位上的取值
        }
        return res;
    }
};




### Number 类型概述 在不同编程语言中,`number` 类型有着不同的实现方式和分类。 #### JavaScript 中的 `number` JavaScript 的 `number` 是一种原始数据类型,用于表示整数和浮点数[^1]。此类型的内部实现基于 IEEE 754 标准下的双精度64位浮点格式。这意味着所有的数字,在 JavaScript 中都被视为带有小数部分的值,即使它们看起来像是整数。此外,特殊数值如 `Infinity`, `-Infinity` 和 `NaN` (Not-a-Number)也归属于 number 类型。 ```javascript let integer = 42; // 整数 let float = 3.14159; // 浮点数 let infinity = Infinity; // 正无穷大 console.log(typeof integer === 'number'); // true ``` #### Python 中的 `number` 相比之下,Python 提供了一个更为丰富的数字体系结构。它不仅包含了整数(`int`)和浮点数(`float`),还有复数(`complex`)和支持高精度运算的大整数等[^2]。这些不同类型被设计成能够处理更广泛的应用场景需求: ```python integer_value = 10 # int 类型 floating_point = 3.14 # float 类型 print(type(integer_value)) # 输出:<class 'int'> print(type(floating_point))# 输出:<class 'float'> ``` #### MySQL 数据库中的 `number` 对于数据库管理系统而言,比如 MySQL,则定义了一系列专门针对存储效率优化过的 numeric 数据类型[^3]。其中包括但不限于 TINYINT、SMALLINT、MEDIUMINT、INT 或 INTEGER 及 BIGINT 来保存不同范围内的精确整数值;DECIMAL/FIXED 被用来确保金融计算时的小数准确性;FLOAT/SINGLE 和 DOUBLE/REAL 则适用于近似科学计数法表达形式。 综上所述,尽管各平台下具体表现有所差异,但总体来说 `number` 属于基础的数据类型之一,旨在满足程序开发过程中对算术操作的支持需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值