问题是这样的:
给出一个非空的整数数组,每个元素出现两次,除了一个。找到一个。
输入:[4,1,2,1,2]
输出:4
我的代码是:
public static int singleNumber(int[] nums) {
int answer = 0;
for (int i =0; i<nums.length-1; i++) {
for(int j = i+1; j<nums.length; j++) {
if(nums[i] != nums[j]) {
answer = nums[i]; //this should be where I am wrong.
}
}
}
return answer;
}
我知道输出为4,然后现在将其更改为1。 我试图弄清楚一旦找到就不更改发现的值。
答案 0 :(得分:8)
逻辑是错误的-您的内部循环会找到不是数组中唯一数字的每个数字。
我会保持Set
来跟踪遇到的数字。第一次遇到数字时,将其添加到Set
中。第二次遇到时,将其从Set
中删除。完成遍历数组后,您将获得一个带有单个元素的Set
,这是您的答案:
public static int singleNumber(int[] nums) {
Set<Integer> unique = new HashSet<>();
for (int num : nums) {
// add returns true if num is indeed new to unique
if (!unique.add(num)) {
unique.remove(num);
}
}
return unique.iterator().next();
}
答案 1 :(得分:2)
对于这个问题,我想对数字按位进行XOR。相等的数字将互相抵消,并且只有一个整数是最终值。
public static int singleNumber(int[] nums) {
int answer = 0;
for (int i =0; i<nums.length; i++) {
answer = answer ^ nums[i];
}
return answer;
}
答案 2 :(得分:1)
下面对您的方法所做的更改将为您提供预期的答案
public static int singleNumber(int[] nums) {
int temp = 0;
int answer = 0;
for (int i = 0; i < nums.length; i++) {
boolean flag = true;
temp = nums[i];
for (int j = 0; j < nums.length; j++) {
if (temp == nums[j]) {
if (i != j) {// if a match found then the loop will terminate
flag = false;
break;
}
}
}
if (flag == true) {
answer = temp;
}
}
return answer;
}
答案 3 :(得分:1)
这是Java 8中使用Collectors.groupingBy
的另一种解决方案:
public static int singleNumber(int[] nums) {
return Arrays.stream(nums).boxed()
.collect(Collectors.groupingBy(a -> a, Collectors.counting()))
.entrySet().stream().filter(e -> e.getValue() == 1).findFirst().get().getKey();
}
这个想法是:
请注意,我假设您的数组包含至少一个元素,否则您可以在搜索之前检查长度,然后引发如下异常:
public static int singleNumber(int[] nums) throws IllegalArgumentException{
if(nums.length == 0){
throw new IllegalArgumentException("empty array");
}
return Arrays.stream(nums).boxed()
.collect(Collectors.groupingBy(a -> a, Collectors.counting()))
.entrySet().stream().filter(e -> e.getValue() == 1).findFirst().get().getKey();
}
更深入地讲,如果您想避免一次重复多个数字的情况,则可以使用:
public static int singleNumber(int[] nums) throws IllegalArgumentException {
if (nums.length == 0) {
throw new IllegalArgumentException("empty array");
}
Map<Integer, Long> grouping = Arrays.stream(nums).boxed()
.collect(Collectors.groupingBy(a -> a, Collectors.counting()));
if (grouping.values().stream().filter(c -> c == 1).count() > 1) {
throw new IllegalArgumentException("more than one element is repeated one time");
}
return grouping.entrySet().stream()
.filter(e -> e.getValue() == 1).findFirst().get().getKey();
}
答案 4 :(得分:1)
这里是使用ArrayList.indexOf和ArrayList.lastIndexOf的解决方案。如果它们相同,则您有答案。
public static int singleNumber(int[] nums) {
int answer = 0;
//ArrayList<Integer> list = new ArrayList<Integer>(Arrays.asList(nums));
ArrayList al = new ArrayList();
for (int i =0; i < nums.length; i++) {
al.add(nums[i]);
}
for (int i =0; i < nums.length; i++) {
int test = nums[i];
if(al.indexOf(test) == al.lastIndexOf(test)){
answer = nums[i];
}
}
return answer;
}
答案 5 :(得分:0)
尝试一下:
int[] nums = new int[] {4,2,1,2,1};
int answer = 0;
for (int i =0; i<nums.length-1; i++) {
int times = 0;
int target = nums[i];
for(int j : nums) {
if(j == target) {
times++;
if(times == 2) {
break;
}
}
}
if(times == 1) {
answer = target;
break;
}
}
System.out.println(answer);
您必须仔细研究每个数字,如果只有1个数字,则立即计算数组中的猛度,立即停止循环结束并设置答案