Java数组替换

huangapple go评论112阅读模式
英文:

Java array replacements

问题

你好,我有3个整数数组。

  • 第一个数组包含信息并且可能有重复项。
  • 第二个数组包含可能出现在第一个数组中的值。
  • 第三个数组包含替换值。
  • 第二个数组和第三个数组的大小相同,且不包含重复项。

我想要检查第二个数组中的元素是否在第一个数组中。
如果第二个数组中的元素在第一个数组中,我希望用第三个数组中的元素来替换它。
替换原始元素的第三个数组中的元素需要与第二个数组中的元素位置相同。
一种实现方式是:

for (int i = 0; i < arr1.length; i++){
  for (int a = 0; a < arr2.length; a++){
    if(arr1[i] == arr2[a]){
      arr1[i] = arr3[a];
      break;
    }
  }
}

我想知道是否有更快或更好的方法来实现这一点。

英文:

Hello I have 3 integer arrays.

  • array #1 has information and contains duplicates.
  • array #2 contains values that might be in array 1.
  • array #3 has replacement values.
  • array #2 and array #3 are the same size and do not contain duplicates.

I want to check if an element from array #2 is in array #1.
If the element is in array #1 I want it replaced with an element from array #3.
The element from #3 that replaces the original needs to have the same location in the array as #2.
A way I could do it is:

for (int i = 0; i&lt;arr1.length; i++){
  for (int a = 0; a&lt;arr2.length; a++){
    if(arr1[i]==arr2[a]){
      arr1[i]=arr3[a];
      break;
    }
  }
}

What I am wondering is if there is a quicker or better way to do this.

答案1

得分: 0

当前算法的时间复杂度为 O(n * m),其中 n 为数组 #1 的长度,m 为数组 #2 的长度。

有一种算法具有更好的时间复杂度。

算法概述:

  1. 对数组 #1 进行排序,同时跟踪元素如何移动以便在最后进行逆向排序(O(n log(n))
  2. 对数组 #2 进行排序,在数组 #3 中相应地排列元素(O(m log(m))
  3. 在数组 #1 中找到所有也在数组 #2 中的元素,并用数组 #3 中相同位置的元素替换它们(O(n + m)
  4. 利用步骤 1 的跟踪信息对数组 #1 进行非排序操作(O(n)

总体而言,我们得到 O(n log(n) + m log(m) + n + m + n) ∈ O(n log(n) + m log(m))

如果数组 #2 和 #3 也必须被还原成原来的顺序,可以在排序过程中同时跟踪并在排序后对它们进行还原操作,因为还原操作仅需要“仅仅” O(m) 的时间。

英文:

The current algorithm has time complexity O(n * m) with n = length of array #1 and m = length of array #2.

There is an algorithm that has a better time complexity.

Sketch of algorithm:

  1. Sort array #1, keep track of how elements move to reverse sorting at the end (O(n log(n)))
  2. Sort array #2, permutate elements in array #3 accordingly (O(m log(m)))
  3. Find all elements in array #1, that are also in array #2 and replace them with the elements at same position in array #3 (O(n + m))
  4. Un-Sort array #1 utilizing the tracking from 1. (O(n))

In total, we get O(n log(n) + m log(m) + n + m + n) ∈
O(n log(n) + m log(m))

If arrays #2 and #3 must be un-shuffled aswell, one can either copy those arrays or keep track during sorting aswell and un-shuffle them aswell since un-shuffling takes "only" O(m).

答案2

得分: 0

利用Set来判断数组array1中的元素是否存在。遍历array2,如果集合中包含其元素,则从array3中复制过来:

Set<T> set = Arrays.stream(arr1).collect(toSet()); // O(n)
for (int i = 0; i < arr2.length; i++){         // O(m)
    if (set.contains(arr2[i])) {
      arr2[i] = arr3[i];
    }
}

假设array1的大小为n,array2的大小为m...
对集合的所有操作都是常数时间(即O(1)),因此构建集合的成本为O(n)。
遍历array2的成本为O(m) - 集合查找的成本为O(1)。

总成本为O(n + m) - 即"线性"。

你目前的成本为O(n * m) - 即"二次方"。


注意:你没有指定数组的类型。如果它们是原始类型(例如int),构建集合需要进行轻微的增强,即添加一个boxed()方法的调用,因为Java不支持原始类型的集合:

Arrays.stream(arr1).boxed().collect(toSet())
英文:

Use a Set of the elements in array1 to determine if an element is in it.
Loop over array2 and copy over forom array3 if the set contains its element:

Set&lt;T&gt; set = Arrays.stream(arr1).collect(toSet()); // O(n)
for (int i = 0; i &lt; arr2.length; i++){         // O(m)
    if (set.contains(arr2[i])) {
      arr2[i] = arr3[i];
    }
}

Given array1 is size n and array2 is size m...
All operations on a Set are constant time (ie O(1)), so building the set cost O(n).
Looping over array2 is O(m) - the set lookup cost is O(1)

Overall cost O(n + m) - ie "linear".

Your current cost is O(n * m) - ie "quadratic".


Note: You have not specified the type of the arrays. If they are primitive (eg int), building the set needs the minor enhancement of adding a call to boxed(), because java does not support collections of primitives:

Arrays.stream(arr1).boxed().collect(toSet())

答案3

得分: 0

Array #2和Array #3不适合用作HashMap的替代。

Map<T, T> replacements = new HashMap<>();
for (int i = 0; i < arr2.length; i++) {
  replacements.put(arr2[i], arr3[i]);
}
for (int i = 0; i < arr1.length; i++) {
  if (replacements.containsKey(arr1[i])) {
    arr1[i] = replacements.get(arr1[i]);
  }
}

这将具有大约O(n)的时间复杂度。

英文:

Array #2 and Array #3 are a bad replacement for a HashMap.

Map&lt;T, T&gt; replacements = new HashMap&lt;&gt;();
for (int i = 0; i &lt; arr2.length; i++) {
  replacements.put(arr2[i], arr3[i]);
}
for (int i = 0; i &lt; arr1.length; i++) {
  if (replacements.containsKey(arr1[i]) {
    arr1[i] = replacements.get(arr1[i]);
  }
}

This will have approximately O(n) time complexity.

huangapple
  • 本文由 发表于 2020年8月27日 05:36:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/63606062.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定