我被要求编写自己的实现来删除数组中的重复值。这就是我创造的。但经过1,000,000个元素的测试后,需要很长时间才能完成。我可以做些什么来改进我的算法或删除任何错误?
我需要编写自己的实现 - 而不是use Set
,HashSet
等。或者任何其他工具,如迭代器。只需一个数组即可删除重复项。
public static int[] removeDuplicates(int[] arr) {
int end = arr.length;
for (int i = 0; i < end; i++) {
for (int j = i + 1; j < end; j++) {
if (arr[i] == arr[j]) {
int shiftLeft = j;
for (int k = j+1; k < end; k++, shiftLeft++) {
arr[shiftLeft] = arr[k];
}
end--;
j--;
}
}
}
int[] whitelist = new int[end];
for(int i = 0; i < end; i++){
whitelist[i] = arr[i];
}
return whitelist;
}
答案 0 :(得分:34)
您可以借助设置集合
int end = arr.length;
Set<Integer> set = new HashSet<Integer>();
for(int i = 0; i < end; i++){
set.add(arr[i]);
}
现在,如果您将遍历此集,它将仅包含唯一值。迭代代码是这样的:
Iterator it = set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
答案 1 :(得分:14)
注意:我假设数组已排序。
代码:
int[] input = new int[]{1, 1, 3, 7, 7, 8, 9, 9, 9, 10};
int current = input[0];
boolean found = false;
for (int i = 0; i < input.length; i++) {
if (current == input[i] && !found) {
found = true;
} else if (current != input[i]) {
System.out.print(" " + current);
current = input[i];
found = false;
}
}
System.out.print(" " + current);
输出:
1 3 7 8 9 10
答案 2 :(得分:7)
通过删除最里面的for循环,对原始代码本身进行轻微修改。
public static int[] removeDuplicates(int[] arr){
int end = arr.length;
for (int i = 0; i < end; i++) {
for (int j = i + 1; j < end; j++) {
if (arr[i] == arr[j]) {
/*int shiftLeft = j;
for (int k = j+1; k < end; k++, shiftLeft++) {
arr[shiftLeft] = arr[k];
}*/
arr[j] = arr[end-1];
end--;
j--;
}
}
}
int[] whitelist = new int[end];
/*for(int i = 0; i < end; i++){
whitelist[i] = arr[i];
}*/
System.arraycopy(arr, 0, whitelist, 0, end);
return whitelist;
}
答案 3 :(得分:7)
由于您可以假设范围在0-1000之间,因此有一个非常简单有效的解决方案
//Throws an exception if values are not in the range of 0-1000
public static int[] removeDuplicates(int[] arr) {
boolean[] set = new boolean[1001]; //values must default to false
int totalItems = 0;
for (int i = 0; i < arr.length; ++i) {
if (!set[arr[i]]) {
set[arr[i]] = true;
totalItems++;
}
}
int[] ret = new int[totalItems];
int c = 0;
for (int i = 0; i < set.length; ++i) {
if (set[i]) {
ret[c++] = i;
}
}
return ret;
}
这以线性时间O(n)运行。警告:返回的数组已排序,如果这是非法的,则此答案无效。
答案 4 :(得分:6)
class Demo
{
public static void main(String[] args)
{
int a[]={3,2,1,4,2,1};
System.out.print("Before Sorting:");
for (int i=0;i<a.length; i++ )
{
System.out.print(a[i]+"\t");
}
System.out.print ("\nAfter Sorting:");
//sorting the elements
for(int i=0;i<a.length;i++)
{
for(int j=i;j<a.length;j++)
{
if(a[i]>a[j])
{
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
//After sorting
for(int i=0;i<a.length;i++)
{
System.out.print(a[i]+"\t");
}
System.out.print("\nAfter removing duplicates:");
int b=0;
a[b]=a[0];
for(int i=0;i<a.length;i++)
{
if (a[b]!=a[i])
{
b++;
a[b]=a[i];
}
}
for (int i=0;i<=b;i++ )
{
System.out.print(a[i]+"\t");
}
}
}
OUTPUT:Before Sortng:3 2 1 4 2 1 After Sorting:1 1 2 2 3 4
Removing Duplicates:1 2 3 4
答案 5 :(得分:5)
这个问题存在很多解决方案。
排序方法
设定方法
您创建一个布尔数组,表示所有准备好的项目(这取决于您在数组中的数据)。
如果您处理大量数据,我会选择1.解决方案。由于您没有分配额外的内存,因此排序速度非常快。对于小的数据集,复杂度将是n ^ 2但是对于大的i,将是n log n。
答案 6 :(得分:4)
如果你创建了两个布尔数组怎么办:1表示负值,1表示正值,并将它们全部设为false。
然后你循环输入数组并在数组中查找已经存在的值。 如果没有,则将其添加到输出数组并将其标记为已使用。
答案 7 :(得分:2)
public static int[] removeDuplicates(int[] arr){
HashSet<Integer> set = new HashSet<>();
final int len = arr.length;
//changed end to len
for(int i = 0; i < len; i++){
set.add(arr[i]);
}
int[] whitelist = new int[set.size()];
int i = 0;
for (Iterator<Integer> it = set.iterator(); it.hasNext();) {
whitelist[i++] = it.next();
}
return whitelist;
}
以O(N)时间而不是O(N ^ 3)时间运行
答案 8 :(得分:2)
由于这个问题仍然受到很多关注,我决定通过复制this answer from Code Review.SE来回答这个问题:
您遵循与冒泡排序相同的理念,即 非常非常非常慢你试过这个吗?:
使用quicksort对无序数组进行排序。 Quicksort要快得多 冒泡排序(我知道,你不是排序,而是算法你 follow几乎与冒泡排序一样遍历数组)。
然后开始删除重复项(重复的值将在每个旁边 其他)。在
for
循环中,您可以有两个索引:source
和destination
。 (在每个循环中,您将source
复制到destination
,除非它们 是相同的,并且增加1)。每次你找到一个 重复你增加源(并且不要执行复制)。 @morgano
答案 9 :(得分:2)
package com.pari.practice;
import java.util.HashSet;
import java.util.Iterator;
import com.pari.sort.Sort;
public class RemoveDuplicates {
/**
* brute force- o(N square)
*
* @param input
* @return
*/
public static int[] removeDups(int[] input){
boolean[] isSame = new boolean[input.length];
int sameNums = 0;
for( int i = 0; i < input.length; i++ ){
for( int j = i+1; j < input.length; j++){
if( input[j] == input[i] ){ //compare same
isSame[j] = true;
sameNums++;
}
}
}
//compact the array into the result.
int[] result = new int[input.length-sameNums];
int count = 0;
for( int i = 0; i < input.length; i++ ){
if( isSame[i] == true) {
continue;
}
else{
result[count] = input[i];
count++;
}
}
return result;
}
/**
* set - o(N)
* does not guarantee order of elements returned - set property
*
* @param input
* @return
*/
public static int[] removeDups1(int[] input){
HashSet myset = new HashSet();
for( int i = 0; i < input.length; i++ ){
myset.add(input[i]);
}
//compact the array into the result.
int[] result = new int[myset.size()];
Iterator setitr = myset.iterator();
int count = 0;
while( setitr.hasNext() ){
result[count] = (int) setitr.next();
count++;
}
return result;
}
/**
* quicksort - o(Nlogn)
*
* @param input
* @return
*/
public static int[] removeDups2(int[] input){
Sort st = new Sort();
st.quickSort(input, 0, input.length-1); //input is sorted
//compact the array into the result.
int[] intermediateResult = new int[input.length];
int count = 0;
int prev = Integer.MIN_VALUE;
for( int i = 0; i < input.length; i++ ){
if( input[i] != prev ){
intermediateResult[count] = input[i];
count++;
}
prev = input[i];
}
int[] result = new int[count];
System.arraycopy(intermediateResult, 0, result, 0, count);
return result;
}
public static void printArray(int[] input){
for( int i = 0; i < input.length; i++ ){
System.out.print(input[i] + " ");
}
}
public static void main(String[] args){
int[] input = {5,6,8,0,1,2,5,9,11,0};
RemoveDuplicates.printArray(RemoveDuplicates.removeDups(input));
System.out.println();
RemoveDuplicates.printArray(RemoveDuplicates.removeDups1(input));
System.out.println();
RemoveDuplicates.printArray(RemoveDuplicates.removeDups2(input));
}
}
输出: 5 6 8 0 1 2 9 11
0 1 2 5 6 8 9 11
0 1 2 5 6 8 9 11
我刚刚编写了上面的代码以供尝试。感谢。
答案 10 :(得分:2)
这是对数组中元素进行排序的简单方法
public class DublicatesRemove {
public static void main(String args[]) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("enter size of the array");
int l = Integer.parseInt(br.readLine());
int[] a = new int[l];
// insert elements in the array logic
for (int i = 0; i < l; i++)
{
System.out.println("enter a element");
int el = Integer.parseInt(br.readLine());
a[i] = el;
}
// sorting elements in the array logic
for (int i = 0; i < l; i++)
{
for (int j = 0; j < l - 1; j++)
{
if (a[j] > a[j + 1])
{
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
// remove duplicate elements logic
int b = 0;
a[b] = a[0];
for (int i = 1; i < l; i++)
{
if (a[b] != a[i])
{
b++;
a[b]=a[i];
}
}
for(int i=0;i<=b;i++)
{
System.out.println(a[i]);
}
}
}
答案 11 :(得分:1)
int tempvar=0; //Variable for the final array without any duplicates
int whilecount=0; //variable for while loop
while(whilecount<(nsprtable*2)-1) //nsprtable can be any number
{
//to check whether the next value is idential in case of sorted array
if(temparray[whilecount]!=temparray[whilecount+1])
{
finalarray[tempvar]=temparray[whilecount];
tempvar++;
whilecount=whilecount+1;
}
else if (temparray[whilecount]==temparray[whilecount+1])
{
finalarray[tempvar]=temparray[whilecount];
tempvar++;
whilecount=whilecount+2;
}
}
希望这有助于或解决目的。
答案 12 :(得分:1)
public static void main(String args[]) {
int[] intarray = {1,2,3,4,5,1,2,3,4,5,1,2,3,4,5};
Set<Integer> set = new HashSet<Integer>();
for(int i : intarray) {
set.add(i);
}
Iterator<Integer> setitr = set.iterator();
for(int pos=0; pos < intarray.length; pos ++) {
if(pos < set.size()) {
intarray[pos] =setitr.next();
} else {
intarray[pos]= 0;
}
}
for(int i: intarray)
System.out.println(i);
}
答案 13 :(得分:1)
对于已排序的数组,只需检查下一个索引:
//sorted data!
public static int[] distinct(int[] arr) {
int[] temp = new int[arr.length];
int count = 0;
for (int i = 0; i < arr.length; i++) {
int current = arr[i];
if(count > 0 )
if(temp[count - 1] == current)
continue;
temp[count] = current;
count++;
}
int[] whitelist = new int[count];
System.arraycopy(temp, 0, whitelist, 0, count);
return whitelist;
}
答案 14 :(得分:1)
我知道这有点死了,但我只是写了这个用于我自己的用途。它或多或少与添加到hashset然后从中拉出所有元素相同。它应该在O(nlogn)最坏的情况下运行。
public static int[] removeDuplicates(int[] numbers) {
Entry[] entries = new Entry[numbers.length];
int size = 0;
for (int i = 0 ; i < numbers.length ; i++) {
int nextVal = numbers[i];
int index = nextVal % entries.length;
Entry e = entries[index];
if (e == null) {
entries[index] = new Entry(nextVal);
size++;
} else {
if(e.insert(nextVal)) {
size++;
}
}
}
int[] result = new int[size];
int index = 0;
for (int i = 0 ; i < entries.length ; i++) {
Entry current = entries[i];
while (current != null) {
result[i++] = current.value;
current = current.next;
}
}
return result;
}
public static class Entry {
int value;
Entry next;
Entry(int value) {
this.value = value;
}
public boolean insert(int newVal) {
Entry current = this;
Entry prev = null;
while (current != null) {
if (current.value == newVal) {
return false;
} else if(current.next != null) {
prev = current;
current = next;
}
}
prev.next = new Entry(value);
return true;
}
}
答案 15 :(得分:1)
您需要对数组进行排序,然后循环并删除重复项。由于您无法使用其他工具,因此您需要自己编写代码。
您可以在Java on the internet中轻松找到快速排序的示例(此示例基于此示例)。
public static void main(String[] args) throws Exception {
final int[] original = new int[]{1, 1, 2, 8, 9, 8, 4, 7, 4, 9, 1};
System.out.println(Arrays.toString(original));
quicksort(original);
System.out.println(Arrays.toString(original));
final int[] unqiue = new int[original.length];
int prev = original[0];
unqiue[0] = prev;
int count = 1;
for (int i = 1; i < original.length; ++i) {
if (original[i] != prev) {
unqiue[count++] = original[i];
}
prev = original[i];
}
System.out.println(Arrays.toString(unqiue));
final int[] compressed = new int[count];
System.arraycopy(unqiue, 0, compressed, 0, count);
System.out.println(Arrays.toString(compressed));
}
private static void quicksort(final int[] values) {
if (values.length == 0) {
return;
}
quicksort(values, 0, values.length - 1);
}
private static void quicksort(final int[] values, final int low, final int high) {
int i = low, j = high;
int pivot = values[low + (high - low) / 2];
while (i <= j) {
while (values[i] < pivot) {
i++;
}
while (values[j] > pivot) {
j--;
}
if (i <= j) {
swap(values, i, j);
i++;
j--;
}
}
if (low < j) {
quicksort(values, low, j);
}
if (i < high) {
quicksort(values, i, high);
}
}
private static void swap(final int[] values, final int i, final int j) {
final int temp = values[i];
values[i] = values[j];
values[j] = temp;
}
因此,该过程分三个步骤进行。
O(nlgn)
O(n)
O(n)
因此,这会显着改善您的O(n^3)
方法。
输出:
[1, 1, 2, 8, 9, 8, 4, 7, 4, 9, 1]
[1, 1, 1, 2, 4, 4, 7, 8, 8, 9, 9]
[1, 2, 4, 7, 8, 9, 0, 0, 0, 0, 0]
[1, 2, 4, 7, 8, 9]
修改强>
OP表明数组中的值并不重要。但我可以假设范围介于0-1000 之间。这是一个经典案例,可以使用O(n)种类。
我们创建了一个大小为range +1
的数组,在本例中为1001
。然后,我们遍历数据并递增与数据点对应的每个索引上的值。
然后我们可以压缩生成的数组,删除未递增的值。这使得值在我们忽略计数时是唯一的。
public static void main(String[] args) throws Exception {
final int[] original = new int[]{1, 1, 2, 8, 9, 8, 4, 7, 4, 9, 1, 1000, 1000};
System.out.println(Arrays.toString(original));
final int[] buckets = new int[1001];
for (final int i : original) {
buckets[i]++;
}
final int[] unique = new int[original.length];
int count = 0;
for (int i = 0; i < buckets.length; ++i) {
if (buckets[i] > 0) {
unique[count++] = i;
}
}
final int[] compressed = new int[count];
System.arraycopy(unique, 0, compressed, 0, count);
System.out.println(Arrays.toString(compressed));
}
输出:
[1, 1, 2, 8, 9, 8, 4, 7, 4, 9, 1, 1000, 1000]
[1, 2, 4, 7, 8, 9, 1000]
答案 16 :(得分:1)
更新用户输入并不是很大的乐趣,但是要考虑到您的限制...
public int[] removeDup(int[] nums) {
Arrays.sort(nums);
int x = 0;
for (int i = 0; i < nums.length; i++) {
if (i == 0 || nums[i] != nums[i - 1]) {
nums[x++] = nums[i];
}
}
return Arrays.copyOf(nums, x);
}
可以使用任何nlog(n)算法轻松替换数组排序。
答案 17 :(得分:0)
这是我的解决方案。时间复杂度为o(n ^ 2)
{{1}}
答案 18 :(得分:0)
const App = () => (
<BrowserRouter>
<Provider store={store}>
<Switch>
<Route path="/contribute" component={Contribute} />
<Route path="/" component={Landing} />
</Switch>
</Provider>
</BrowserRouter>
);
答案 19 :(得分:0)
package javaa;
public class UniqueElementinAnArray
{
public static void main(String[] args)
{
int[] a = {10,10,10,10,10,100};
int[] output = new int[a.length];
int count = 0;
int num = 0;
//Iterate over an array
for(int i=0; i<a.length; i++)
{
num=a[i];
boolean flag = check(output,num);
if(flag==false)
{
output[count]=num;
++count;
}
}
//print the all the elements from an array except zero's (0)
for (int i : output)
{
if(i!=0 )
System.out.print(i+" ");
}
}
/***
* If a next number from an array is already exists in unique array then return true else false
* @param arr Unique number array. Initially this array is an empty.
* @param num Number to be search in unique array. Whether it is duplicate or unique.
* @return true: If a number is already exists in an array else false
*/
public static boolean check(int[] arr, int num)
{
boolean flag = false;
for(int i=0;i<arr.length; i++)
{
if(arr[i]==num)
{
flag = true;
break;
}
}
return flag;
}
}
答案 20 :(得分:0)
这是一个访谈问题:从数组中删除重复项。我不会使用任何Set或集合。完整的解决方案是:
git remote | xargs git remote remove
答案 21 :(得分:0)
GetRequestStream()
答案 22 :(得分:0)
这里有一种更简单,更好的方法是使用arraylists:
public static final <T> ArrayList<T> removeDuplicates(ArrayList<T> in){
ArrayList<T> out = new ArrayList<T>();
for(T t : in)
if(!out.contains(t))
out.add(t);
return out;
}
答案 23 :(得分:0)
如果允许您使用Java 8流:
Arrays.stream(arr).distinct().toArray();
答案 24 :(得分:0)
在不使用set的情况下从整数数组中删除重复项的最有效方法是,仅创建一个temp数组并迭代原始数组,并检查temp数组中是否存在数字,然后不压入数组,否则放入temp数组并返回temp结果数组。请考虑以下代码片段:
package com.numbers;
import java.util.Arrays;
public class RemoveDuplicates {
public int[] removeDuplicate(int[] array) {
int[] tempArray = new int[array.length];
int j = 0;
for (int i : array) {
if (!isExists(tempArray, i)) {
tempArray[j++] = i;
}
}
return tempArray;
}
public static boolean isExists(int[] array, int num) {
if (array == null)
return false;
for (int i : array) {
if (i == num) {
return true;
}
}
return false;
}
public static void main(String[] args) {
int [] array = { 10, 20, 30, 10, 45, 30 };
RemoveDuplicates duplicates = new RemoveDuplicates();
System.out.println("Before removing duplicates : " + Arrays.toString(array));
int [] newArray = duplicates.removeDuplicate(array);
System.out.println("After removing duplicates : " + Arrays.toString(newArray));
}
}
答案 25 :(得分:0)
删除重复项只是一个窍门。
public class RemoveDuplicates {
public static void main(String[] args) {
int[] arr = {2,2,2,2,2,5,9, 4,5,6,1,6,6,2,4,7};
arr = removeDuplicates(arr);
print(arr);
}
public static int[] removeDuplicates(int [] arr) {
final int garbage = -2147483648;
int duplicates = 0;
for(int i=0; i<arr.length; i++) {
for(int j=i+1; j<arr.length; j++) {
if (arr[i] == arr[j]) {
arr[i] = garbage;
duplicates++;
}
}
}
int[] nArr = new int[arr.length - duplicates];
int nItr = 0;
for(int i=0; i<arr.length; i++) {
if (arr[i] != garbage) {
nArr[nItr] = arr[i];
nItr++;
}
}
return nArr;
}
public static void print(int [] arr) {
for (int n : arr) {
System.out.print(n + "\t");
}
}
}
答案 26 :(得分:0)
public class FindDuplicates {
public static void main(String[] args)
{
int a[]={80,70,50,50,30,10,20,10};
System.out.print("Before Sorting: ");
for (int i=0;i<a.length; i++ )
{
System.out.print(a[i]+"\t");
}
System.out.print ("\nAfter Sorting: ");
//sorting the elements
for(int i=0;i<a.length;i++)
{
for(int j=i+1;j<a.length;j++)
{
if(a[i]>a[j])
{
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
//After sorting
for(int i=0;i<a.length;i++)
{
System.out.print(a[i]+"\t");
}
System.out.print("\nAfter removing duplicates:");
int temp[] = new int[a.length];
int j=0;
for (int i=0;i<a.length-1;i++)
{
if(a[i]!=a[i+1])
{
temp[j]=a[i];
j++;
}
}
temp[j]=a[a.length-1];
for (int i=0;i<temp.length;i++)
{
System.out.print(temp[i]+"\t");
}
}
}
答案 27 :(得分:0)
import java.util.Arrays;
public class Practice {
public static void main(String[] args) {
int a[] = { 1, 3, 3, 4, 2, 1, 5, 6, 7, 7, 8, 10 };
Arrays.sort(a);
int j = 0;
for (int i = 0; i < a.length - 1; i++) {
if (a[i] != a[i + 1]) {
a[j] = a[i];
j++;
}
}
a[j] = a[a.length - 1];
for (int i = 0; i <= j; i++) {
System.out.println(a[i]);
}
}
}
**This is the most simplest way**
答案 28 :(得分:0)
您可以使用辅助数组(temp),该数组在索引中是主数组的编号。因此,时间复杂度将为线性和O(n)。因为我们想在不使用任何库的情况下做到这一点,所以我们定义了另一个数组(唯一)来推送非重复元素:
var num = [2,4,9,4,1,2,24,12,4];
let temp = [];
let unique = [];
let j = 0;
for (let i = 0; i < num.length; i++){
if (temp[num[i]] !== 1){
temp[num[i]] = 1;
unique[j++] = num[i];
}
}
console.log(unique);
答案 29 :(得分:0)
如果您要使用相同的数组删除重复项,同时还要保持O(n)的时间复杂度。然后,这应该可以解决问题。另外,只有在对数组排序后才能起作用。
function removeDuplicates_sorted(arr){
let j = 0;
for(let x = 0; x < arr.length - 1; x++){
if(arr[x] != arr[x + 1]){
arr[j++] = arr[x];
}
}
arr[j++] = arr[arr.length - 1];
arr.length = j;
return arr;
}
这里是未排序数组的O(n),但使用的空间比已排序数组还要复杂。
function removeDuplicates_unsorted(arr){
let map = {};
let j = 0;
for(var numbers of arr){
if(!map[numbers]){
map[numbers] = 1;
arr[j++] = numbers;
}
}
arr.length = j;
return arr;
}
答案 30 :(得分:0)
我们可以使用堆数据结构删除重复项。
O(n)
)O(nlog(n))
,因为我们要从堆中删除一个元素,而要花费log n
,我们要这样做直到从堆n * logn
中删除所有n个元素为止。总时间复杂度为O(nlog(n))
。
我的方法的Python代码
import heapq
l =[1,2,4,6,3,2,6,1]
heapq.heapify(l)
no_duplicate_list =[]
try:
while True:
e = heapq.heappop(l)# will return the minimum value from the heap
if no_duplicate_list ==[]:
no_duplicate_list.append(e)
else:
if e == no_duplicate_list[-1]:
continue
no_duplicate_list.append(e)
except IndexError as i:
print(no_duplicate_list) #[1, 2, 3, 4, 6]
答案 31 :(得分:0)
为什么所有人都不检查下面的行?
我需要编写自己的实现 - 不要使用Set,HashSet等。或者任何其他工具,如迭代器。只需一个数组即可删除重复项。
我发布了非常简单的实施方案,并注意上述内容。
public class RemoveDuplicates {
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 2, 3, 1 }; // input array
int len = arr.length;
for (int i = 0; i < arr.length; i++) {
for (int j = i + 1; j < len; j++) {
if (arr[i] == arr[j]) {
while (j < (len) - 1) {
arr[j] = arr[j - 1];
j++;
}
len--;
}
}
}
for (int i = 0; i < len; i++) {
System.out.print(" " +arr[i]);
}
}
}
输入:1,2,3,4,2,3,1
输出:1 2 3 4
答案 32 :(得分:0)
好的,所以你不能使用Set
或其他收藏品。到目前为止我没有看到的一个解决方案是基于Bloom filter的使用,它本质上是一个位数组,所以可能会超出你的要求。
布隆过滤器是一种可爱且非常方便的技术,快速且节省空间,可用于快速检查集合中元素的存在,而无需存储集合本身或元素。它具有(通常较小的)假阳性率,但没有假阴性率。换句话说,对于您的问题,如果Bloom过滤器告诉您到目前为止尚未看到某个元素,您可以确定它没有。但如果它说已经看到一个元素,你实际上需要检查。如果您的列表中没有太多重复项,这仍然可以节省大量时间(对于那些,没有循环要做,除了在假阳性的小概率情况下 - 您通常根据多少选择此速率您愿意为Bloom过滤器提供的空间(经验法则:每个独特元素少于10位,误报率为1%)。
Bloom过滤器有很多实现,例如, here或here,所以我不会在这个答案中重复这一点。让我们假设最后一个引用中描述的api,特别是put(E e)
的{{3}}:
true
如果Bloom过滤器的位由于此操作而改变。如果位改变了,那么第一次将对象添加到过滤器时肯定是。如果位未更改,则可能是第一次将对象添加到过滤器。 (...)
使用这种Bloom过滤器的实现将是:
public static int[] removeDuplicates(int[] arr) {
ArrayList<Integer> out = new ArrayList<>();
int n = arr.length;
BloomFilter<Integer> bf = new BloomFilter<>(...); // decide how many bits and how many hash functions to use (compromise between space and false positive rate)
for (int e : arr) {
boolean might_contain = !bf.put(e);
boolean found = false;
if (might_contain) {
// check if false positive
for (int u : out) {
if (u == e) {
found = true;
break;
}
}
}
if (!found) {
out.add(e);
}
}
return out.stream().mapToInt(i -> i).toArray();
}
显然,如果您可以更改传入的数组,那么就不需要ArrayList
:最后,当您知道唯一元素的实际数量时,只需要arraycopy()
。
答案 33 :(得分:0)
这一个怎么样,只有对于排序数组的数字,打印没有重复的数组,不使用Set 或其他集合,只是数组:
public static int[] removeDuplicates(int[] array) {
int[] nums =new int[array.length];
int addedNum = 0;
int j=0;
for(int i=0;i<array.length;i++) {
if (addedNum != array[i]) {
nums[j] = array[i];
j++;
addedNum = nums[j-1];
}
}
return Arrays.copyOf(nums, j);
}
以33020纳秒( 0.033020毫秒)处理的1040个重复数字的数组。
答案 34 :(得分:0)
这不是使用Set,Map,List或任何额外的集合,只有两个数组:
package arrays.duplicates;
import java.lang.reflect.Array;
import java.util.Arrays;
public class ArrayDuplicatesRemover<T> {
public static <T> T[] removeDuplicates(T[] input, Class<T> clazz) {
T[] output = (T[]) Array.newInstance(clazz, 0);
for (T t : input) {
if (!inArray(t, output)) {
output = Arrays.copyOf(output, output.length + 1);
output[output.length - 1] = t;
}
}
return output;
}
private static <T> boolean inArray(T search, T[] array) {
for (T element : array) {
if (element.equals(search)) {
return true;
}
}
return false;
}
}
主要测试它
package arrays.duplicates;
import java.util.Arrays;
public class TestArrayDuplicates {
public static void main(String[] args) {
Integer[] array = {1, 1, 2, 2, 3, 3, 3, 3, 4};
testArrayDuplicatesRemover(array);
}
private static void testArrayDuplicatesRemover(Integer[] array) {
final Integer[] expectedResult = {1, 2, 3, 4};
Integer[] arrayWithoutDuplicates = ArrayDuplicatesRemover.removeDuplicates(array, Integer.class);
System.out.println("Array without duplicates is supposed to be: " + Arrays.toString(expectedResult));
System.out.println("Array without duplicates currently is: " + Arrays.toString(arrayWithoutDuplicates));
System.out.println("Is test passed ok?: " + (Arrays.equals(arrayWithoutDuplicates, expectedResult) ? "YES" : "NO"));
}
}
输出:
Array without duplicates is supposed to be: [1, 2, 3, 4]
Array without duplicates currently is: [1, 2, 3, 4]
Is test passed ok?: YES
答案 35 :(得分:0)
我觉得Android Killer的想法很棒,但我只是想知道我们是否可以利用HashMap。所以我做了一个小实验。我发现HashMap似乎比HashSet更快。
这是代码:
int[] input = new int[1000000];
for (int i = 0; i < input.length; i++) {
Random random = new Random();
input[i] = random.nextInt(200000);
}
long startTime1 = new Date().getTime();
System.out.println("Set start time:" + startTime1);
Set<Integer> resultSet = new HashSet<Integer>();
for (int i = 0; i < input.length; i++) {
resultSet.add(input[i]);
}
long endTime1 = new Date().getTime();
System.out.println("Set end time:"+ endTime1);
System.out.println("result of set:" + (endTime1 - startTime1));
System.out.println("number of Set:" + resultSet.size() + "\n");
long startTime2 = new Date().getTime();
System.out.println("Map start time:" + startTime1);
Map<Integer, Integer> resultMap = new HashMap<Integer, Integer>();
for (int i = 0; i < input.length; i++) {
if (!resultMap.containsKey(input[i]))
resultMap.put(input[i], input[i]);
}
long endTime2 = new Date().getTime();
System.out.println("Map end Time:" + endTime2);
System.out.println("result of Map:" + (endTime2 - startTime2));
System.out.println("number of Map:" + resultMap.size());
结果如下:
Set start time:1441960583837
Set end time:1441960583917
result of set:80
number of Set:198652
Map start time:1441960583837
Map end Time:1441960583983
result of Map:66
number of Map:198652
答案 36 :(得分:-1)
请检查一下。它适用于已排序/未排序的数组。复杂度为O(n ^ 2)与冒泡排序相同。 是的,通过第一次排序然后二进制搜索可以进一步提高复杂性。但这很简单,可以处理除负元素(-1)之外的所有情况。这也可以通过使用大整数值而不是-1来改变。
void remove_duplicates(int *A, int N)
{
int i,j;
for (i=1; i<N; i++) {
if (A[i] == -1) continue;
for (j=i+1; j<=N; j++) {
if (A[i] == A[j])
A[j] = -1;
}
}
}
int main() {
int N;
int A[1001];
int i;
printf("Enter N: ");
scanf("%d", &N);
printf("Enter the elements:\n");
for (i=1; i<=N; i++)
scanf("%d", &A[i]);
remove_duplicates(A, N);
for (i=1; i<=N; i++) {
if (A[i] == -1)
continue;
printf("%d ", A[i]);
}
printf("\n");
return 0;
}
答案 37 :(得分:-2)
import java.util.*;
class removeDuplicate{
int [] y ;
public removeDuplicate(int[] array){
y=array;
for(int b=0;b<y.length;b++){
int temp = y[b];
for(int v=0;v<y.length;v++){
if( b!=v && temp==y[v]){
y[v]=0;
}
}
}
}
答案 38 :(得分:-2)
public static int[] removeDuplicates(int[] input){
int j = 0;
int i = 1;
//return if the array length is less than 2
if(input.length < 2){
return input;
}
while(i < input.length){
if(input[i] == input[j]){
i++;
}else{
j = j+1;
input[j] = input[i];
i = i+1;
}
}
int[] output = new int[j+1];
for(int k=0; k<output.length; k++){
output[k] = input[k];
}
return output;
}
public static void main(String a[]){
int[] input1 = {2,3,6,6,8,9,10,10,10,12,12};
int[] output = removeDuplicates(input1);
for(int i:output){
System.out.println(i+" ");
}
}
答案 39 :(得分:-2)
第一个答案是使用hashset设计用于删除重复项,因为Android Killer的答案指出
方法2: -
但是,如果您不允许使用set,则先使用快速排序对其进行排序,然后应用XOR
操作来查找重复项
优化一个
public static void removeDuplicates(int[] arr) {
int[] input = new int[] { 1, 1, 3, 7, 7, 8, 9, 9, 9, 10 };
int current = input[0];
boolean found = false;
for (int i = 0; i < input.length-1; i++) {
if((input[i]^input[i+1])==0){
System.out.println(input[i]);
}
}
}
答案 40 :(得分:-2)
//Remove duplicate from sorted array
public class RemDupFromArray {
static int num;
public static void main(String[] args){
int arr[] = {0,0,2,2,3, 5, 5,7, 7, 7};
for(int i=0;i<arr.length-1;i++){
if(num!=arr[i]){
num=arr[i];
System.out.print(arr[i]);
}
}
}
}
答案 41 :(得分:-2)
public class RemoveDuplicates {
public static void main(String[] args) {
// TODO Auto-generated method stub
int size;
System.out.println("Enter an array size");
Scanner sc=new Scanner(System.in);
size = sc.nextInt();
int arr[] = new int[size];
System.out.println("Enter "+size+" numbers");
for(int i=0;i<size;i++){
arr[i]=sc.nextInt();
}
for(int i=0;i<size;i++){
int count=0;
for(int j=i+1;j<size;j++){
if(arr[i]==arr[j]){
int shiftLeft = j;
for (int k = j+1; k < size; k++, shiftLeft++) {
arr[shiftLeft] = arr[k];
}
size--;
j--;
}
}
}
System.out.println("New Array");
for(int i=0;i<size;i++)
{
System.out.println(arr[i]);
}
}
}
答案 42 :(得分:-2)
希望它有所帮助...
if (!checked)//Condition to add into array {
$scope.selectWeekDays.push(WeekKeys);
} else {
for (i = 0; i <= $scope.selectWeekDays.length; i++) // Loop to check IsExists {
if ($scope.selectWeekDays[i] == WeekKeys)//then if Equals removing by splice {
$scope.selectWeekDays.splice(i, 1);
break;
}
}
}
答案 43 :(得分:-2)
根据需要使用ArrayUtil类。除了删除重复项之外,我还写了一些方法。无需使用任何Collection框架类即可实现此类。
public class ArrayUtils {
/**
* Removes all duplicate elements from an array.
* @param arr Array from which duplicate elements are to be removed.
* @param removeAllDuplicates true if remove all duplicate values, false otherwise
* @return Array of unique elements.
*/
public static int[] removeDuplicate(int[] arr, boolean removeAllDuplicates) {
int size = arr.length;
for (int i = 0; i < size;) {
boolean flag = false;
for (int j = i + 1; j < size;) {
if (arr[i] == arr[j]) {
flag = true;
shrinkArray(arr, j, size);
size--;
} else
j++;
}
if (flag && removeAllDuplicates) {
shrinkArray(arr, i, size);
size--;
} else
i++;
}
int unique[] = new int[size];
for (int i = 0; i < size; i++)
unique[i] = arr[i];
return unique;
}
/**
* Removes duplicate elements from an array.
* @param arr Array from which duplicate elements are to be removed.
* @return Array of unique elements.
*/
public static int[] removeDuplicate(int[] arr) {
return removeDuplicate(arr, false);
}
private static void shrinkArray(int[] arr, int pos, int size) {
for (int i = pos; i < size - 1; i++) {
arr[i] = arr[i + 1];
}
}
/**
* Displays the array.
* @param arr The array to be displayed.
*/
public static void displayArray(int arr[]) {
System.out.println("\n\nThe Array Is:-\n");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
}
/**
* Initializes the array with a given value.
* @param arr The array to be initialized.
* @param withValue The value with which the array is to be initialized.
*/
public static void initializeArray(int[] arr, int withValue) {
for (int i = 0; i < arr.length; i++) {
arr[i] = withValue;
}
}
/**
* Checks whether an element is there in the array.
* @param arr The array in which the element is to be found.
* @param element The element that is to be found.
* @return True if found false otherwise
*/
public static boolean contains(int arr[], int element) {
for(int i=0; i< arr.length; i++) {
if(arr[i] == element)
return true;
}
return false;
}
/**
* Removes a element from an array.
* @param arr The array from which the element is to removed.
* @param element The element to be removed
* @return The size of the array after removing.
*/
public static int removeElement(int[] arr, int element) {
int size = arr.length;
for(int i=0; i< arr.length; i++){
if(arr[i] == element){
shrinkArray(arr, i, arr.length);
size--;
}
}
return size;
}
/**
* Counts unique elements in an array.
* @param arr The required array.
* @return Unique element count.
*/
public static int uniqueElementCount(int arr[]) {
int count = 0;
int uniqueCount=0;
int[] consideredElements = new int[arr.length];
initializeArray(consideredElements, 0);
for(int i=0;i<arr.length;i++) {
int element = arr[i];
for(int j=i+1;j<arr.length; j++){
if(element != arr[j] && !contains(consideredElements, element)){
consideredElements[count++] = element;
}
}
}
for(int i=0;i< consideredElements.length;i++)
if(consideredElements[i]!=0)
uniqueCount++;
return uniqueCount;
}
}
答案 44 :(得分:-2)
我已经将样本用作12个元素,
公共课Remdup_arr {
public static void main(String[] args) {
int a[] = {1,1,2,3,4,4,5,6,7,8,6,8};
for(int p : a)
{
System.out.print(p);
System.out.print("\t");
}
System.out.println();
System.out.println();
remdup(a);
}
private static void remdup(int[] a) {
int length = a.length;
int b[] = new int[11];
int d = 1;
b[0]=a[0];
while(length<13 && length>0)
{
int x = a[length-1];
if(!(contain(b , x)))
{b[d] = a[length-1];
d++;}
length--;
}
for( int z = 0;z<b.length;z++){
System.out.print(b[z]);
System.out.print("\t");}
}
private static boolean contain(int[] b ,int p) {
boolean bool = false;
int len = b.length;
for(int i = 0;i<len;i++)
{
if(p == b[i])
bool = true;
}
return bool;
}
}
输出是: - 1 1 2 3 4 4 5 6 7 8 6 8
1 8 6 7 5 4 3 2 0 0 0
答案 45 :(得分:-2)
public class RemoveDuplicates {
public Integer[] returnUniqueNumbers(Integer[] original,
Integer[] uniqueNumbers) {
int k = 0;
for (int j = original.length - 1; j >= 0; j--) {
boolean present = false;
for (Integer u : uniqueNumbers) {
if (u != null){
if(u.equals(original[j])) {
present = true;
}}
}
if (present == false) {
uniqueNumbers[k] = original[j];
k++;
}
}
return uniqueNumbers;
}
public static void main(String args[]) {
RemoveDuplicates removeDup = new RemoveDuplicates();
Integer[] original = { 10, 20, 40, 30, 50, 40, 30, 20, 10, 50, 50, 50,20,30,10,40 };
Integer[] finalValue = new Integer[original.length + 1];
// method to return unique values
Integer[] unique = removeDup.returnUniqueNumbers(original, finalValue);
// iterate to return unique values
for (Integer u : unique) {
if (u != null) {
System.out.println("unique value : " + u);
}
}
}}
此代码处理包含多个重复项的未排序数组以获取相同的值,并返回唯一元素。
答案 46 :(得分:-3)
public static void main(String[] args) {
int input[] = { 1, 5, 1, 0, -3, 1, -3, 2, 1 };
int j = 0;
int output[] = new int[100];
Arrays.fill(a, 0);
for (int i = 0; i < 9; i++) {
if (output[input[i]] == 0) {
input[j++] = input[i];
output[input[i]]++;
}
}
for (int i = 0; i < j; i++) {
System.out.print(input[i] + " ");
}
}