我有一个问题:
对象显示给定排序数组,删除重复项,使每个元素只出现一次并返回新长度。 不要为另一个数组分配额外的空间,必须使用常量内存来执行此操作。例如, 给定输入数组nums = [1,1,2], 你的函数应返回length = 2,nums的前两个元素分别为1和2。你留下的新长度并不重要。
我使用HashSet来做这个问题,但结果总是显示[1,1]。我无法弄清楚是否有人可以帮助我知道问题出在哪里?
我的代码:
class Solution {
public int removeDuplicates(int[] nums) {
if (nums.length == 0) return 0;
Set<Integer> numset = new HashSet<>();
for(int i:nums){
numset.add(i);
}
return numset.size();
}
}
您的意见 [1,1,2] 你的答案 [1,1] 预期答案 [1,2]
答案 0 :(得分:1)
假设你有一个排序数组:
int[] nums = { 1, 2, 2, 2, 4, 5, 5, 5, 7, 7, 8 };
... walk through nums, at some read position check for being a duplicate,
... (otherwise) write it compact at the write position
... return new length
覆盖nums。
由于我不想破坏编码方面的任何满足感,请继续......
战术:在纸上解决问题。
答案 1 :(得分:1)
因此,对于您的问题,这是一个简单的就地解决方案,其最坏情况时间复杂度为O(n)。
public int removeDuplicates(int[] nums){
int length = nums.length;
int index = 0;
for(int i = 0; i < length - 1; i++){
if(nums[i] == nums[i+1]){
nums[index++] = nums[i];
}
}
// this is needed because upper for loop runs until i equals to length-2
// in order to avoid ArrayOutOfBoundException
nums[index++] = nums[length-1];
// for displaying the unique array
/*
for(int i = 0; i < index; i++){
System.out.println(nums[i]);
}
*/
return index;
}
答案 2 :(得分:0)
使用额外的数据结构也违反了您提到的规则,即不为其分配额外的空间。 现在,由于您的数组已经排序,以下代码将正常工作。
int solution(int[] nums) {
int size = nums.length;
if (size == 0 || size == 1) {
return size;
}
int next = 0;
for (int i = 0; i < size - 1; i++) {
if (nums[i] != nums[i + 1]) {
nums[next++] = nums[i];
}
}
nums[next++] = nums[size - 1];
return next;
}
在上面的代码中,我们只是维护一个额外的索引(下一个)来跟踪唯一元素,并通过覆盖非唯一元素将它们移到前面。
答案 3 :(得分:0)
Integer.MAX_VALUE
或Integer.MIN_VALUE
这样的分隔符。然后,直到
点击迭代值得到它的大小或做操作
无论你需要什么地方。奇怪的解决方案,
private static int removeDuplicatesWithDelimiter(int[] nums) {
if (nums.length == 0) return 0;
Set<Integer> numset = new HashSet<>();
for(int i : nums){
numset.add(i);
}
int newArraySize = numset.size();
for (int i = 0; i < newArraySize; ++i) {
nums[i] = (Integer) numset.toArray()[i];
}
nums[newArraySize] = Integer.MIN_VALUE;
return newArraySize;
}
更好的解决方案,
class ArrayDuplicateTest {
private static int[] removeDuplicates(int[] list) {
int newLength = list.length;
// find length w/o duplicates:
for (int i = 1; i < list.length; i++) {
for (int j = 0; j < i; j++) {
if (list[i] == list[j]) { // if duplicate founded then decrease length by 1
newLength--;
break;
}
}
}
int[] newArray = new int[newLength]; // create new array with new length
newArray[0] = list[0]; // 1st element goes to new array
int inx = 1; // index for 2nd element of new array
boolean isDuplicate;
for (int i = 1; i < list.length; i++) {
isDuplicate = false;
for (int j = 0; j < i; j++) {
if (list[i] == list[j]) { // if duplicate founded then change boolean variable and break
isDuplicate = true;
break;
}
}
if (!isDuplicate) { // if it's not duplicate then put it to new array
newArray[inx] = list[i];
inx++;
}
}
return newArray;
}
public static void main(String[] args) {
int nums[] = {1, 1, 2, 3, 5, 6,6 ,6};
int noDup[] = removeDuplicates(nums);
for (int i : noDup) {
System.out.println(i + " ");
}
System.out.println("length: " + noDup.length);
}
}
答案 4 :(得分:0)
另一个&#34;就地&#34;解。 只要没有要求在任何地方保留重复值,并且Java没有办法在没有新数组的情况下缩小数组,重复项将替换为MAX_VALUE,然后排序到数组的末尾。 (请参阅代码中的内容)
BTW:在方法执行期间声明了一个变量uniqueCount
public int removeDuplicates(int[] nums) {
if (nums.length == 0) return 0;
// at least one element is unique
int uniqueCount = 1;
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i] == nums[i + 1]) {
// duplicate value replaced with Integer.MAX_VALUE to be at the end of array
nums[i] = Integer.MAX_VALUE;
} else {
// nums[i] is unique
uniqueCount++;
}
}
// Re-sort array to move MAX_VALUE elements to the end of array
Arrays.sort(nums);
return uniqueCount;
}