堆 heap, 准备博客参考
那个概率越乘越小,但是这个路径是累加的效果,到达当前节点目前最大,不代表它就是最大的路径。
但是,如果当前节点是距离最小的,它一定就是最小了。
也就是能应用迪特斯特拉算法思想,其实是贪心思想的,面临选择的时候,选择它,它一定是最佳的。
如果是求最短路径
var maxSum = function(nums1, nums2) {
let n12 = [...new Set([...nums1.concat(nums2)])];
console.log('n12: ',n12)
let n12l = n12.length;
let s1 = nums1[0],
s2 = nums2[0],
r1 = nums1[nums1.length-1],
r2 = nums2[nums2.length-1],
s1Index = n12.indexOf(s1),
s2Index = n12.indexOf(s2),
r1Index = n12.indexOf(r1),
r2Index = n12.indexOf(r2);
let e1 = [],
e2 = [];
nums1.forEach((n1, i)=>{
if(nums1[i+1] !== undefined)
e1.push([n1, nums1[i+1]]);
})
nums2.forEach((n1, i)=>{
if(nums2[i+1] !== undefined)
e1.push([n1, nums2[i+1]])
})
let e12 = e1.concat(e2);
let len = n12.length;
let nl = n12.length;
let paths = [];
while(nl--){
paths[nl] = []
}
// for(let i=0;i< n12.length; i++){
// paths.set(n12[i], [])
// }
let edges = [];
let succProb = [];
e12.forEach(([s, e])=>{
let sI = n12.indexOf(s),
eI = n12.indexOf(e),
w = s+e;
// s-e 的权重 w
paths[sI].push([eI, w]);
paths[eI].push([sI, w]);
edges.push([sI, eI])
succProb.push(w)
})
// let succ = [];
// // dfs
// let st = [nums1[0]];
// let map = new Map();
// while(st.length){
// let n = st.shift();
// if(map.get(n)) continue;
// map.set(n, true)
// let ps = paths[n];
// for(let i=0; i<ps.length; i++){
// let n1 = ps[i];
// if(map.get(n1)) continue;
// succ.push(n+n1)
// }
// }
let mod = 10**9 + 7;
// const getCount = (s, e)=>{
// let dp = new Array(n12l).fill(0);
// dp[s] = 10**7;
// while(true){
// let k = false;
// for(let j=0; j<edges.length; j++){
// if(dp[edges[j][0]] + succProb[j] > dp[edges[j][1]]){
// dp[edges[j][1]] = dp[edges[j][0]] + succProb[j];
// k = true;
// }
// if (dp[edges[j][1]] + succProb[j] > dp[edges[j][0]]) {
// dp[edges[j][0]] = dp[edges[j][1]] + succProb[j];
// k = true;
// }
// }
// if(!k) break;
// }
// return dp[e]
// }
// Dijkstra每次选距离最小的点,是一种贪心决策。从源点出发时,也必须挑选最短点。eg:d(0-c)>d(0-a)+d(a-c),所以初始c点时不能进入S集合的。
const getCount = (s, e)=>{
let v = new Array(n12l).fill(false);
let stack = [[s, 0]];
while(stack.length){
console.log('stack: ',JSON.stringify(stack))
let [n, weight] = stack.shift();
if(v[n]) continue
v[n] = true;
if(n===e) return weight;
let ps = paths[n];
for (let i = 0; i < ps.length; i++) {
let [nn, nw] = ps[i];
if(v[nn]) continue;
let f = 0;
if(n!==s){
// 这个权限是2点的和,会重复累加,所以要减去
f = n12[n]
}
stack.push([nn, (weight+nw-f)%mod]);
// 这个应该是从小到大,虽然从大到小测试用例也一样,纯属巧合
stack.sort((a, b)=>a[1]-b[1])
}
}
}
let res1 = 0,
res2 = 0,
res3 = 0,
res4 = 0;
res1 = getCount(s1Index, r1Index);
res2 = getCount(s1Index, r2Index);
res3 = getCount(s2Index, r1Index);
res4 = getCount(s2Index, r2Index);
// 2数组之间可能没有交集
// res1 = res1 === undefined? 0: res1;
// res2 = res2 === undefined? 0: res2;
// res3 = res3 === undefined? 0: res3;
// res4 = res4 === undefined? 0: res4;
console.log(res1, res2, res3, res4)
return Math.max(res1, res2, res3, res4)
};
let nums1 = [1,4,5,8,9,11,19], nums2 = [2,3,4,11,12];
console.log(maxSum(nums1, nums2))
// 最小距离
// console.log(res1, res2, res3, res4)
// 35 28 39 32
下面这2个实现堆都是从数组索引0开始,