ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

数字出现的次数

2021-02-01 19:05:34  阅读:120  来源: 互联网

标签:数字 nums int 次数 数组 include 出现


文章目录

1.一个长度为n的数组,只有一个数字出现了一次,其余数字均出现了两次,请找到出现一次的这个数字

异或运算的性质:1.结合律:a ^ b = b ^ a;
2.交换律:(a ^ b ) ^ c = a ^ (b ^ c);
两个相同的数抑或得到的数是0;任何数与0抑或得到的是它本身

故一个整型数组中,若只有一个数字只出现一次,其他数字都出现了两次,那么把数组中的所有的数遍历异或一遍的结果就是只出现一次的那个数字.

#include<iostream>
using namespace std; 
int main() {    
	int n, sum = 0, temp;
    cin >> n;    
    for (int i = 0; i < n; i++) {
        cin >> temp;        
        sum ^= temp;
    }    
    cout << sum << endl;
    return 0;
}
    

2.一个长度为n的数组,只有两个数字出现了一次,其余数字均出现了两次,请找到出现一次的这两个数字

思路

[a, b, c, c, d, d, e, e, f, f]
1.现将出现偶数的数通过异或去掉:
(1)两个相同的数异或的结果是0;
(2)所有不为0的数和0异或的结果是本身。
(a异或b=a’b+b’a),
2.异或后的数是要求的两个数(a和b)的异或结果
3.异或得到的数找到该数的二进制数是1的一个位置(ind), 该数是一意味着该位置上a和b是不一样的, 一个是1, 一个是0.这样我们可以将数组里的数分成两组, 一组数的二进制数在ind是1(a, c, c, f, f), 一组数在ind的值为0(b, d,d, e, e).在将两组数分别异或便可得a和b.

#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;

int main() {    
	int n;
    cin >> n;    
    int nums[n + 5];
    int add = 0;    
    for (int i = 0; i < n; i++) {
        cin >> nums[i];       
        add ^= nums[i];
    }    
    int left = 0;
    for (int i = 0; i < 32; i++) {        
    	if ((add >> i) & 1) {
            left = i;            
            break;
        }    
    }
    int num1 = 0,  num2 = 0;    
    for (int i = 0; i < n; i++) {
        if ((nums[i] >> left) & 1) {            
        	num1 ^= nums[i];
        } else {            
        	num2 ^= nums[i];
        }    
    }
    cout << num1 << " " << num2 << endl;    
    return 0;
}

3.在一个长度为n的数组里的所有数字都在0~n - 1范围内,已知只有一个数字出现了两次,其余数字出现了一次,如何找到这个出现两次的数字,分析时间复杂度.

时间复杂度: O ( n ) O(n) O(n)空间复杂度: O ( 1 ) O(1) O(1)

现在让我们重排这个数组,从头到尾扫描这个数组中的每个数字.当扫描的下标为i的数字时,首先比较这个数字(用m表示)是不是等于i.如果是,,则接着扫描下一个数字;如果不是,则再那它和下标是m的数字n进行比较.如果m和n相等,就找到了一个重复数字(该数字在下标i和m的位置都出现了), 如果n和m不等,就把m和n交换, 把m放在属于它的位置.接下来再重复这个交换的过程,直到我们发现一个重复的数字.

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;
 int func(int *nums, int n ) {
    for (int i = 0; i < n; i++) {
    	int m = nums[i];    
    	while(m != i) {
    		int n = nums[m];
    		if (m == n) return m;            
            swap(nums[i], nums[m]);
        }    
    }
    return -1;
}
    
int main() {    
	int n;
    cin >> n;    
    int nums[n + 5];
    for (int i = 0; i < n; i++) {        
    	cin >> nums[i];
    }    
    cout << func(nums, n) << endl;
    return 0;
}

4.在一个长度为n + 1的数组里的所有数字都在1~n范围内,已知只有一个数字出现了两次,其余数字出现了一次,如何找到这个出现两次的数字,不能修改输入的数组,分析时间复杂度.

时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)空间复杂度: O ( 1 ) O(1) O(1)

1.我们把从1~ n的数字从中间的数字m分为两部分,前面一半为1 ~ m, 后面一半为m + 1 ~ n;2.如果1 ~ m的数字的数目超过m, 那么这一半的区间里一定包含重复的数字;否则,另一半m + 1 ~ n的区间里一定包含重复的数字.
3.重复过程2.直到找到一个重复的数字.

#include<cstring>#include<algorithm>
#include<cstdio>#include<queue>
#include<vector>using namespace std;
 int countRange(const int *nums, int n, int l, int r) {
    int count = 0;    for (int i = 0; i < n; i++) {
        if (nums[i] >= l && nums[i] <= r) {            count += 1;
        }    }
    return count;}

int getDuplication(const int *nums, int n) {    int l = 0, r = n - 1;
    while(r >= l) {        int mid = ((r - l ) >> 1) + l;
        int count = countRange(nums, n, l, mid);        if (l == r) {
            if (count > 1) return l;            break;
        }        if (count > (mid - l + 1)) r = mid;
        else l = mid + 1;    }
    return -1;}

int main() {    int n;
    cin >> n;    int nums[n + 5];
    for (int i = 0; i < n; i++) {        cin >> nums[i];
    }    cout << getDuplication(nums, n) << endl;
    return 0;}

5.(一个数出现n次,其他数出现m次,n < m)在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。

思路:
二进制的每个位置相加余3得到的数便是要求的.
例:{7, 4, 4, 4, 6, 6, 6, 9, 9, 9}
00111

00100
00100
00100

00101
00101
00101

01001
01001
01001

求3的余数,我们用二进制来表示(0:00; 1:01; 2:10), 分别用a, b来表示.新出现的数在该位的数用c来表示, a', b'是加上c后余3的结果.
a b c  a’ b’
0 0 0   0 0
0 1 0   0 1
1 0 0   1 0

0 0 1   0 1
0 1 1   1 0
1 0 1   0 0
出现一次的数是b’为1, b’ = (~ a & b &~ c) | (~ a & ~ b & c) = ~a & (b ^ c);

出现两次的数是a’为1, a’ = (a & ~ b & ~ c) | (~ a & b & c)
代码实现

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int a = 0, b = 0, a1, b1;
        for (int i = 0; i < nums.size(); i++) {
            int c = nums[i];
            a1 = (a & ~b & ~c) | (~a & b & c);
            b1 = ~a & ((~b & c) | (b & ~c));
            a = a1;
            b = b1;
        }
        return b;
    }
};

当m为4原理也是如此:(0 : 00, 1:01, 2: 10, 3:11)
a b c a’ b’
0 0 0 0 0
0 1 0 0 1   
1 0 0 1 0
1 1 0 1 1

0 0 1 0 1
0 1 1 1 0
1 0 1 1 1
1 1 1 0 0

a’ = (a & ~b & ~ c) | (a & b & ~c) | ( ~a & b & c) | (a & ~b & c) = (a & ~c) | (c & (a ^ b))
b’ = (b& ~c) | ( ~b & c)

标签:数字,nums,int,次数,数组,include,出现
来源: https://blog.csdn.net/weixin_43117602/article/details/113523026

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有