題目:小特最近要開學了,他打算入學前買一臺筆記本電腦。小特看中了戴爾和微軟的超薄本,他打算 先找兩個品牌價格最接近的型號比較一下性能。他已經在電商網站上找到了兩個品牌各個型號的 價格, 請你寫程序幫助他找到價格差最小的兩款!
輸入:
第一行第 1 個數爲 戴爾電腦型號的數量 n,接着有 n 個數表示每個型號的價格。
第二行第 1 個數爲 微軟電腦型號的數量 m,接着有m個數表示每個型號的價格。 每行數字用空格分割。
電腦價格爲大於 0 小於 2147483647 的整數
輸出:
輸出價格差最小的兩款電腦的下標,用空格分開
樣例輸入:
5 3998 4698 6698 8898 7798
4 2068 5688 10198 5288
樣例輸出:
1 3(價格最接近的是 4698 和 5288,下標分別爲 1 和 3)
提示:
暴力 O(mn)的方法會視爲錯誤
思路:二路歸併
解法:
function generateNumbers(n){
let arr = []
for (let i = 0; i < n; i++) {
let num = parseInt(Math.random() * 100000000)
arr.push(num)
}
return arr
}
function cmpPrice(a, b) {
return a.price - b.price
}
// 查找arr1 和 arr2 最相近的兩個數的下標
function findNearest(arr1, arr2) {
let x = [], y = []
for (let i = 0; i < arr1.length; i++) {
x.push({price:arr1[i], index:i})
}
for (let i = 0; i < arr2.length; i++) {
y.push({price:arr2[i], index:i})
}
// 按價格排序 複雜度O(mlgm)+O(nlgn)
x.sort(cmpPrice)
y.sort(cmpPrice)
let a = x.shift()
let b = y.shift()
let delta = 2147483647 // 歷史最小差值
let idx1 = 0 // 歷史最小差值對應的arr1.index
let idx2 = 0 // 歷史最小差值對應的arr2.index
// 兩路歸併, 複雜度O(m+n)
while (true) {
let d = Math.abs(a.price - b.price)
if (d == 0) { // 兩個值相等,這是最小的差值了,直接返回結果
return [a.index, b.index]
}
// 如果當前的差值比歷史最小差值還小,那麼就更新下
if (d < delta) {
idx1 = a.index
idx2 = b.index
delta = d
}
// 兩個隊列都空了,返回
if (x.length == 0 && y.length == 0) {
return [idx1, idx2]
}
if (x.length == 0) { // x空了,那麼從y取一個
b = y.shift()
}else if (y.length == 0) { // y空了,那麼從x取一個
a = x.shift()
}else if (a.price < b.price) { // 誰小從誰那取
a = x.shift()
}else {
b = y.shift()
}
}
// 總複雜度O(mlgm)+O(nlgn) + O(m+n) 即 O(mlgm) 假設m>n
}
// 查找arr1 和 arr2 最相近的兩個數的下標
// 窮舉解法,用來驗證答案
function exhaustive(arr1, arr2) {
let delta = 2147483647
let idx1 = 0
let idx2 = 0
for (let i = 0; i < arr1.length; i++) {
for (let j = 0; j < arr2.length; j++) {
let d = Math.abs(arr1[i] - arr2[j])
if (d < delta) {
idx1 = i
idx2 = j
delta = d
}
}
}
return [idx1, idx2]
}
function solve() {
let arr1 = generateNumbers(10)
let arr2 = generateNumbers(15)
console.log("arr1 =",arr1)
console.log("arr2 =",arr2)
let result = findNearest(arr1, arr2)
console.log('當前算法結果:',result, '左:',arr1[result[0]], '右:', arr2[result[1]], '差值', Math.abs(arr1[result[0]]-arr2[result[1]]))
let result2 = exhaustive(arr1, arr2)
console.log('窮舉算法結果:',result2, '左:',arr1[result2[0]], '右:', arr2[result2[1]], '差值', Math.abs(arr1[result2[0]]-arr2[result2[1]]))
}
solve()