這是小川的第393次更新,第427篇原創
01 看題和准備
今天介紹的是LeetCode算法題中Easy級別的第258題(順位題號是1122)。給定兩個數組arr1
和arr2
,arr2
中的元素是不同的,arr2
中的所有元素也在arr1
中。
對arr1
的元素進行排序,使arr1
中元素的相對順序與arr2
中的相對順序相同。未出現在arr2
中的元素應按升序放置在arr1
的末尾。
例如:
輸入:arr1 = [2,3,1,3,2,4,6,7,9,2,19],arr2 = [2,1,4,3,9,6]
輸出:[2,2,2,1,4,3,3,9,6,7,19]
注意:
-
arr1.length,arr2.length <= 1000
-
0 <= arr1 [i],arr2 [i] <= 1000
-
每個arr2[i]都是不同的。
-
每個arr2[i]都在arr1中。
02 第一種解法
題目的意思是對arr1
分兩部分排序,前部分的順序要和arr2
中元素的順序一樣,剩余不是arr2
中的元素,要按照增序排列。
直接翻譯題目即可,利用一個HashMap
,將arr2
中的元素值作為key
,因為arr2
中的元素不會重復出現,將value
設統一值0,接着遍歷arr1
,如果當前元素在HashMap
中存在,就計數出現的次數,賦值到value
上,反之就將其存入ArrayList
中。遍歷arr2
,將對應的元素寫入到結果數組中,出現幾次就寫入幾次。最后,如果ArrayList
中有剩余未處理的數據,就將其排序,再寫入到結果數組中去。
此解法的時間復雜度是O(N)
,最壞的情況可能到O(N^2)
,空間復雜度是O(N)
。
public int[] relativeSortArray(int[] arr1, int[] arr2) {
int[] result = new int[arr1.length];
List<Integer> left = new ArrayList<Integer>();
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int num : arr2) {
map.put(num, 0);
}
for (int num : arr1) {
if (map.containsKey(num)) {
map.put(num, map.getOrDefault(num, 0)+1);
} else {
left.add(num);
}
}
int index = 0, i = 0;
while (i<result.length && index<arr2.length) {
int count = map.get(arr2[index]);
while (count > 0) {
result[i++] = arr2[index];
count--;
}
index++;
}
if (left.size() > 0) {
Collections.sort(left);
for (int j=0; j<left.size(); j++) {
result[i++] = left.get(j);
}
}
return result;
}
03 第二種解法
我們也可以使用計數排序算法,簡化計算步驟。
此解法的時間復雜度是O(N)
,空間復雜度是O(N)
。
public int[] relativeSortArray2(int[] arr1, int[] arr2) {
int[] count = new int[1001];
// 遍歷arr1中的元素並計數
for (int num : arr1) {
count[num]++;
}
int index = 0;
// 處理arr2中的元素
for (int num : arr2) {
while (count[num] > 0) {
arr1[index++] = num;
count[num]--;
}
}
// 處理剩余不是arr2中的元素
for (int i=0; i<count.length; i++) {
while (count[i] > 0) {
arr1[index++] = i;
count[i]--;
}
}
return arr1;
}
04 第三種解法
我們也可以直接重寫排序方法。
此解法的時間復雜度是O(N log(N))
,最壞的情況可能到O(N^2 log(N))
,空間復雜度是O(N)
。
public int[] relativeSortArray3(int[] arr1, int[] arr2) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i=0; i<arr2.length; i++) {
map.put(arr2[i], i);
}
// 為方便后面排序,將arr1轉成Integer類型的數組
Integer[] sort = new Integer[arr1.length];
for (int i=0; i<sort.length; i++) {
sort[i] = arr1[i];
}
Arrays.sort(sort, new Comparator<Integer>() {
@Override
public int compare(Integer a, Integer b) {
// a和b都不是arr2中的元素
if (!map.containsKey(a) && !map.containsKey(b)) {
return a - b;
}
// 不能直接使用map.get(key),會報空指針
return map.getOrDefault(a, arr1.length) -
map.getOrDefault(b, arr1.length);
}
});
// 將排序后的sort數組元素回寫到arr1中去
for (int i=0; i<arr1.length; i++) {
arr1[i] = sort[i];
}
return arr1;
}
05 小結
算法專題目前已連續日更超過八個月,算法題文章264+篇,公眾號對話框回復【數據結構與算法】、【算法】、【數據結構】中的任一關鍵詞,獲取系列文章合集。
以上就是全部內容,如果大家有什么好的解法思路、建議或者其他問題,可以下方留言交流,點贊、留言、轉發就是對我最大的回報和支持!