Skip to content

第 2 题:合并二维有序数组成一维有序数组,归并排序的思路 #8

@lgwebdream

Description

@lgwebdream
Owner

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

Activity

Genzhen

Genzhen commented on Jun 22, 2020

@Genzhen
Collaborator
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

Genzhen commented on Jun 22, 2020

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

Genzhen commented on Jun 22, 2020

@Genzhen
Collaborator
// 方法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

hehuilin commented on Jul 12, 2020

@hehuilin
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

hehuilin commented on Jul 12, 2020

@hehuilin
// 方法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

hehuilin commented on Jul 13, 2020

@hehuilin

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

SiHao24 commented on Jul 13, 2020

@SiHao24

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

123456zzz commented on Jul 13, 2020

@123456zzz
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

ppmiao0628 commented on Jul 13, 2020

@ppmiao0628

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

ppoollaarr

ppoollaarr commented on Jul 14, 2020

@ppoollaarr
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

chengming9731 commented on Jul 16, 2020

@chengming9731
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

work25 commented on Jul 16, 2020

@work25
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

HuberTRoy commented on Jul 16, 2020

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

40 remaining items

yuxiziyoutiankong

yuxiziyoutiankong commented on Aug 23, 2021

@yuxiziyoutiankong
 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

nhyu commented on Oct 3, 2021

@nhyu
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

SnailOwO commented on Oct 20, 2021

@SnailOwO
 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

18602435705 commented on Dec 24, 2021

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

18602435705 commented on Dec 24, 2021

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

ty888 commented on Jan 6, 2022

@ty888
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

listen-amo commented on Jan 17, 2022

@listen-amo

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

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

kangyana commented on Feb 15, 2022

@kangyana
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

chenpengdepot commented on Feb 25, 2022

@chenpengdepot

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

HeroTangMy commented on Mar 6, 2022

@HeroTangMy

异步解决方案
`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

wringY commented on Mar 27, 2022

@wringY
    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

nanmu-yuan commented on Aug 10, 2022

@nanmu-yuan

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

AAA611

AAA611 commented on Aug 25, 2022

@AAA611

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

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

jakenik commented on Feb 12, 2024

@jakenik

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

aaronxdd

aaronxdd commented on Sep 7, 2024

@aaronxdd

const myFlatSort = (arr) => {
if (!Array.isArray(arr)) return;
return arr.flat().sort();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @ruandao@markduan@qiheng@ppmiao0628@JJL-SH

        Issue actions

          第 2 题:合并二维有序数组成一维有序数组,归并排序的思路 · Issue #8 · lgwebdream/FE-Interview