Skip to content
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

Open
lgwebdream opened this issue Jun 19, 2020 · 64 comments
Labels
JavaScript teach_tag 头条 company

Comments

@lgwebdream
Copy link
Owner

lgwebdream commented Jun 19, 2020

欢迎在下方发表您的优质见解

@lgwebdream lgwebdream added JavaScript teach_tag 头条 company labels Jun 19, 2020
@Genzhen
Copy link
Collaborator

Genzhen commented Jun 22, 2020

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)

@Genzhen
Copy link
Collaborator

Genzhen commented Jun 22, 2020

/**
 * 解题思路:
 * 双指针 从头到尾比较 两个数组的第一个值,根据值的大小依次插入到新的数组中
 * 空间复杂度: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);

@Genzhen
Copy link
Collaborator

Genzhen commented Jun 22, 2020

// 方法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));

@hehuilin
Copy link

hehuilin commented Jul 12, 2020

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
		})
	}

@hehuilin
Copy link

// 方法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));

这个是不是少了排序的功能,只做了将多维数组转换为一维数组

@hehuilin
Copy link

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
})
}

数据长度的判断逻辑放在函数最开始是不是更好一点?

我是放在前面了呀,不知道你说的意思是要?

@SiHao24
Copy link

SiHao24 commented Jul 13, 2020

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
})
}

数据长度的判断逻辑放在函数最开始是不是更好一点?

我是放在前面了呀,不知道你说的意思是要?

看错了,不好意思。

@123456zzz
Copy link

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);

@ppmiao0628
Copy link

ppmiao0628 commented Jul 13, 2020

[[1,2,3],[4,5,6],[7,8,9],[1,2,3],[4,5,6]].flat(Infinity).sort((a,b)=>{ return a-b;})

@ppoollaarr
Copy link

ppoollaarr commented Jul 14, 2020

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;
}

@chengming9731
Copy link

chengming9731 commented Jul 16, 2020

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]])

不知道怎么调整格式凑合一下-_-

@work25
Copy link

work25 commented Jul 16, 2020

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()

@HuberTRoy
Copy link

HuberTRoy commented Jul 16, 2020

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))

@Genzhen Genzhen closed this as completed Jul 20, 2020
@523451928
Copy link

function flat(arr) {
  let copyArr = [...arr]
  while (copyArr.some(item => Array.isArray(item))) {
    copyArr = [].concat(...copyArr)
  }
  return copyArr.sort((a, b) => { a - b })
}
flat([[1, 2], [6, 4, 2], [3]])

@GolderBrother
Copy link

function flattenAndSort(arr = []) {
// 方法一: 借助concat方法
// function flatten(arr) {
// while (arr.some((item) => Array.isArray(item))) {
// arr = [].concat(...arr);
// }
// return arr;
// }

// 方法二: 借助reduce方法
// function flatten(arr = []) {
// return arr.reduce((accu, current) => {
// return Array.isArray(current)
// ? [...accu, ...flatten(current)]
// : [...accu, current];
// }, []);
// }

// 方法三: 直接使用数组的API flat, 传入Infinity值
function flatten(arr = []) {
return arr.flat(Infinity);
}

// 排序一个数组,我们先把数组从中间分成前后两部分,然后对前后两部分分别排序,再将排好序的两部分合并在一起,这样整个数组就都有序了。
// 归并排序采用的是分治思想。
function mergeSort(arr = []) {
// 采用自上而下的递归方法
const len = arr.length;
if (len < 2) return arr;
const middleIndex = len >> 1,
left = arr.slice(0, middleIndex),
right = arr.slice(middleIndex);
// 开局就深度递归到子元素,然后再两两元素比较排序
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;
}

return mergeSort(flatten(arr));
}

let arr = [
[1, 4, 6],
[7, 8, 10],
[2, 6, 9],
[3, 7, 13],
[1, 5, 12],
];
console.log(flattenAndSort(arr));

@Genzhen Genzhen reopened this Jul 29, 2020
@JJL-SH
Copy link

JJL-SH commented Aug 20, 2020

const mergeSort = (arr) =>
arr.reduce((cacheArr, it) => [...cacheArr, ...it], []).sort((a, b) => a - b);
const arr = [[1, 2, 3], [6], [7, 8, 9], [1, 12, 13], [4, 5, 6]];
mergeSort(arr)

@huzedong2015
Copy link

huzedong2015 commented Aug 28, 2020

const data = [
    [6, 7, 8, 9],
    [1, 2, 3, 4, 5],
    [10, 11, 12, 13]
];

const newData = data.flat();

newData.sort((a, b) => a - b);

如果是上面这种数据,可以先排序再扁平化数组

@jm19940203
Copy link

type flatReturn = Array;

export const flat = ( a: Array ): flatReturn => {

const newArr = a.toString().split(",");

return newArr.sort((a, b) => a - b);

}
//test
flat([[1, 2], [6, 4, 2], [3]])

@WJiaoJiao
Copy link

let arr = [[7,8,9],[1,2,3],[4,5,6]];

function mergeSort(arr) {
    let len = arr.length;
    if(len <= 1) return arr[0];
    let middleNum = Math.floor(len / 2);
    let left = arr.slice(0, middleNum);
    let right = arr.slice(middleNum);
    return merge(mergeSort(left), mergeSort(right));
}

function merge(left, right) {
    let result = [];
    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;
}

mergeSort(arr);

@gejianvs
Copy link

// 思路: 首先扁平化数组,再进行排序, 扁平化可以通过数组的tostring 和字符串split 方法
const arr =[[1,2,4],[2,3,7],[3,5,7],[4,5,8]]
const mySort = arr2 =>{
if(Array.isArray(arr2)){
const plantArr = arr2.toString().split(',')
plantArr.sort((a, b)=> a-b)
return plantArr
}
return []
}

console.log(mySort(arr))

@qiheng
Copy link

qiheng commented Oct 16, 2020

function mergeSort(arr) {

	let result = [];

	if (Array.isArray(arr)) {

		let newArr = JSON.parse(JSON.stringify(arr))

		while(newArr.length > 0) {

			let arrTmp = newArr.shift();

			result = result.concat(arrTmp)
			
		}

		result.sort(function(v1,v2) {
			return v1-v2
		})

	}

	return result

}

var arr = [[1,2,3],[4,5,6],[7,8,9],[1,2,3,21,45,33],[4,5,6]];

mergeSort(arr)

@noney
Copy link

noney commented Oct 22, 2020

/**
 * [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]]]);

@ruandao
Copy link

ruandao commented Oct 29, 2020

const mergeSort = (a: Array<number>, b: Array<number>): Array<number> => {
    if(a.length === 0) {
        return a
    }
    if(b.length === 0) {
        return b
    }
    const arr = [];
    let ai=0;
    let bi = 0;
    while(ai < a.length && bi < b.length) {
        if(a[ai] < b[bi]) {
            arr.push(a[ai]);
            ai++;
        } else {
            arr.push(b[bi]);
            bi++;
        }
    }
    for(;ai<a.length;ai++) {
        arr.push(a[ai])
    }
    for(;bi<b.length;bi++) {
        arr.push(b[bi])
    }
    return arr;
}
// 好吧,看错了....
const mergeSortArr = (arr: Array<number[]>): Array<number> => {
    if(!Array.isArray(arr)) {
        throw "传入的不是数组"
    }

    if(arr.length === 0) {
        throw "数组中至少需要一个元素"
    }
    if(arr.length === 1) {
        return arr[0];
    }
    return arr.slice(1).reduce((acc, item) => mergeSort(acc, item), arr[0])
}

var arr = [[1,2,3],[4,5,6],[7,8,9],[1,2,3,21,33, 45],[4,5,6]];

const result = mergeSortArr(arr)
console.log(result)

@chengazhen
Copy link

没有添加任何判断只是为了实现需求 不知道自己写的对不对 看上面大家都写了好多 是不是我理解错了啊

  • 先利用flat进行扁平化处理
  • 然后利用Set对象进行去重处理
  • 利用from将set数组化
  • 最后利用sort排序
 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]

@markduan
Copy link

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));

@jieceng
Copy link

jieceng commented Nov 18, 2020

function mergeArray(arr){
return Array.prototype.concat.apply([],arr).sort()
}
let arr = [[1,2,3],[4,5,6],[7,8,9],[1,2,3],[4,5,6]];
console.log( mergeArray(arr) )

@db46rt00ors
Copy link

db46rt00ors commented Mar 30, 2021

function mergeSort1(arr) {
            return arr.toString().split(',').map(item => +item).sort((a, b) => a - b)
        }

function mergeSort2(arr) { return arr.flat(Infinity).sort((a, b) => a - b) }

@hahazexia
Copy link

hahazexia commented Apr 11, 2021

这个题目其实提出了两个问题,一个是数组的展平,一个是归并排序的实现。

利用 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]

@zengxiaoluan
Copy link

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)
}

@zjg910723
Copy link

let arr = [[1,2,3],[2,3,4],[4,5,6]]; let newArr = arr.reduce((a,b) => { return a.concat(b); }) console.log(newArr.sort())

@Mrfujianfei
Copy link

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);
}

@HereSinceres
Copy link

HereSinceres commented May 20, 2021

const mergeArr = (arr) => {
	return arr.reduce((_memo,curr)=>{ return [..._memo,...curr].sort((a,b)=>a-b)},[])
}
mergeArr([[1,3],[2,4]])

@qq820137708
Copy link

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))

@chjssg
Copy link

chjssg commented Jun 2, 2021

/**
 * 合并二维有序数组成一维有序数组,归并排序的思路[[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]])

@Luoyuda
Copy link

Luoyuda commented Jun 9, 2021

    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
    }

@CYLpursuit
Copy link

CYLpursuit commented Jun 18, 2021

// 采用归并排序的思路,不断向结果数组中添加新数组进行归并
      function merge(leftArr, rightArr) {
        const result = [];
        while (leftArr.length > 0 && rightArr.length > 0) {
          if (leftArr[0] < rightArr[0]) {
            result.push(leftArr.shift());
          } else {
            result.push(rightArr.shift());
          }
        }
        return result.concat(leftArr).concat(rightArr);
      }
      function myMergeSortTwoDimension(twoDMSArr) {
        if (twoDMSArr.length <= 1) return twoDMSArr.shift();
        // 使用reduce
        return twoDMSArr.reduce(merge);
      }

@CYLpursuit
Copy link

[[1,2,3],[4,5,6],[7,8,9],[1,2,3],[4,5,6]].flat(Infinity).sort((a,b)=>{ return a-b;})

硬核

@CYLpursuit
Copy link

// 严格意义上的归并排序实现
function merge(leftArr, rightArr) {
      const result = [];
      if (leftArr[0] instanceof Array) {
        leftArr = leftArr.shift();
      }
      if (rightArr[0] instanceof Array) {
        rightArr = rightArr.shift();
      }
      while (leftArr.length > 0 && rightArr.length > 0) {
        if (leftArr[0] < rightArr[0]) {
          result.push(leftArr.shift());
        } else {
          result.push(rightArr.shift());
        }
      }

      return result.concat(leftArr).concat(rightArr);
    };
 function   myMergeSort(arr) {
      if (arr.length === 1) return arr;
      const middle = Math.floor(arr.length / 2);
      const leftArr = arr.slice(0, middle);
      const rightArr = arr.slice(middle);
      return merge(myMergeSort(leftArr), myMergeSort(rightArr));
    };

a = myMergeSort([[1,4,7],[2,5,8],[3,6,9]]);

@diuleiloumouF
Copy link

const sortFunc = (left, right) => {
if (!Array.isArray(left)) left = [left]
if (!Array.isArray(right)) right = [right]
const res = []
while (left.length > 0 && right.length > 0) {
if (left[0] < right[0]) {
res.push(left.shift())
} else {
res.push(right.shift())
}
}
return res.concat(left).concat(right)
}
const sort = arr => arr.reduce((pre, cur) => sortFunc(pre, cur))
console.log(sort([100, [1,4,6],[7,8,10],[2,6,9],[3,7,13],[1,5,12]]))

@Evllis
Copy link

Evllis commented Aug 9, 2021

没有添加任何判断只是为了实现需求 不知道自己写的对不对 看上面大家都写了好多 是不是我理解错了啊

  • 先利用flat进行扁平化处理
  • 然后利用Set对象进行去重处理
  • 利用from将set数组化
  • 最后利用sort排序
 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]

如果碰到多维数据就废了,比如:

let arr = [1, 2, [3, 4, [5, 6, 7, 3, [10, 12]], 7, 8]];

当然你这个解题对二维数组是完全可以解决的,但我觉得应该尽量想的周全一点。
加油。

@Wesley-front-end
Copy link

`let arrs = [[1, 2, [10, 12], 3], [5, 6, 8], [9, 4, 7]]

let newArr = []
function formatArr(arr) {
arr.forEach(item => {
if (Array.isArray(item)) {
formatArr(item)
}else{
newArr.push(item)
}
})
}

formatArr(arrs)

console.log(newArr.sort((a,b)=>a-b))`

@yuxiziyoutiankong
Copy link

 function flat(arr) {
  const l = []
  function dg (arr, p) {
    if (arr === p) return
    arr.forEach((item,index) => {
      if (item instanceof Array) {
        dg(item, arr)
      } else {
        l.push(item)
      }
    })
  }
  dg(arr)
  for(let i = 0; i < l.length; i++) {
    for(let j = i + 1; j < l.length; j++) {
      if (l[i] < l[j]) {
        let a = ''
        a = l[i]
        l[i] = l[j]
        l[j] = a
      }
    }
  }
  return l
}

@nhyu
Copy link

nhyu commented Oct 3, 2021

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]

@SnailOwO
Copy link

SnailOwO commented Oct 20, 2021

 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)))
`

@18602435705
Copy link

18602435705 commented Dec 24, 2021

/**
 * 合并两个一维有序数组
 * 双指针法
 * @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);

@18602435705
Copy link

/**
 * 合并两个一维有序数组
 * 首元素比较法
 * @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);

@ty888
Copy link

ty888 commented Jan 6, 2022

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]]
mergeSort(arr)

@listen-amo
Copy link

listen-amo commented Jan 17, 2022

简单来说,应该是归并排序少去从中分割的逻辑部分,直接进行合并排序的操作

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);
}

@kangyana
Copy link

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]

@chenpengdepot
Copy link

function oneArry(arr){
arr=arr.flat();
arr=[...new Set(arr)].sort((a,b)=>{
return a-b
})
return arr;
}
let oldArr=[[1,2,4],[2,3,7],[3,5,7],[4,5,8]]
oldArr=oneArry(oldArr)
console.log(oldArr)

@HeroTangMy
Copy link

异步解决方案
`const testAry = [
[1, 23, 45, 99],
[4, 8, 9, 15, 48],
[4, 8, 17, 32],
[5, 7, 9]
]
async function tomerge(arr1, arr2) {
let mergedAry = [];
// console.log(arr1,arr2)
let longgerAry = arr1.length > arr2.length ? arr1 : arr2;
let shortAry=arr1.length < arr2.length ? arr1 : arr2;
let j = 0;
let i = 0;
while (shortAry.length != 0 || longgerAry.length != 0) {
if (shortAry.length == 0) {
mergedAry = mergedAry.concat(longgerAry)
break
}
if (longgerAry.length == 0) {
mergedAry = mergedAry.concat(shortAry)
break
}
if (shortAry[0] > longgerAry[0]) {
// console.log(mergedAry)
mergedAry.push(longgerAry.shift())
}
else {
// console.log(mergedAry)
mergedAry.push(shortAry.shift())
}
}
return mergedAry

}
function merge(thisary) {
    let promiseArr = []
    // console.log(thisary)
    if (thisary.length % 2 === 1) {
        thisary.push([])
    }
    return new Promise((resolve, reject) => {
        while (thisary.length >= 2) {
            // console.log(thisary[0], thisary[1])
            promiseArr.push(tomerge(thisary[0], thisary[1]))
            thisary.shift()
            thisary.shift()
        }
        console.log(promiseArr)
        Promise.all(promiseArr).then(NextNums => {
            if (NextNums.length === 1) {
                // console.log(NextNums[0])
                resolve(NextNums[0])
            } else {
                // console.log(NextNums)
                merge(NextNums).then(res => {
                    resolve(res)
                })
            }
        })
    })
}

merge(testAry).then(info => { console.log(info) })`

@wringY
Copy link

wringY commented Mar 27, 2022

    function mergeSort(leftArr, rightArr) {
        
        const left = leftArr.flat(Infinity)
        const right = rightArr.flat(Infinity)

        let result = []
        let i = 0, j = 0;
        while (i < left.length && j < right.length) {
            if (left[i] <= right[j]) {
                result.push(left[i])
                i++
            } else {
                result.push(right[j])
                j++
            }
        }

        if ( i < left.length) {
            result.push(...left.slice(i))
        } else {
            result.push(...right.slice(j))
        }

        return result
    }
    console.log(mergeSort([[0, 1],[2, 3], [4, 5]], [[6, 7],[8, 9], [10, 11]]))

@nanmu-yuan
Copy link

const arr1 = [[5,9,6],[5,9,6,],[8,9,6]];
const mergeAndSex = (arr)=>[].concat(...arr).sort((a,b)=>a-b)

@AAA611
Copy link

AAA611 commented Aug 25, 2022

题目应该不是要直接把数组展平然后排序,那样的话我直接:

function sortTest(nums) {
  return nums.flat().sort((a, b) => a - b)
}

题目说是归并排序的思路,归并排序分为归和并两个过程

  1. 归:把数组分为若干份分别将其排为有序数组
  2. 并:把有序数组进行合并成为最终的排序结果

题目中给出的是多个有序数组,需要合并为一个有序数组,因此不需要“归”,直接“并”

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
}

@jakenik
Copy link

jakenik commented Feb 12, 2024

const mergeList = (...list) => {
return list.flat(Infinity).sort((a, b) => a - b)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
JavaScript teach_tag 头条 company
Projects
None yet
Development

No branches or pull requests