New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
第 2 题:合并二维有序数组成一维有序数组,归并排序的思路 #8
Comments
function mergeSort(arr) {
const len = arr.length
// 处理边界情况
if(len <= 1) {
return arr[0]
}
// 计算分割点
const mid = Math.floor(len / 2)
// 递归分割左子数组,然后合并为有序数组
const leftArr = mergeSort(arr.slice(0, mid))
// 递归分割右子数组,然后合并为有序数组
const rightArr = mergeSort(arr.slice(mid,len))
// 合并左右两个有序数组
arr = mergeArr(leftArr, rightArr)
// 返回合并后的结果
return arr
}
function mergeArr(arr1, arr2) {
// 初始化两个指针,分别指向 arr1 和 arr2
let i = 0, j = 0
// 初始化结果数组
const res = []
// 缓存arr1的长度
const len1 = arr1.length
// 缓存arr2的长度
const len2 = arr2.length
// 合并两个子数组
while(i < len1 && j < len2) {
if(arr1[i] < arr2[j]) {
res.push(arr1[i])
i++
} else {
res.push(arr2[j])
j++
}
}
// 若其中一个子数组首先被合并完全,则直接拼接另一个子数组的剩余部分
if(i<len1) {
return res.concat(arr1.slice(i))
} else {
return res.concat(arr2.slice(j))
}
}
var arr=[[1,2,4],[2,3,7],[3,5,7],[4,5,8]]
mergeArr(arr) |
/**
* 解题思路:
* 双指针 从头到尾比较 两个数组的第一个值,根据值的大小依次插入到新的数组中
* 空间复杂度:O(m + n)
* 时间复杂度:O(m + n)
* @param {Array} arr1
* @param {Array} arr2
*/
function merge(arr1, arr2){
var result=[];
while(arr1.length>0 && arr2.length>0){
if(arr1[0]<arr2[0]){
/*shift()方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。*/
result.push(arr1.shift());
}else{
result.push(arr2.shift());
}
}
return result.concat(arr1).concat(arr2);
}
function mergeSort(arr){
let lengthArr = arr.length;
if(lengthArr === 0){
return [];
}
while(arr.length > 1){
let arrayItem1 = arr.shift();
let arrayItem2 = arr.shift();
let mergeArr = merge(arrayItem1, arrayItem2);
arr.push(mergeArr);
}
return arr[0];
}
let arr1 = [[1,2,3],[4,5,6],[7,8,9],[1,2,3],[4,5,6]];
let arr2 = [[1,4,6],[7,8,10],[2,6,9],[3,7,13],[1,5,12]];
mergeSort(arr1);
mergeSort(arr2); |
// 方法1:使用concat
const flatten1 = (arr) => {
while (arr.some((item) => Array.isArray(item))) {
arr = [].concat(...arr);
}
return arr;
};
// 方法2:使用reduce
const flatten2 = (arr) =>
arr.reduce(
(acc, cur) =>
Array.isArray(cur) ? [...acc, ...flatten2(cur)] : [...acc, cur],
[]
);
// test
var arr = [1, 2, [3, 4, [5, 6], 7, 8]];
console.log(flatten1(arr));
console.log(flatten2(arr)); |
function sortFlatArray (arr) {
function flatArray (arr) {
const newArr = arr.flat()
return newArr.some(item => Array.isArray(item))? flatArray(newArr) : newArr
}
if (!arr || !arr.length) {
return []
}
let flattenedArr = flatArray(arr)
return flattenedArr.sort((a, b) => {
return a - b
})
} |
这个是不是少了排序的功能,只做了将多维数组转换为一维数组 |
我是放在前面了呀,不知道你说的意思是要? |
看错了,不好意思。 |
const mergeSort = (arr1: number[], arr2: number[]) => {
const len1 = arr1.length,
len2 = arr2.length;
let i = 0,
j = 0,
arr = [];
if (len1 === 0) return arr2;
if (len2 === 0) return arr1;
while (i < len1 || j < len2) {
if (arr1[i] <= arr2[j] || j === len2) {
arr.push(arr1[i]);
i++;
} else {
arr.push(arr2[j]);
j++;
}
}
return arr;
};
//test
const arr1 = [1, 2, 3];
const arr2 = [2, 3, 4];
const arr3 = [1, 5, 6];
const arr = [arr1, arr2, arr3];
const res = arr.reduce((pre, cur) => mergeSort(pre, cur), []);
console.log(res); |
|
function merge(left: number[], right: number[]): number[] {
let result: number[] = [];
while (left.length > 0 && right.length > 0) {
if (left[0] <= right[0]) {
result.push(left.shift());
} else {
result.push(right.shift());
}
}
while (left.length > 0) {
result.push(left.shift());
}
while (right.length > 0) {
result.push(right.shift());
}
return result;
} |
function merge (arr) {
if (arr.length === 0) {
return []
}
// 扁平化数组
let newArr = arr.flat(Infinity)
// 排序
return newArr.sort(($1, $2) => $1 - $2)
}
merge([[1,2,3],[4,5,6],[7,8,9],[1,2,3],[4,5,6]])
|
let a = [1, 2, [3, 4, [5, 6]]]
let arr = []
function change(a) {
a.forEach(item => {
if (typeof item == 'object') {
change(item)
} else {
arr.push(item)
}
})
}
change(a)
arr = arr.sort() |
let tt = [
[1,2,3,4,5],
[8,9,10],
[6,8,9],
]
function sort(arr) {
if (!(arr instanceof Array)) {
return
}
// 这里还应该有一个非 二维数组的判断。
return arr.flat().sort((a, b) => {
if (typeof(a) !== 'number' || typeof(a) !== 'bigint') {
throw Error('Number need')
}
if (typeof(b) !== 'number' || typeof(b) !== 'bigint') {
throw Error('Number need')
}
return a - b
})
}
console.log(sort(tt)) |
|
function flattenAndSort(arr = []) { // 方法二: 借助reduce方法 // 方法三: 直接使用数组的API flat, 传入Infinity值 // 排序一个数组,我们先把数组从中间分成前后两部分,然后对前后两部分分别排序,再将排好序的两部分合并在一起,这样整个数组就都有序了。 return mergeSort(flatten(arr)); let arr = [ |
const mergeSort = (arr) => |
|
type flatReturn = Array; export const flat = ( a: Array ): flatReturn => {
} |
|
// 思路: 首先扁平化数组,再进行排序, 扁平化可以通过数组的tostring 和字符串split 方法 console.log(mySort(arr)) |
|
/**
* [mergeArrAndSort description]
* @param {Array} arr [二维数组]
* @param {Array} resArr [结果数组]
* @return {[type]} [description]
*/
function mergeArrAndSort(arr = [], resArr = []) {
for(let v of arr) {
if (Array.isArray(v)) {
mergeArrAndSort(v, resArr);
} else {
resArr.push(v);
}
}
console.log(resArr.sort());
return resArr.sort();
}
mergeArrAndSort([[1, 2], [2, 3], [4, 5, 7]]);
mergeArrAndSort([[1, 2], [2, 3], [4, 5, [6, 7, 8]]]); |
|
没有添加任何判断只是为了实现需求 不知道自己写的对不对 看上面大家都写了好多 是不是我理解错了啊
let arr = [
[1, 4, 6],
[7, 8, 10],
[2, 6, 9],
[3, 7, 13],
[1, 5, 12]
];
//[[1,2,3],[4,5,6],[7,8,9],[1,2,3],[4,5,6]]
function func(arr) {
return Array.from(new Set(arr.flat(1))).sort((a, b) => a - b)
}
//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13]
// [1, 2, 3, 4, 5, 6, 7, 8, 9] |
const arrayA = [1,3,5,7,9];
const arrayB = [111,221,331,441,551,661,771,881,991];
const arrayC = [2,4,5,6,8,10];
const arrayD = [11,22,33,44,55,66,77,88,99];
const matrix = [arrayA, arrayB, arrayC, arrayD]
function mergeArray(arrayA, arrayB) {
let i = j = 0;
const sortedArray = [];
while(i < arrayA.length && j < arrayB.length) {
if (arrayA[i] < arrayB[j]) {
sortedArray.push(arrayA[i]);
i += 1;
continue
}
sortedArray.push(arrayB[j]);
j += 1;
}
sortedArray.push(...arrayA.slice(i));
sortedArray.push(...arrayB.slice(j));
return sortedArray;
}
function flatMatrix(matrix) {
return matrix.reduce((arrayA, arrayB) => {
return mergeArray(arrayA, arrayB);
});
}
console.log(flatMatrix(matrix)); |
function mergeArray(arr){ |
|
这个题目其实提出了两个问题,一个是数组的展平,一个是归并排序的实现。 利用 Generator 函数返回 Iterator 的特性,递归调用自己,然后使用扩展运算符将 Iterator 展开变成数组,归并排序直接使用标准实现就可以了。 function mergeSort (arr) {
const len = arr.length;
if (len < 2) {
return arr;
}
const middle = Math.floor(len / 2),
left = arr.slice(0, middle),
right = arr.slice(middle);
return merge(mergeSort(left), mergeSort(right));
}
function merge (left, right) {
const result = [];
while (left.length && right.length) {
if (left[0] <= right[0]) {
result.push(left.shift());
} else {
result.push(right.shift());
}
}
while (left.length) {
result.push(left.shift());
}
while (right.length) {
result.push(right.shift());
}
return result;
}
function* flat (arr) {
if (Array.isArray(arr)) {
for (let i = 0; i < arr.length; i++) {
yield* flat(arr[i]);
}
} else {
yield arr;
}
}
function mergeSortFlatten () {
return mergeSort([...flat([...arguments])]);
}
let arr1 = [[1,2,3],[4,5,6],[7,8,9],[1,2,3],[4,5,6]];
let arr2 = [[1,4,6],[7,8,10],[2,6,9],[3,7,13],[1,5,12]];
mergeSortFlatten (arr1, arr2);
// [1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 10, 12, 13] |
let arr = [[1,20,30],[4,5,6],[-1,9,89,90]] // 我们的测试数组
let len = arr.length
let res = arr[0]
let index = 1
while(index < len) res = merge(res, arr[index++])
console.log(res)
// 利用数组元素已经排好序的事实
function merge (left, right) {
let res = []
while(left.length && right.length) {
if(left[0] < right[0]) res.push(left.shift())
else res.push(right.shift())
}
return res.concat(left, right)
} |
|
const merge = (arr1,arr2) => {
const arr = [];
while(arr1.length>1 && arr2.length>1){
if(arr1[0] < arr2[0]){
arr.push(arr1.shift())
}else{
arr.push(arr2.shift())
}
}
return arr.concat(arr2).concat(arr1)
}
const mergeArr = (data) => {
let arr = [];
while(data.length >= 1){
arr = merge(arr,data.shift())
}
return arr.sort((a,b)=>a-b);
}
|
const mergeArr = (arr) => {
return arr.reduce((_memo,curr)=>{ return [..._memo,...curr].sort((a,b)=>a-b)},[])
}
mergeArr([[1,3],[2,4]]) |
function sortArr(arr){
function flatArr(arr){
return arr.flat()
}
let flatArray = flatArr(arr)
return flatArray.sort((a,b)=>a-b)
}
let arr=[[1,10,4],[2,3,7],[3,5,7],[4,5,8]]
console.log(sortArr(arr)) |
/**
* 合并二维有序数组成一维有序数组,归并排序的思路[[1,2,3],[4,5,6,7,8,9]]*/
//[1,3,5,7,9],[2,4,6,7,8,9]
// 归并两个数组
function mergeArr(arr1,arr2){
let result = []
while (arr1.length||arr2.length) {
if(arr1.length==0||arr2.length==0) {
result.push(...arr2,...arr1)
arr1=[]
arr2=[]
} else
result.push(arr1[0]>arr2[0]?arr2.shift():arr1.shift())
}
console.log(result)
return result
}
// mergeArr([1,3,5,7,9],[2,4,6,7,8,9])
function mergeArr2(arr) {
let result = arr.shift()
while (arr.length) {
result = mergeArr(result, arr.shift())
}
console.log(result)
return result
}
mergeArr2([[1,2,3],[4,5,6,7,8,9],[4,7,9,10]]) |
function mergeArr(arr){
let n = arr.length;
if(n <= 1) return arr[0];
let m = Math.floor(n / 2)
let left = mergeArr(arr.slice(0, m))
let right = mergeArr(arr.slice(m))
arr = merge(left, right)
return arr
}
function merge(left, right) {
let i = 0
let j = 0
let len1 = left.length
let len2 = right.length
let res = []
while(i < len1 && j < len2){
res[i + j] = left[i] < right[j] ? left[i++] : right[j++]
}
while(i < len1){
res[i + j] = left[i++]
}
while(j < len2){
res[i + j] = right[j++]
}
return res
} |
|
硬核 |
|
const sortFunc = (left, right) => { |
如果碰到多维数据就废了,比如: let arr = [1, 2, [3, 4, [5, 6, 7, 3, [10, 12]], 7, 8]]; 当然你这个解题对二维数组是完全可以解决的,但我觉得应该尽量想的周全一点。 |
`let arrs = [[1, 2, [10, 12], 3], [5, 6, 8], [9, 4, 7]] let newArr = [] formatArr(arrs) console.log(newArr.sort((a,b)=>a-b))` |
|
const fn = (arr) => [].concat(...arr).sort();
console.log(fn([[1, 3, 5], [2, 4, 6], [3, 5, 7]])); //=> [1, 2, 3, 3, 4, 5, 5, 6, 7] |
let ary = [
[1, 2, 3, 3],
[4, 5, 6, 6],
[7, 8, 9, 9],
[1, 2, 3, 1],
[4, 5, 6, 6]
]
// const arr1 = [1, 2, 4, 6, 9, 12, 15, 10, 3, 7, 8]
function mergeSort(ary) {
const len = ary.length
if (len < 2) {
return ary
}
const mid = Math.floor(len / 2)
const left = ary.slice(0, mid)
const right = ary.slice(mid)
return merge(mergeSort(left), mergeSort(right))
}
function merge(ary1, ary2) {
const result = []
while (ary1.length && ary2.length) {
if (ary1[0] <= ary2[0]) {
result.push(ary1.shift())
} else {
result.push(ary2.shift())
}
}
return result.concat(ary1).concat(ary2)
}
function flatAry(ary) {
return Array.isArray(ary) ?
ary.reduce((acc, cur) => [...acc, ...flatAry(cur)], []) : [ary]
}
// console.log(flatAry(ary))
console.log(mergeSort(flatAry(ary)))
` |
/**
* 合并两个一维有序数组
* 双指针法
* @param {Array} arr1
* @param {Array} arr2
* @returns
*/
function merge(arr1, arr2) {
let result = [];
let i = 0;
let j = 0;
for (
let index = 0, length = arr1.length + arr2.length;
index < length;
index++
) {
if (arr1[i] && arr2[j]) {
if (arr1[i] <= arr2[j]) {
result.push(arr1[i]);
i++;
} else {
result.push(arr2[j]);
j++;
}
continue;
}
if (arr1[i]) {
result = [...result, ...arr1.slice(i)];
break;
}
if (arr2[j]) {
result = [...result, ...arr2.slice(j)];
break;
}
}
return result;
}
// 遍历二维数组,依次合并
function mergeSort(arr) {
if (!arr.length) return [];
let result = [];
for (let i = 0; i < arr.length; i++) {
result = merge(result, arr[i]);
}
console.log(result);
}
// 测试
const arr = [
[1, 4, 6],
[7, 8, 10],
[2, 6, 9],
[3, 7, 13],
[1, 5, 12],
];
mergeSort(arr); |
/**
* 合并两个一维有序数组
* 首元素比较法
* @param {Array} arr1
* @param {Array} arr2
* @returns {Array}
*/
function merge(arr1, arr2) {
const [a, b] = [[...arr1], [...arr2]]; // 浅拷贝数组
const result = [];
while (a[0] && b[0]) {
result.push(a[0] <= b[0] ? a.shift() : b.shift()); // 比较2个数组的第1个元素,谁小谁出列
}
return [...result, ...a, ...b];
}
// 遍历二维数组,依次合并
function mergeSort(arr) {
if (!arr.length) return [];
let result = [];
for (let i = 0; i < arr.length; i++) {
result = merge(result, arr[i]);
}
console.log(result);
}
// 测试
const arr = [
[1, 4, 6],
[7, 8, 10],
[2, 6, 9],
[3, 7, 13],
[1, 5, 12],
];
mergeSort(arr); |
|
简单来说,应该是归并排序少去从中分割的逻辑部分,直接进行合并排序的操作 let arr = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[1, 2, 3],
[4, 5, 6],
];
console.log( merge(arr) );
function merge(arr) {
let temp = [];
for (let i = 0; i < arr.length; i++) {
temp = sort(temp, arr[i]);
}
return temp;
}
function sort(a, b) {
let temp = [];
while (a.length && b.length) {
temp.push(a[0] < b[0] ? a.shift() : b.shift());
}
return temp.concat(a, b);
} |
function flattenDeep(array, result = []) {
array.forEach(item => {
if (item.length) {
flattenDeep(item, result);
} else {
result.push(item);
}
})
return result;
}
// 测试用例
var arr = [1, 2, [3, 4, [5, 6, 7, 3, [10, 12]], 7, 8]];
var num = flattenDeep(arr).sort((a, b) => a - b);
// => [1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 10, 12] |
function oneArry(arr){ |
异步解决方案
|
|
const arr1 = [[5,9,6],[5,9,6,],[8,9,6]]; |
题目应该不是要直接把数组展平然后排序,那样的话我直接:function sortTest(nums) {
return nums.flat().sort((a, b) => a - b)
} 题目说是归并排序的思路,归并排序分为归和并两个过程
题目中给出的是多个有序数组,需要合并为一个有序数组,因此不需要“归”,直接“并” function sort(nums) {
let leftNums = nums[0]
let res
for (let i = 1; i < nums.length; i++) {
res = []
let rightNums = nums[i]
let left = 0
let right = 0
while (left < leftNums.length && right < rightNums.length) {
if (leftNums[left] < rightNums[right]) {
res.push(leftNums[left])
left++
} else {
res.push(rightNums[right])
right++
}
}
if (left < leftNums.length) {
res.push(...leftNums.slice(left))
}
if (right < rightNums.length) {
res.push(...rightNums.slice(right))
}
leftNums = res.slice()
}
return res
} |
const mergeList = (...list) => { |
欢迎在下方发表您的优质见解
The text was updated successfully, but these errors were encountered: