1、一个非空整数数组,除了一个元素只出现一次,其余元素都出现了两次。找出这个一单独出现的元素。
note: 线性的时间复杂度,空间复杂度。
思路:第一时间想到了 Map 的 contains。以前做过一点点题,用到过,所以第一时间就想到了它。但也仅仅是想到,模模糊糊的。写的时候有想到了 ArrayList,感觉 ArrayList 要比 Map 好一些。于是就开始写了。
class Solution {
public int singleNumber(int[] nums) {
ArrayList<Integer> list = new ArrayList<>();
for (int i : nums) {
if (list.contains(i)) {
list.remove(i);
} else {
list.add(i);
}
}
return list.get(0);
}
}
然后检验,然后报错。
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 2, Size: 1
at java.util.ArrayList.rangeCheck(ArrayList.java:614)
at java.util.ArrayList.remove(ArrayList.java:453)
at Solution.singleNumber(Solution.java:6)
at __Driver__.main(__Driver__.java:21)
这里不想 AndroidStudio 那样明确的指出了哪一行报错,可以点击定位,于是马虎的没有发现。纠结了好一会儿。发现是 list.remove(i);
的错。看了下源码,发现不是我像当然的移除此元素,而是移除此位置上的元素。没想到这里又想当然了,发现了两个 remove
方法。
/**
* Removes the element at the specified position in this list.
* Shifts any subsequent elements to the left (subtracts one from their
* indices).
*
* @param index the index of the element to be removed
* @return the element that was removed from the list
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E remove(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
modCount++;
E oldValue = (E) elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
/**
* Removes the first occurrence of the specified element from this list,
* if it is present. If the list does not contain the element, it is
* unchanged. More formally, removes the element with the lowest index
* <tt>i</tt> such that
* <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>
* (if such an element exists). Returns <tt>true</tt> if this list
* contained the specified element (or equivalently, if this list
* changed as a result of the call).
*
* @param o element to be removed from this list, if present
* @return <tt>true</tt> if this list contained the specified element
*/
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
一个是移除当前位置的元素,一个是移除此元素。第一反应懵了一下, int
与Integer
的区别这时出现了。根据这两种方法,可修改为:
list.remove(list.indexOf(i));
list.remove(Integer.valueOf(i));
真的是越简单约不简单啊。
最优解:位运算
class Solution {
public int singleNumber(int[] nums) {
int ans = 0;
for (int i : nums) {
ans ^= i;
}
return ans;
}
}
网友评论