两个有序数组,将其合并成一个有序数组
思路1,先合并,然后排序;不优雅!
merge (arr1, arr2) {return arr1.concat(arr2).sort((a, b) => a - b);}
双指针的写法
思路是新建一个长度为和的新数组,指针m指向数组1的最后,n指向数组2的最后,p表示新数组的最后,如果m > n,则m比数组2的所有都大,把m的值付给新数组的p的位置,并p-1;反之则n比数组1的值都大,放到p的位置
merge (arr1, arr2) {let len1 = arr1.length,len2 = arr2.length,m = len1 - 1,n = len2 - 1;if (m < 0 || n < 0) { // 如果有一个数组为空,展开后直接返回return [...arr1, ...arr2];}if (arr1[0] > arr2[n]) { // 如果arr1的第一个比arr2的最后一个还大,concat后返回return arr2.concat(arr1);}if (arr2[0] > arr1[m]) { // 同上 处理特殊情况 非必须return arr1.concat(arr2);}let arr = arr1.concat(new Array(len2).fill(0)), // 新建一个数组,将arr1放进去后补0到两数组和的长度p = arr.length - 1; // p代表返回数组的最后一个while (n >= 0) { // n代表目标数组的指针if (arr[m] > arr2[n]) { // 如果n小于arr的m,把m放到p的位置arr[p] = arr[m];m--;} else { // n大于或等于m 把n放到最后面arr[p] = arr2[n];n--;}p--;}return arr;}
可优化的地方是,while跳出循环的条件为两个数组其一的指针走到了头(小于0),若n < 0,则数组2中的数值都在arr中找到了位置,如果m < 0,那么说明数组2中剩余的所有值都比arr中的值小,则把arr剪切n + 1的长度,并把arr2中的剩余值拼接上
function merge (arr, arr2, arr1) {let len1 = arr1.length,len2 = arr2.length,m = len1 - 1,n = len2 - 1;let arr = arr1.concat(new Array(len2).fill(0)), // 新建一个数组,将arr1放进去后补0到两数组和的长度p = arr.length - 1; // p代表返回数组的最后一个while(m >= 0 && n >= 0) {// 注意--符号在后面,表示先进行计算再减1,这种缩写缩短了代码arr[p--] = arr[m] > arr2[n] ? arr[m--] : arr2[n--];}arr.splice(0, n + 1, ...arr2.slice(0, n + 1)); // 处理m < 0时 循环跳出,说明arr2剩余元素都比arr中的小了,所以直接剪裁拼接就ok了return arr;}
