我有一个任务,要删除数组中的重复项,“删除”意味着将元素向下移动1
,并使最后一个元素等于0
,
所以如果我有int[] array = {1, 1, 2, 2, 3, 2};
的输出应该是这样的:
1, 2, 3, 0, 0, 0
我尝试了这种逻辑:
public class ArrayDuplicates {
public static void main(String[] args) {
int[] array = {1, 1, 2, 2, 3, 2};
System.out.println(Arrays.toString(deleteArrayDuplicates(array)));
}
public static int[] deleteArrayDuplicates(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[i] == array[j]) { //this is for comparing elements
for (; i > 0; i--) {
array[j + 1] = array[j]; //this is for shifting
}
array[array.length - 1] = 0; //making last element equal to "0"
}
}
}
return array;
}
}
但是它不起作用。.是否有人熟悉正确的解决方案? 非常感谢您的协助和关注。
答案 0 :(得分:3)
您的代码:
简而言之,您选择的方法需要第三个循环变量k来代表当前正向左移动1个位置的索引。
i
-当前唯一商品的位置j
-当前位置正在测试是否具有i
上唯一项的相等性k
-由于j
处的擦除操作,当前位置向左移动建议:
一种更有效的方法是消除每次发现重复项时发生的重复左移,而是根据找到的重复项的数量来跟踪偏移:
private static int[] deleteArrayDuplicates(int[] array) {
int dupes = 0; // total duplicates
// i - the current unique item's position
for (int i = 0; i < array.length - 1 - dupes; i++) {
int idupes = 0; // duplicates for current value of i
// j - the current position being tested for equality with unique item at i
for (int j = i + 1; j < array.length - dupes; j++) {
if (array[i] == array[j]) {
idupes++;
dupes++;
} else if(idupes > 0){
array[j-idupes] = array[j];
}
}
}
if(dupes > 0) {
Arrays.fill(array, array.length-dupes, array.length, 0);
}
return array;
}
这与answer发布的dbl具有相似的复杂性,尽管由于最后消除了一些额外的循环,所以它应该稍微快一些。另一个优点是,与该答案不同,该代码不依赖于任何假设,即输入不应该包含零。
答案 1 :(得分:2)
@artshakhov: 这是我的方法,与您所找到的方法非常接近,但是使用的操作更少了。
private static int[] deleteArrayDuplicates(int[] array) {
for (int i = 0; i < array.length - 1; i++) {
if (array[i] == NEUTRAL) continue; //if zero is a valid input value then don't waste time with it
int idx = i + 1; //no need for third cycle, just use memorization for current shifting index.
for (int j = i + 1; j < array.length; j++) {
if (array[i] == array[j]) {
array[j] = NEUTRAL;
} else {
array[idx++] = array[j];
}
}
}
return array;
}
答案 2 :(得分:1)
我刚刚编写了以下代码来回答您的问题。我对其进行了测试,并获得了您期望的输出。如果有任何我可能错过的特殊情况,我深表歉意,但它似乎适用于包括您在内的各种意见。
其背后的想法是,当我们遍历数组时,我们将使用哈希映射来跟踪是否已经在数组中看到特定元素。如果地图已经包含该元素-意味着我们已经在数组中看到该元素-我们将继续循环。但是,如果这是我们第一次看到该元素,则将更新j指向i指向的索引处的元素,然后递增j。
因此,基本上,通过j指针,我们能够将所有不同的元素移至数组的前面,同时确保其顺序与输入数组中的顺序相同。
现在,在第一个循环之后,我们的j指针指向数组中的第一个重复元素。我们可以将i设置为j并遍历数组的其余部分,使它们为零。
此算法的时间复杂度为O(N)。由于哈希表的原因,空间复杂度为O(N)。可能有一种方法可以在O(N)时间,O(1)空间中做到这一点。
public static int[] deleteArrayDuplicates(int[] array) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
int j = 0;
for (int i = 0; i < array.length; i++) {
if (map.containsKey(array[i])) {
continue;
}
else {
map.put(array[i],1);
array[j] = array[i];
j++;
}
}
for (int i = j; i < array.length; i++) {
array[i] = 0;
}
return array;
}
如果您还有其他问题,请告诉我。
答案 3 :(得分:1)
花了几个小时尝试为我自己的解决方案,并创建了这样的内容:
public static int[] deleteArrayDuplicates(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[j] == array[i]) { //this is for comparing elements
int tempIndex = j;
while (tempIndex + 1 < array.length) {
array[tempIndex] = array[tempIndex + 1]; //this is for shifting elements down/left by "1"
array[array.length - 1] = 0; //making last element equal to "0"
tempIndex++;
}
}
}
}
return array;
}
代码没有任何API帮助器,但似乎现在正在工作。
答案 4 :(得分:0)
尝试一下:
public static void main(String[] args)
{
int a[]={1,1,1,2,3,4,5};
int b[]=new int[a.length];
int top=0;
for( int i : a )
{
int count=0;
for(int j=0;j<top;j++)
{
if(i == b[j])
count+=1;
}
if(count==0)
{
b[top]=i;
top+=1;
}
}
for(int i=0 ; i < b.length ; i++ )
System.out.println( b[i] );
}
说明:
创建另一个与给定数组大小相同的数组(b)。现在只需在数组 b 中仅包含唯一元素。仅当 b 中不存在数组 a 的元素时,才将其添加到数组 b 。
答案 5 :(得分:0)
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class StackOverFlow {
public static void main(String[] args) {
int[] array = {1, 1, 2, 2, 3, 2};
Set<Integer> set=new HashSet<>();
for (int anArray : array) {
set.add(anArray);
}
int[] a=new int[array.length];
int i=0;
for (Integer s:set) {
a[i]=s;
i++;
}
System.out.println(Arrays.toString(a));
}
}
希望这个简单的方法对您有所帮助。 利用不允许重复的Set。
答案 6 :(得分:0)
我们可以使用 ARRAYLIST 和 Java-8流功能来获取输出。
public static int[] deleteArrayDuplicates(int[] array) {
List<Integer> list = new ArrayList(Arrays.stream(array).boxed().distinct().collect(Collectors.toList()));
for (int i = 0; i < array.length; i++) {
if (i < list.size()) {
array[i] = list.get(i);
} else {
array[i] = 0;
}
}
return array;
}
输出
[1、2、3、0、0、0]