Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 在数组中查找一个元素,其中每个元素重复奇数次(但不止一次出现),并且只有一个元素出现一次_Arrays_Algorithm - Fatal编程技术网

Arrays 在数组中查找一个元素,其中每个元素重复奇数次(但不止一次出现),并且只有一个元素出现一次

Arrays 在数组中查找一个元素,其中每个元素重复奇数次(但不止一次出现),并且只有一个元素出现一次,arrays,algorithm,Arrays,Algorithm,您有一个数组,其中每个数字重复奇数次(但不止一次)。一次只出现一个数字。如何找到只出现一次的号码 e.g.: {1, 6, 3, 1, 1, 6, 6, 9, 3, 3, 3, 3} 答案是9 我在考虑创建一个哈希表,然后只计算计数为1的元素。 这看起来很琐碎,我并没有使用其他元素都重复了奇数次的事实。有更好的方法吗。我相信您仍然可以使用XOR的基本思想以一种聪明的方式解决这个问题 首先,让我们改变问题,使一个数字出现一次,所有其他数字出现三次 算法: 这里A是长度n的数组: int

您有一个数组,其中每个数字重复奇数次(但不止一次)。一次只出现一个数字。如何找到只出现一次的号码

e.g.: {1, 6, 3, 1, 1, 6, 6, 9, 3, 3, 3, 3}
答案是9

我在考虑创建一个哈希表,然后只计算计数为1的元素。
这看起来很琐碎,我并没有使用其他元素都重复了奇数次的事实。有更好的方法吗。

我相信您仍然可以使用XOR的基本思想以一种聪明的方式解决这个问题

首先,让我们改变问题,使一个数字出现一次,所有其他数字出现三次


算法:

这里
A
是长度
n
的数组:

   int ones = 0;  
   int twos = 0;  
   int not_threes, x;  

   for (int i=0; i<n; ++i) {  
            x =  A[i];  
            twos |= ones & x;  
            ones ^= x;  
            not_threes = ~(ones & twos);  
            ones &= not_threes;  
            twos &= not_threes;  
   }  
int-one=0;
int-twos=0;
int不是三,x;

对于(int i=0;i对于所述的问题,最有效的答案很可能是O(n)空间答案。另一方面,如果我们将问题缩小为“除只出现一次的数字外,所有数字都出现n次”或“除只出现一次的数字外,所有数字都出现n次的倍数”对于任何n(显然大于1)都有一个相当简单的解决方案,它只需要O(1)空间,这就是将每个数字分解为位,然后计算每个位被开启的次数并取模n。如果结果是1,那么答案中应该开启它。如果是0,那么应该关闭它。(任何其他答案都表明问题的参数不成立)。如果我们检查n为2的情况,我们可以看到使用异或正是这样做的(按位加法模2)。我们只是对n的其他值进行按位加法模n的推广

顺便说一句,这就是n=3的另一个答案所做的,它实际上只是一种复杂的逐位加法,它为每一位存储一个2位的计数。称为“一”的整数包含计数的一位,而称为“二”的整数包含计数的两个位。当计数达到3时,int not_threes用于将两个位设置回零,从而以模3而不是正常的方式计数位(因为位会环绕,所以是模4)。理解他的代码最简单的方法是作为一个2位累加器,带有一个额外的部分,使其以模3工作

因此,对于除一个唯一数字外的所有数字都是3倍的情况,我们可以为32位整数编写以下代码:

int findUnique(int A[], int size) {
  // First we set up a bit vector and initialize it to 0.
  int count[32];
  for (int j=0;j<32;j++) {
    count[j] = 0;
  }

  // Then we go through each number in the list.
  for (int i=0;i<size;i++) {
    int x = A[i];

    // And for each number we go through its bits one by one.
    for (int j=0;j<32;j++) {
      // We add the bit to the total.
      count[j] += x & 1;
      // And then we take it modulo 3.
      count[j] %= 3;
      x >>= 1;
    }
  }

  // Then we just have to reassemble the answer by putting together any
  // bits which didn't appear a multiple of 3 times.
  int answer = 0;
  for (int j=31;j>=0;j--) {
    answer <<= 1;
    if (count[j] == 1) {
      answer |= 1;
    }
  }

  return answer;
}
int findUnique(int A[],int size){
//首先,我们设置一个位向量并将其初始化为0。
整数计数[32];

对于(int j=0;j,我知道这个问题的潜台词是找到一个有效或高性能的解决方案,但我认为最简单、可读的代码非常重要,在大多数情况下,它已经足够了

那么这个呢:

var value = (new [] { 1, 6, 3, 1, 1, 6, 6, 9, 3, 3, 3, 3, })
    .ToLookup(x => x)
    .Where(xs => xs.Count() == 1)
    .First()
    .Key;
好老LINQ.:-

测试分数100%,c#

使用系统;
使用System.Collections.Generic;
//您还可以使用其他导入,例如:
//使用System.Collections.Generic;
//您可以出于调试目的写入stdout,例如。
//WriteLine(“这是一条调试消息”);
类解决方案{
公共int解决方案(int[]A){
Dictionary dic=新字典();
foreach(A中的int i)
{
if(dic.ContainsKey(i))
{
dic[i]=dic[i]+1;
}
其他的
{
dic.添加(i,1);
}
}
foreach(dic中的变量d)
{
如果(d.值%2==1)
{
返回d.键;
}
}
返回-1;
}
}

Java,正确率100%,性能100%,任务分数100%

// you can also use imports, for example:
// import java.util.*;

// you can write to stdout for debugging purposes, e.g.
// System.out.println("this is a debug message");
import java.util.HashMap;

class Solution {

     /*Simple solution 
          Will be using HashMap(for performance) as Array, 
          only Key set is needed.
          Initially tried with ArryList but there was performance issue with
          that so switch to HashMap.
          Iterate over the given array and if item is there in key set         
          remove it(coz you found your pair) otherwise add as new Key.
          After full Iteration only one key will be there in the Map that is 
          your solution.
          In Short: If pair is found, remove it from Map's Key set,
          Last Key will be your solution
    */
    public int solution(int[] A) {

        //Map but used as Array
        final HashMap<Integer, Boolean> mapHave = new HashMap<>();

        //Iterate over given Array
        for (int nIdx = 0; nIdx < A.length; nIdx++) {

            //Current Item
            Integer nVal = A[nIdx];

            //Try to remove the current item, if item does not exists will
            //return null and if condition will be true
            if (mapHave.remove(nVal) == null) {
                //current item not found, add it
                mapHave.put(nVal, Boolean.TRUE);
            }
        }

        //There will be only one key remaining in the Map, that is
        //your solution
        return mapHave.keySet().iterator().next();
    }
}
//您也可以使用导入,例如:
//导入java.util.*;
//您可以出于调试目的写入stdout,例如。
//System.out.println(“这是一条调试消息”);
导入java.util.HashMap;
类解决方案{
/*简单解
将使用HashMap(用于性能)作为数组,
只需要设置键。
最初尝试使用ArryList,但出现了性能问题
因此,请切换到HashMap。
迭代给定数组,如果项在键集中
删除它(因为您找到了您的配对),否则添加为新密钥。
在完全迭代之后,地图中只有一个键
你的解决方案。
简而言之:如果找到配对,请将其从映射的密钥集中删除,
最后一个关键将是您的解决方案
*/
公共int解决方案(int[]A){
//映射但用作数组
final HashMap mapHave=新HashMap();
//迭代给定数组
for(int-nIdx=0;nIdx
如果9真的是答案,那么这个问题的措辞就不是很好。我认为9和1(3次)、3(5次)和6(3次)一样是奇数(1次)。一个更有趣的问题是,有些人重复奇数次,有些人重复偶数次。对不起,我误读了。这个问题可能遗漏了一些吗?也许是因为你必须使用固定大小的内存?但就我看来,这仍然不是很有趣,也不使用“奇数”。他说
// you can also use imports, for example:
// import java.util.*;

// you can write to stdout for debugging purposes, e.g.
// System.out.println("this is a debug message");
import java.util.HashMap;

class Solution {

     /*Simple solution 
          Will be using HashMap(for performance) as Array, 
          only Key set is needed.
          Initially tried with ArryList but there was performance issue with
          that so switch to HashMap.
          Iterate over the given array and if item is there in key set         
          remove it(coz you found your pair) otherwise add as new Key.
          After full Iteration only one key will be there in the Map that is 
          your solution.
          In Short: If pair is found, remove it from Map's Key set,
          Last Key will be your solution
    */
    public int solution(int[] A) {

        //Map but used as Array
        final HashMap<Integer, Boolean> mapHave = new HashMap<>();

        //Iterate over given Array
        for (int nIdx = 0; nIdx < A.length; nIdx++) {

            //Current Item
            Integer nVal = A[nIdx];

            //Try to remove the current item, if item does not exists will
            //return null and if condition will be true
            if (mapHave.remove(nVal) == null) {
                //current item not found, add it
                mapHave.put(nVal, Boolean.TRUE);
            }
        }

        //There will be only one key remaining in the Map, that is
        //your solution
        return mapHave.keySet().iterator().next();
    }
}