一组数组中只有一个数(两个数)出现一次,其他的都成对出现,找出该数

一组数据中只有一个数字出现了一次。其他所有数字都是成对出现的。请找出这个数字。(使用位运算)

>可以这么理解:如果两个数相等,它们异或之后的结果是0。而0与任何数异或都是该数本身。

(比如00000001^00000001结果是0。00000000^00000001=00000001)

那么将一组数中所有元素异或,相同的数字结果是0,最后的结果就是单独出现的数字。

编程实现如下:

#include <stdio.h>
#include <windows.h>
int main()
{
    int arr[]={1,2,3,4,5,1,2,3,4};
    int i=0;
    int j=0;
    for(i=1;i<sizeof(arr)/sizeof(arr[0]);i++)
    {
    arr[0]=arr[0]^arr[i];  //将它们整体异或
}
printf("the single is:%d\n",arr[0]);
system("pause");
return 0;
 }

那如果是一组数据中有两个数字出现了一次。其他所有数字都是成对出现的。该如何找出这两个数字。(使用位运算)

这个问题用常规的方法也可以做,依次遍历数组,查找不相同的数,打印出来。

但接着用上面的方法该怎么做呢,首先我们先分析一下:和上面的一样将整个数组异或一遍,得到一个结果,该值可以看成是要查找的两个数异或得来的。

比如一组数1,2,3,1

1:     00000001

1:     00000001

2:     00000010

3:     00000011

异或:00000001

整体 异或值肯定不等于1,那么找比特位不为0的位,该位处相同的数据,比特位是一样的;该位处不同的数据比特位是不一样的,现在分两个组分别存放这两部分,即相同的数据划分到一组,不同的数据划分到不同组。不用考虑每组中存放多少个元素,反正相同的数据肯定放在一个组中。然后问题就转化为第一题的样式,即每个分组中有一个数出现了一次,其他数都是成对出现。

代码实现如下:

#include <stdio.h>
#include <windows.h>
#include <assert.h>
void find_diff_data(int arr[],int len)
{
    assert(arr);
    assert(len>2);
    int i = 0;
    int value = arr[0];
    for(i = 0;i < len;i++)
    {
        value ^= arr[i];  //整体异或
    }
    int farg = 1;
    i = 0;
    while(i < 32)
    {
        if(value & (farg <<= i))  // 查找为1的比特位
        {
            break;
        }
    i++;
    }
    i = 0;
    int data1 = 0;
    int data2 = 0;
    for(i = 0;i < len;i++)
    {
        if(arr[i] & farg)
        {
            data1 ^= arr[i];  
        }
        else
        {
            data2 ^= arr[i];
        }
    }
    printf("%d  %d",data1,data2);
}
int main()
{
    int arr[] = {1,2,3,4,5,6,1,2,3,4};
    int len = sizeof(arr)/sizeof(arr[0]);
    find_diff_data(arr,len);
    system("pause");
    return 0;
}
时间: 2024-10-11 04:07:45

一组数组中只有一个数(两个数)出现一次,其他的都成对出现,找出该数的相关文章

查找数组中单独出现的两个数

一个数组中,只有两个数单独出现,其他数都是成对出现的,找出这两个数. 方法一:利用位运算 #include<stdio.h> int find_one_bit(int num) { int i=0; while(num) { if(num%2==1) { return i; } else { i++; } num/=2; } } void find_two_num(int arr[],int len) { int i=0; int ret=0; int pos=0; int num1=0; i

《剑指offer》:[41]数组中和为S的两个数

题目:输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的它们的和正好是S.如果有多对数字的和等于S,输出其中的一对即可. 例如输入数组{1,2,4,7,11,15}和数字15.由于4+11=15,因此输出4和11. 方案一:时间复杂度为O(N*N).顺序查找法,固定一个数,然后和剩余的N-1个数做和,看和是否为S:如没有,将固定的数下移一个,再与N-2个数字做和,看是否相等.很明显,其时间复杂度为:O(N*N) . 方案二:时间复杂度为O(N)的查找方法.因为数组是有序的递增的序列,我

JAVA基础(数组)数组排序和查找数组中是否还有某一个数

数组排序和数组中含有某一个数 import java.util.Arrays;class Demo4 { public static void main(String[] args) { //数组中的使用工具:Arrays int[] arr = {1,2,4,5}; //查找数组中是否还有某一个数 int num = 3; //有 : 对应索引位置 int result = Arrays.binarySearch(arr,num); System.out.println(result); //

给定一个整数数组和一个目标值,找出数组中和为目标值的两个数

题目描述: 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数.   你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用.示例:给定 nums = [2, 7, 11, 15], target = 9返回 [0, 1] 思路: 第一层for循环从索引0到倒数第二个索引拿到每个数组元素,第二个for循环遍历上一层for循环拿到的元素的后面的所有元素. 具体代码: 1 public class Solution { 2 public int[] twoSum(int[] nums,

找出十进制数中出现的&#39;&#39;一&#39;&#39;的个数

一.题目要求: 给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数. 要求: 1.写一个函数 f(N) ,返回1 到 N 之间出现的“1”的个数.例如 f(12)  = 5. 2.在32位整数范围内,满足条件的“f(N) =N”的最大的N是多少. 二.解决思路 通过列举几个数进行计算,可以发现函数f(N)规律如下: 1.一位十进制数:当N>=1时,f(N)=1:当N=0时,f(N)= 0; 2.两位十进制数:f(13)=个位出现1的个数+十位出现1的个数=2+4

找出一堆数中最小的前K个数

描写叙述: 给定一个整数数组.让你从该数组中找出最小的K个数 思路: 最简洁粗暴的方法就是将该数组进行排序,然后取最前面的K个数就可以. 可是,本题要求的仅仅是求出最小的k个数就可以,用排序能够但显然有点浪费.比方让求10000个整数数组中的最小的10个数.用排序的话平均时间复杂度差为Nlog(N). 于是想到了,用堆来实现,可是自己实现又太麻烦.想到了java里面的TreeSet,先将K个数放入TreeSet中.因为TreeSet会对里面的元素进行排序.所以在TreeSet中的元素是有序的.以

黑马基础阶段测试题:定义一个int类型的数组,数组中元素为{5,7,3,9,4}。求出数组中的最小值,并判断最小值是否为偶数,如果是偶数则输出“最小值为偶数”,如果不是偶数则输出“最小值为奇数”。打印如下:

package com.swift; import java.util.Arrays; public class ArrayTest { public static void main(String[] args) { /* * 定义一个int类型的数组,数组中元素为{5,7,3,9,4}. * 求出数组中的最小值,并判断最小值是否为偶数,如果是偶数则输出"最小值为偶数",如果不是偶数则输出"最小值为奇数".打印如下 */ int arr[]= {5,7,3,9,4

在一个整型数组中有一个元素的出现次数超过了数组长度的一半,试设计一个 在时间上尽可能高效的算法,找出这个元素。

题目:在一个整型数组中有一个元素的出现次数超过了数组长度的一半,试设计一个 在时间上尽可能高效的算法,找出这个元素.要求:(1)给出算法的基本设计思想.(2)根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释.(3)说明你所设计算法的时间复杂度和空间复杂度. (1)基本的设计思想: 一个数字出现的次数超过了长度的一半, 那么我们可以这样认为这个数字出现的个数一定大于其他全部数字出现的个数之和.算法的步骤如下: ①设数组为data[],数组长度为n,i=1.置currentAxi

用JAVA写一个函数,功能如下: 任意给定一组数, 找出任意数相加之后的结果为35(任意设定)的情况

用JAVA写一个函数.功能如下:任意给定一组数,例如{12,60,-8,99,15,35,17,18},找出任意数相加之后的结果为35(任意设定)的情况. 可以递归算法来解: package test1; import java.util.Arrays; public class demo { public static void main(String[] args) { String str = "12,60,-8,99,15,35,17,18,8,10,11,12"; int s