Advanced-Frontend / Daily-Interview-Question

我是依扬(木易杨),公众号「高级前端进阶」作者,每天搞定一道前端大厂面试题,祝大家天天进步,一年后会看到不一样的自己。

Home Page:https://muyiy.cn/question/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

第 135 题:算法题

yygmind opened this issue · comments

在一个字符串数组中有红、黄、蓝三种颜色的球,且个数不相等、顺序不一致,请为该数组排序。使得排序后数组中球的顺序为:黄、红、蓝。

例如:红蓝蓝黄红黄蓝红红黄红,排序后为:黄黄黄红红红红红蓝蓝蓝。

function sortBalls (str) {
let arr = str.split('')
arr.sort((a, b) => {
return getNumByType(a) - getNumByType(b)
})

return arr.join('')

function getNumByType (type) {
  switch (type) {
    case '黄':
      return 1
    case '红':
      return 2
    default:
      return 3
  }
}

}

const strList = '红蓝蓝黄红黄蓝红红黄红'
const sortRules = {'黄': 0, '红': 1, '蓝': 2,}
const list = [[],[],[]]
strList.split('').forEach(item => {list[sortRules[item]].push(item)})
list.reduce((pre, cur) => pre += cur.join(''), '')
//黄黄黄红红红红红蓝蓝蓝
    /**
     * 在一个字符串数组中有红、黄、蓝三种颜色的球,且个数不相等、顺序不一致,请为该数组排序。使得排序后数组中球的顺序为:黄、红、蓝。

     例如:红蓝蓝黄红黄蓝红红黄红,排序后为:黄黄黄红红红红红蓝蓝蓝。
     */
    let inputStr = "红蓝蓝黄红黄蓝红红黄红";

    /**
     * 过滤好拼接
     * @param inputStr
     * @returns {*}
     */
    function sortStr1(inputStr){
        let inputArr = inputStr.split("");
        let yellowArr = inputArr.filter(item => item === "黄");
        let redArr = inputArr.filter(item => item === "红");
        let blueArr = inputArr.filter(item => item === "蓝");
        return [...yellowArr, ...redArr, ...blueArr].join("");
    }

    console.log(sortStr1(inputStr));

    /**
     * 根据sort函数排序拼接
     * @param inputStr
     */
    function sortStr2(inputStr){
        let dict = {
            "黄": 0,
            "红": 1,
            "蓝": 2,
            0: "黄",
            1: "红",
            2: "蓝"
        };
        let inputArr = inputStr.split("").map(item => dict[item]);
        inputArr.sort((a, b) => a - b);
        inputArr = inputArr.map(item => dict[item]);
        return inputArr.join("");
    }

    console.log(sortStr2(inputStr));

    /**
     * 先数各几个,然后通过repeat拼接
     * @param inputStr
     */
    function sortStr3(inputStr){
        let yellowCount = 0;
        let redCount = 0;
        let blueCount = 0;
        for (let i = 0; i < inputStr.length; i++) {
            switch(inputStr[i]){
                case "黄":
                    yellowCount++;
                    break;
                case "红":
                    redCount++;
                    break;
                case "蓝":
                    blueCount++;
                    break;
            }
        }
        return "黄".repeat(yellowCount)+"红".repeat(redCount)+"蓝".repeat(blueCount);

    }

    console.log(sortStr3(inputStr));

sortColor = colorArr => {
if (Array.isArray(colorArr)) {
let map = {}
colorArr.map((item, index) => {
if (map[item]) {
map[item].push(item)
} else {
map[item] = []
map[item].push(item)
}
})
return [...map['黄'], ...map['红'], ...map['蓝']]
}
return colorArr;
}

var arr = ['蓝','黄','蓝','红','黄','蓝','红','黄','蓝','蓝','红','黄','黄','红'];
var arrNew = [];
var color = ['黄','红','蓝'];
function maps(arr,i){
for(var item of arr){
if(item == color[i]){
arrNew.push(item)
}
}
}
for(var i = 0; i < color.length; i++){
maps(arr,i)
}
console.log(arrNew)

const colorStr = '红蓝蓝黄红黄蓝红红黄红';
function sortColor(colors) {
  let tmpArr = colors.split('');
  let obj = {
    '黄': [],
    '红': [],
    '蓝': []
  };
  for (let key of tmpArr) {
    obj[key].push(key);
  }
  return [...Object.values(obj)].flat(Infinity).join('');
}
sortColor(colorStr)
commented

let originStr = '红蓝蓝黄红黄蓝红红黄红';
let sortStr = '黄红蓝';
originStr.split('').sort((prev, next) => {
return sortStr.indexOf(prev) - sortStr.indexOf(next)
}).toString()
image

/**
 * 根据order的顺序对数据排序
 * @param arr 排序数组
 * @param order 排序内容order
 */
function cunstomSort<T>(arr: Array<T>, order: Array<any>): Array<T> {
  return arr.sort((a, b) => order.indexOf(a) - order.indexOf(b));
}

console.log(
  cunstomSort('红蓝蓝黄红黄蓝红红黄红'.split(''), ['红', '黄', '蓝'])
);
commented

写的比较low,大神写的真秀,敬佩敬佩

     //  在一个字符串数组中有红、黄、蓝三种颜色的球,且个数不相等、顺序不一致,请为该数组排序。使得排序后数组中球的顺序为:黄、红、蓝。
      //例如:,排序后为:黄黄黄红红红红红蓝蓝蓝。

      let sort = (str, aimAry) =>
        Array.from(str)
          .reduce(
            (prev, item) => (prev[aimAry.indexOf(item)].push(item), prev),
            Array.from({ length: aimAry.length }, child => [])
          )
          .flat(1)
          .join('')
  
      let res = sort('红蓝蓝黄红黄蓝红红黄红', '黄红蓝')
      console.log(res)
const splitSource = (source) => {
    let targetArray = [[],[],[]];
    source.split('').forEach(element => {
        switch (element) {
            case '黄':
                targetArray[0].push(element)
                break;
            case '红':
                targetArray[1].push(element)
                break;
            case '蓝':
                targetArray[2].push(element)
                break;
        
            default:
                break;
        }
    });
    return targetArray.flat()
}

splitSource('红蓝蓝黄红黄蓝红红黄红')

用到了 flat
其实 sort() 和 charCodeAt() 也可以做的

看了楼上的高赞做的,这个做法是真秀,之前想用 charCodeAt() 来做排序的依据的,没想到换个思路自己给定义一下顺序就搞定了 真是秀

const stringOrder = {
    '黄':0,
    '红':1,
    '蓝':2
}
'红蓝蓝黄红黄蓝红红黄红'.split('').sort((a,b) =>stringOrder[a]-stringOrder[b] )
const balls = ['红', '蓝', '蓝', '黄', '红', '黄', '蓝', '红', '红', '黄', '红'];

// 定义排序规则,越小越靠前
const sortRule = new Map([
  ['黄', 1], ['红', 2], ['蓝', 3]
]);

balls.sort((a, b) => sortRule.get(a) - sortRule.get(b));

//只循环一次,应该比冒泡排序快,或许吧。。。
var a=[1,2,3,3,2,2,3,1,2,3,1,2,3,1,2,3,1,3,3,1,3,1,2];
var b=[[],[],[]];
for(var i=0;i<a.length;i++){
if(a[i]==1){
b[0].push(1)
}else if(a[i]==2){
b[1].push(2)
}else if(a[i]==3){b[2].push(3)}
}
console.log([...b[0],...b[1],...b[2]]);

var originStr = "红蓝蓝黄红黄蓝红红黄红";
var redCount = originStr.match(/红/ig).length;
var yellowCount = originStr.match(/黄/ig).length;
var blueCount = originStr.match(/蓝/ig).length;
console.log("红".repeat(redCount)+"黄".repeat(yellowCount)+"蓝".repeat(blueCount))

['黄','红','蓝'].map((o)=>o.repeat([...'红蓝蓝黄红黄蓝红红黄红'.matchAll(o)].length)).join('')

一行代码嘻嘻

const str = ['红', '蓝', '蓝', '黄', '红', '黄', '蓝', '红', '红', '黄', '红']; function rank(list) { const map = { '黄': 0, '红': 1, '蓝': 2 } return list.sort((val, nextVal) => { return map[val] - map[nextVal] }) }

    var arr = '红蓝蓝黄红黄蓝红红黄红'
    var arrList = arr.split('')
    var obj = {
        "黄": [],
        "红": [],
        "蓝": []
    }
    arrList.map(item => obj[item].push(item))
    console.log([...obj['黄'], ...obj['红'], ...obj['蓝']].join(''))

let str = '蓝蓝黄红黄蓝红红黄红';
function sortColor(str){
let arrY = [],arrR = [],arrB = [];
let str1 = str.split('');
str1.map((item,index)=>{
if(item=='黄')arrY.push(item);
if(item=='红')arrR.push(item);
if(item=='蓝')arrB.push(item);
})
let newarr = (arrY.concat(arrR)).concat(arrB);
}
sortColor(str)

function Ball(inputStr){
inputarr = inputStr.split("");
var red = [];
var yellow = [];
var blue = [];
// yellow Red blue
// 黄 红 蓝
inputarr.forEach((item) => {
if(item === "黄") {
yellow.push(item)
}
if(item === "红"){
red.push(item)
}
if(item === "蓝") {
blue.push(item)
}
})
return yellow.join("")+red.join("")+blue.join("")
}

outstr = Ball("红红红黄黄蓝红黄蓝红蓝")
console.log(outstr)

let colorString = '红蓝蓝黄红黄蓝红红黄红';
   function formatColor(string) {
       let colorObj = {
           '黄': 1,
           '红': 2,
           '蓝': 3,
       }
       return Array.from(string).sort(function (a, b) { return colorObj[a] - colorObj[b] }).join('');
   }
   console.log(formatColor(colorString));  //黄黄黄红红红红红蓝蓝蓝
function sortStr(str) {
    var arr = [];
    var redIndex = 0;
    for(let i = 0; i< str.length; i++) {
        switch(str[i]) {
            case "黄":
                arr.unshift(str[i])
                redIndex++;
                break;
            case "红": 
                arr.splice(redIndex, 0, str[i])
                redIndex++
                break;
            case "蓝": 
                arr.push(str[i]);
                break;
        }
    }
    return arr.join("");
}
console.log(sortStr(str)); //黄黄黄红红红红红蓝蓝蓝

` function colorSort(str) {

if(!str) return null;

const match = {
    黄:0,
    红:1,
    蓝:2
};

const arr = str.split('');

arr.sort((a,b) => match[a]-match[b]);

console.log(arr.join(''));

}`

function sortColor(list) {
        if (list.length <= 1) return list
        let yellow = 0
        let blue = list.length - 1
        let pointer = 0
        while (list[yellow] === '黄') {
            yellow++
            pointer++
        }
        while (list[blue] === '蓝') {
            blue--
        }
        while (pointer <= blue) {
            if (list[pointer] === '黄') {
                swap(list, pointer, yellow)
                yellow++
                pointer++
            } else if (list[pointer] === '蓝') {
                swap(list, pointer, blue)
                blue--
            } else {
                pointer++
            }
        }

        return list
    }
    function swap(list, a, b) {
        [list[a], list[b]] = [list[b], list[a]]
    }

尝试用了三指针,类似快排的**,原地交换。空间复杂度O(1),时间复杂度应该在O(n)吧
也可以先一遍把黄色分出来,然后再分红和蓝
不知道对不对啊😂😂😂 写算法经常是在一些边界条件上出问题

这个最实在

   const str = '红蓝蓝黄红黄蓝红红黄红';
   const order = '黄红蓝'
   function orderColor(str, order) {
       return [...str].sort((a,b) =>order.indexOf(a) - order.indexOf(b) ).join('');
   }
   console.log(orderColor(str, order ));  //黄黄黄红红红红红蓝蓝蓝
                                  `###最长版本来了###`

三中符号代表三种不同的颜色 最后排序 什么符号都可以的 随意改。。。

var color = '<%><%<%>%<%<><%<><%%<><%<%%><%>><%%<%>'.split('')
function sortColor (color) {
  let colorType = getColorType(color)
  let newColor = []
  for (let i=0;i<color.length;i++) {
    if(color[i]===colorType[0]){
      newColor.unshift(color.splice(i,1)[0])
      i--
    } 
  }
  for (let i=0;i<color.length;i++) {
    if(color[i]===colorType[1]){
      newColor.push(color.splice(i,1)[0])
      i--
    } 
  }
  return newColor.concat(color)
}

function getColorType (color) {
  let colorType = []
  let comparison = []
  colorType.push(color[0])
  for (let i=0;i<color.length;i++) {
    if(color[i]!==color[0]){
      comparison.push(color[i])
    }
  }
  colorType.push(comparison[0])
  for(let i=0;i<comparison.length;i++) {
    if(comparison[i]!==comparison[0]){
      colorType.push(comparison[i])
      return colorType
      }
  }
}
let sortcolor = sortColor(color)
console.log(sortcolor)
var arr = ['a','b','c','c','b','b','a','c','b']
    arr.filter(res => res === 'a').concat(arr.filter(res => res === 'b').concat(arr.filter(res => res === 'c')));
commented
function foo(a, b) {
  return [...a].reduce((acc, next) => {
	return acc + [...b].filter(i => next === i).join('')
  }, '')
}

foo('黄红蓝', '红蓝蓝黄红黄蓝红红黄红')
function sortColor(str) {
  const arr = str.split("");
  const map = {
    "黄": 1,
    "红": 2,
    "蓝": 3
  };
  arr.sort((cl1, cl2) => map[cl1] - map[cl2]);
  console.log(arr);
  return arr.join("");
}

不知道怎么 发出像 上面人的格式....

const sortColourBall = (ball) => {
const blurArr = []
const ballArr = ball.split('').reduce((acc,cur) => {
if (cur === '黄') {
acc.unshift(cur)
}
else if(cur === '红') {
acc.push(cur)
}
else if (cur === '蓝') {
blurArr.push(cur)
}
return acc
},[])
return ballArr.concat(blurArr).join('')
}

const sortArr = arr => {

    const map = {
        '红': 0,
        '橙': 1,
        '黄': 2,
        '绿': 3,
        '青': 4,
        '蓝': 5,
        '紫': 6
    }
    arr.sort((a, b) => map[a] - map[b]);
    return arr;
}
console.log(sortArr(['红', '橙', '红', '黄', '黄', '绿', '青', '蓝', '紫', '绿', '青', '蓝', '紫', '橙', '红']));

let str='红蓝蓝黄红黄蓝红红黄红';
function getColors(color){

return str.match(eval("/"+color+'/g'));

};

let result=getColors('黄').concat(getColors('红')).concat(getColors('蓝')).join('');
image

let arr = '红蓝蓝黄红黄蓝红红黄红'
arr = arr.split('')
function sortByColor(arr) {
  const colorMap = { '黄':[],'红':[],'蓝':[]}
  arr.forEach(item => colorMap[item].push(item))
  return colorMap['黄'].concat(colorMap['红']).concat(colorMap['蓝'])
}
console.log(sortByColor(arr))
commented

image
这也太弟弟了

        function sort(arr) {
            let str = '';
            arr = arr.join('');
            [ '黄','红', '蓝'].forEach(item => {
                let reg = new RegExp(item, 'g');
                str += arr.match(reg).join('');
            })
            return str.split('');
        }
let s='红蓝蓝黄红黄蓝红红黄红';
let obj={
  '红':1,
  '黄':2,
  '蓝':3,
};
let comp1=(a,b)=>{
  return obj[a]-obj[b];
}
console.log(s.split('').sort(comp1).join(''));
//输出:"红红红红红黄黄黄蓝蓝蓝"
    let str = '红蓝蓝黄红黄蓝红红黄红';
    let keys = '黄红蓝';
    console.info(str.split('').sort((a, b) => keys.indexOf(a) - keys.indexOf(b)).join(''));
  const arr = ['红', '蓝', '蓝', '黄', '红', '黄', '蓝', '红', '红', '黄', '红'];
  function fn(arr) {
    const obj = {
      '黄': [],
      '红': [],
      '蓝': [],
    };
    arr.forEach(ele => obj[ele].push(ele));
    let newArr = [];
    Object.keys(obj).forEach(key => {
      newArr = newArr.concat(...obj[key])
    });
    return newArr;
  }
var colorObj = {
  '黄色': 0,
  '红色': 1,
  '蓝色': 2
}

var colorSort = array => array.sort((a, b) => colorObj[a] - colorObj[b])

var color = ['黄色', '红色', '蓝色']

var colorArr = Array.apply(null, { length: Math.round(Math.random() * 10000) }).map(() => color[Math.round(Math.random() * 2)])
colorSort(colorArr)
console.dir(colorArr)
var colorObj = {
  '黄色': 0,
  '红色': 1,
  '蓝色': 2
}

var colorSort = array => array.sort((a, b) => colorObj[a] - colorObj[b])

var color = ['黄色', '红色', '蓝色']

var colorArr = Array.apply(null, { length: Math.round(Math.random() * 10000) }).map(() => color[Math.round(Math.random() * 2)])
colorSort(colorArr)
console.dir(colorArr)

试了下,colorObj换成Map,性能可以提升60%往上

没怎么考虑效率,实现罢了
let sortBall = (group) => {

let fianllBall = [], redBall = [], yellowBall = [], blueBall = [];
group.forEach((item, index) => {
	switch(item){
		case '红':
			redBall.push(item);
			break;
		case '蓝':
			blueBall.push(item);
			break;
		case '黄':
			yellowBall.push(item);
			break;
		default :
			break;
	}
})
fianllBall = [...yellowBall, ...redBall, ...blueBall];
return fianllBall;

}
const ballArray = ['红','蓝','蓝','黄','红','黄','蓝','红','红','黄','红'];
sortBall(ballArray);

function changecolor(str) {
    let obj = {}
    for (let i = 0; i < str.length; i++) {
        if (obj.hasOwnProperty(str[i])) {
            obj[str[i]]++
        }else{
            obj[str[i]] = 1
        }
        
    }
    let a=obj["黄"]
    let b=obj["红"]
    let c=obj["蓝"]
    return "黄".repeat(a)+"红".repeat(b)+"蓝".repeat(c)
}
<script>
        let str = '红蓝蓝黄红黄蓝红红黄红';
        let reg_1 = /黄/g;
        let yellow = str.match(reg_1);
        let reg_2 = /红/g;
        let red = str.match(reg_2);
        let reg_3 = /蓝/g;
        let blue = str.match(reg_3);
        let sortColor = yellow.concat(red).concat(blue).join("");
        console.log(sortColor);//黄黄黄红红红红红蓝蓝蓝
    </script>
const originStr = '红蓝蓝黄红黄蓝红红黄红';

function sort(str){
  let array = str.split('');
  let obj = {};
  array && array.map(arr => {
    if (arr === '黄'){
      obj['黄'] = obj['黄'] || [];
      obj['黄'].push(arr)
    } else if (arr === '红'){
      obj['红'] = obj['红'] || [];
      obj['红'].push(arr)
    } else if (arr === '蓝'){
      obj['蓝'] = obj['蓝'] || [];
      obj['蓝'].push(arr)
    }
  })
  const finalStr = obj['黄'].join('') + obj['红'].join('') + obj['蓝'].join('')
}

sort(originStr)
let arr=[...'红蓝蓝黄红黄蓝红红黄红'];
function fn(arr){
    let map={
        '黄':0,
        '红':1,
        '蓝':2
    }
   arr.sort((a,b)=> map[a]-map[b])
}

面试用内置函数会不会被diss吖...

function sortBalls(str){
let strY = str.replace(/红|蓝/g,'');
let strR = str.replace(/黄|蓝/g,'');
let strB = str.replace(/黄|红/g,'');
return strY+strR+strB;
}

  let arr = '红蓝蓝黄红黄蓝红红黄红';
        let result = arr.split('').sort();
        sortBall(result)
        function sortBall(arr) {
            let back = [];
            arr.forEach(v => {
                v === '黄' ? back.unshift(v) : back.push(v);
            })
            return back;
        }
/*
在一个字符串数组中有红、黄、蓝三种颜色的球,
且个数不相等、顺序不一致,请为该数组排序。
使得排序后数组中球的顺序为:黄、红、蓝。
例如:红蓝蓝黄红黄蓝红红黄红,排序后为:黄黄黄红红红红红蓝蓝蓝。

*/
function orderBall(arr,rule){
    arr.sort((a,b)=>rule[a]-rule[b]);
    return arr;
}
const rule = {
    '黄':0,
    '红':1,
    '蓝':2
}
const str = '红蓝蓝黄红黄蓝红红黄红';

console.log(orderBall(str.split(''),rule));
var str1 = '红蓝蓝黄红黄蓝红红黄红';
let obj1 = [...str1].reduce((total, item) => {
	item in total ? total[item]++ : total[item] = 1
	return total
}, {});
let str2 = new Array(obj1.).fill('黄').concat(new Array(obj1.).fill('红'), new Array(obj1.).fill('蓝')).join('');
console.log(str2); // 黄黄黄红红红红红蓝蓝蓝
var str1 = '红蓝蓝黄红黄蓝红红黄红';
var rule = {
	'黄' : 0,
	'红' : 1,
	'蓝' : 2
};
let str3 = [...str1].sort((a, b) => rule[a] - rule[b]).join('');
console.log(str3); // 黄黄黄红红红红红蓝蓝蓝

function sortBalls (str) {
let arr = str.split('')
arr.sort((a, b) => {
return getNumByType(a) - getNumByType(b)
})

return arr.join('')

function getNumByType (type) {
  switch (type) {
    case '黄':
      return 1
    case '红':
      return 2
    default:
      return 3
  }
}

}

不花里胡哨 适合面试官看 起码面试官看起来不累2333

const yellow = (str) => (/黄/u.test(str))
const red = (str) => (/红/u.test(str))
const blue = (str) => (/蓝/u.test(str))
const str = '黄蓝蓝红黄红蓝蓝黄红黄蓝红红黄红'
const testitem = str.split('')
var ylen = 0
var res = testitem.reduce((res, item) => {
    if (yellow(item)) {
        res.unshift(item)
        ylen++
    } else if (red(item)) {
        res.splice(ylen, 0, item)
    } else {
        res.push(item)
    }
    return res
}, [])
console.log(res)

// [
//     '黄', '黄', '黄', '黄',
//     '黄', '红', '红', '红',
//     '红', '红', '红', '蓝',
//     '蓝', '蓝', '蓝', '蓝'
// ]

const str = '红蓝蓝黄红黄蓝红红黄红'
const order={
'黄':1,
'红':2,
'蓝':3,
};
console.log([...str].sort((a,b)=>order[a]-order[b]).join(''))

哈哈哈哈哈哈
function fn(str){
return str.replace(/黄/g,0).replace(/红/g,1).replace(/蓝/g, 2).split('').sort().join('').replace(/0/g, '黄').replace(/1/g,'红').replace(/2/g, '蓝')
}

commented

function f(str){
let hash={};
str.split("").map(el=>{
hash[el]?hash[el].push(el):hash[el]=[el];
});

reurn [...hash['黄'],...hash['红'],...hash['蓝']].join("");
}

['黄','红','蓝'].map((o)=>o.repeat([...'红蓝蓝黄红黄蓝红红黄红'.matchAll(o)].length)).join('')

一行代码嘻嘻

慢慢往下看,总是有惊喜!

算法题目,想了个原地改变数组的办法:

  1. 把黄色都移动到前面
  2. 把蓝色都移动到后面
  3. 剩下的自然都是红色,不用管了就
// 黄,红,蓝
function sort(arr) {
  let i = 0;
  let j = arr.length;

  for (let k = 0; k < j; k++) {
    if (arr[k] === '黄') {
      [arr[i], arr[k]] = [arr[k], arr[i]];
      i++;
    } else if (arr[k] === '蓝') {
      j--;
      [arr[j], arr[k]] = [arr[k], arr[j]];
    }
  }
  return arr;
}

Test:

console.log(sort('红红红红红红红红'.split('')));
console.log(sort('蓝蓝蓝蓝蓝蓝蓝蓝'.split('')));
console.log(sort('黄黄黄黄黄黄黄黄'.split('')));
console.log(sort('红蓝蓝黄红黄蓝红红黄红'.split('')));
commented
function sortColor(str) {
      let yellowCount = 0
      return str.split('').reduce((res, cur)=>{
        if(cur==='黄'){
          yellowCount++
          res.unshift(cur)
        }else if(cur==='红'){
          res.splice(yellowCount,0,cur)
        }else if(cur==='蓝'){
          res.push(cur)
        }
        return res
      }, [])
}

算法题目,想了个原地改变数组的办法:

  1. 把黄色都移动到前面
  2. 把蓝色都移动到后面
  3. 剩下的自然都是红色,不用管了就
// 黄,红,蓝
function sort(arr) {
  let i = 0;
  let j = arr.length;

  for (let k = 0; k < j; k++) {
    if (arr[k] === '黄') {
      [arr[i], arr[k]] = [arr[k], arr[i]];
      i++;
    } else if (arr[k] === '蓝') {
      j--;
      [arr[j], arr[k]] = [arr[k], arr[j]];
    }
  }
  return arr;
}

Test:

console.log(sort('红红红红红红红红'.split('')));
console.log(sort('蓝蓝蓝蓝蓝蓝蓝蓝'.split('')));
console.log(sort('黄黄黄黄黄黄黄黄'.split('')));
console.log(sort('红蓝蓝黄红黄蓝红红黄红'.split('')));

测试了一下,结果没有符合预期

sort( '红蓝蓝黄红黄蓝红红黄红蓝'.split(''));  // 结果为 ["黄", "黄", "红", "红", "红", "蓝", "黄", "红", "红", "蓝", "蓝", "蓝"]

k++不应该在每个循环中都执行,当arr[k]和arr[j]交换之后,这时的arr[k]其实没有判断过,直接k++就跳过了这个元素。
@whosesmile

'红蓝蓝黄红黄蓝红红黄红'.split('').sort((a, b) => {
  if (a === '黄') return -1;
  if (a === '蓝') return 1;
  if (b === '黄') return 1;
  if (b === '蓝') return -1;
}).join('')
        let arr = '红蓝蓝黄红黄蓝红红黄红'.split('')

        let i = 0;
        let order = ['黄', '红', 0];
        let next = 0;
        while (order[next]) {
            for (j = i + 1; j < arr.length; j++) {
                if (arr[j] == order[next]) {
                    if (arr[i] != order[next]) {
                        let t = arr[i];
                        arr[i] = arr[j];
                        arr[j] = t;
                    } else {
                        if (arr[i + 1] != order[next]) {
                            let t = arr[i + 1];
                            arr[i + 1] = arr[j];
                            arr[j] = t;
                        }
                        i++;
                    }
                }
            }

            i = i + 1;
            next++;
        }

        console.log(arr.join(''))
commented

"红蓝蓝黄红黄蓝红红黄红".split("").sort((a,b)=>a==="黄"?-1:a==="蓝"?1:0).join("")

function sortColor(str) {
    return str.split('').sort((a, b) => {
        if (b === '蓝' || b === '红' && a === '黄') return -1;
    }).join('');
}
commented

'红蓝蓝黄红黄蓝红红黄红'.split('').sort((a,b) => {if(a=='黄' || b=='蓝'){return -1}}).join('')

算法题目,想了个原地改变数组的办法:

  1. 把黄色都移动到前面
  2. 把蓝色都移动到后面
  3. 剩下的自然都是红色,不用管了就
// 黄,红,蓝
function sort(arr) {
  let i = 0;
  let j = arr.length;

  for (let k = 0; k < j; k++) {
    if (arr[k] === '黄') {
      [arr[i], arr[k]] = [arr[k], arr[i]];
      i++;
    } else if (arr[k] === '蓝') {
      j--;
      [arr[j], arr[k]] = [arr[k], arr[j]];
    }
  }
  return arr;
}

Test:

console.log(sort('红红红红红红红红'.split('')));
console.log(sort('蓝蓝蓝蓝蓝蓝蓝蓝'.split('')));
console.log(sort('黄黄黄黄黄黄黄黄'.split('')));
console.log(sort('红蓝蓝黄红黄蓝红红黄红'.split('')));

测试了一下,结果没有符合预期

sort( '红蓝蓝黄红黄蓝红红黄红蓝'.split(''));  // 结果为 ["黄", "黄", "红", "红", "红", "蓝", "黄", "红", "红", "蓝", "蓝", "蓝"]

k++不应该在每个循环中都执行,当arr[k]和arr[j]交换之后,这时的arr[k]其实没有判断过,直接k++就跳过了这个元素。
@whosesmile

确实,没考虑周全, k 元素被替换后需要再次判断,所以应该k--回退,保持不变再重新迭代一次K。

// 黄,红,蓝
function sort(arr) {
  let i = 0;
  let j = arr.length - 1;

  for (let k = 0; k <= j; k++) {
    if (arr[k] === '黄') {
      [arr[i], arr[k]] = [arr[k], arr[i]];
      i++;
      k = k > i ? k-- : k;
    } else if (arr[k] === '蓝') {
      [arr[j], arr[k]] = [arr[k], arr[j]];
      j--;
      k--;
    }
  }
  return arr;
}

! 高赞的回答时间复杂度太高,面试并不一定能过

题目地址(75. 颜色分类)

https://leetcode-cn.com/problems/sort-colors/

题目描述

给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

注意:
不能使用代码库中的排序函数来解决这道题。

示例:

输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]
进阶:

一个直观的解决方案是使用计数排序的两趟扫描算法。
首先,迭代计算出0、1 和 2 元素的个数,然后按照0、1、2的排序,重写当前数组。
你能想出一个仅使用常数空间的一趟扫描算法吗?

前置知识

公司

  • 阿里
  • 腾讯
  • 百度
  • 字节

思路

这个问题是典型的荷兰国旗问题 (https://en.wikipedia.org/wiki/Dutch_national_flag_problem)。 因为我们可以将红白蓝三色小球想象成条状物,有序排列后正好组成荷兰国旗。

解法一 - 计数排序

  • 遍历数组,统计红白蓝三色球(0,1,2)的个数
  • 根据红白蓝三色球(0,1,2)的个数重排数组

这种思路的时间复杂度:$O(n)$,需要遍历数组两次(Two pass)。

image

解法二 - 挡板法

我们可以把数组分成三部分,前部(全部是 0),中部(全部是 1)和后部(全部是 2)三个部分。每一个元素(红白蓝分别对应 0、1、2)必属于其中之一。将前部和后部各排在数组的前边和后边,中部自然就排好了。

我们用三个指针,设置两个指针 begin 指向前部的末尾的下一个元素(刚开始默认前部无 0,所以指向第一个位置),end 指向后部开头的前一个位置(刚开始默认后部无 2,所以指向最后一个位置),然后设置一个遍历指针 current,从头开始进行遍历。

形象地来说地话就是有两个挡板,这两个挡板实现我们不知道,我们的目标就是移动挡板到合适位置,并且使得挡板每一部分都是合适的颜色。

image

还是以题目给的样例来说,初始化挡板位置为最左侧和最右侧:

image

读取第一个元素是 2,它应该在右边,那么我们移动右边地挡板。

image

带有背景色的圆圈 1 是第一步的意思。

并将其和移动挡板后挡板右侧地元素进行一次交换,这意味着“被移动挡板右侧地元素已就位”。

image

。。。

整个过程大概是这样的:

这种思路的时间复杂度也是$O(n)$, 只需要遍历数组一次。

关键点解析

  • 荷兰国旗问题
  • counting sort

代码

代码支持: Python3, CPP

Python3 Code:

class Solution:
    def sortColors(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        p0 = cur = 0
        p2 = len(nums) - 1

        while cur <= p2:
            if nums[cur] == 0:
                nums[cur], nums[p0] = nums[p0], nums[cur]
                p0 += 1
                cur += 1
            elif nums[cur] == 2:
                nums[cur], nums[p2] = nums[p2], nums[cur]
                p2 -= 1
            else:
                cur += 1

CPP Code:

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int r = 0, g = 0, b = 0;
        for (int n : nums) {
            if (n == 0) {
                nums[b++] = 2;
                nums[g++] = 1;
                nums[r++] = 0;
            } else if (n == 1) {
                nums[b++] = 2;
                nums[g++] = 1;
            } else nums[b++] = 2;
        }
    }
};

复杂度分析

  • 时间复杂度:$O(N)$
  • 空间复杂度:$O(1)$

相关题目

参考代码:

class Solution:
    def partition(self, head: ListNode, x: int) -> ListNode:
        l1 = cur = head
        while cur:
            if cur.val < x:
                cur.val, l1.val = l1.val, cur.val
                l1 = l1.next
            cur = cur.next
        return head

复杂度分析

  • 时间复杂度:$O(N)$,其中 N 为链表长度。
  • 空间复杂度:$O(1)$。

大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 40K star 啦。
大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。

function sortColor(str) {
    return str.split('').sort((a, b) => colorToNum(a) - colorToNum(b)).join('');
  }
function sort(str){
        const arr = ['黄','红','蓝']// 题目要求的顺序
        return  arr.map(item =>{
            const len = str.length // 提取字符长度
            // 对比原长度和切割字符后的长度得出字符数量 根据字符数量创建对应长度的空数组 使用fill方法填充 
            return new Array(len - str.replaceAll(item,'').length).fill(item)
        }).toString() // 构建完毕后toString转换为字符串
    }
const balls = '红蓝蓝黄红黄蓝红红黄红'

function sort(balls) {
    const blist = balls.split('')
    const points = [0, 0, 0]
    const res = []
    for (let i = 0, l = blist.length; i < l; i++) {
        const ball = blist[i]
        switch (ball) {
            case '黄':
                res.splice(points[0], 0, ball)
                points[0]++
                break
            case '红':
                res.splice(points[0] + points[1], 0, ball)
                points[1]++
                break
            case '蓝':
                res.splice(points[0] + points[1] + points[2], 0, ball)
                points[2]++
                break
        }
    }
    return res
}
const strList = '红蓝蓝黄红黄蓝红红黄红';
const colors = ['黄', '红', '蓝'];

console.log(strList.split('').sort((pre, next) => colors.indexOf(pre) - colors.indexOf(next)));

// 上面大佬提到的 挡板法,两个挡板,先把 2 全部移到第二个挡板的后面 然后遍历比较 挡板 1前的 数 和 挡板的大小,将 0 一个个移到挡板 1 前 ,排序完成

var sortColors = function (nums) {
    const len = nums.length;
    let l = 0;
    let r = len - 1;

    for (let i = 0; i < len; i++) {
        while (nums[i] === 2 && i < r) {
            let temp = nums[i];
            nums[i] = nums[r];
            nums[r] = temp;
            r--;
        }
        if (nums[i] === 0) {
            let temp = nums[i];
            nums[i] = nums[l];
            nums[l] = temp;
            l++;
        }
    }
    return nums;
};
const s = '红蓝蓝黄红黄蓝红红黄红';


function swap(arr, i, j) {
    const t = arr[i];
    arr[i] = arr[j];
    arr[j] = t;
}


// 本质上是个双指针问题,
function sort(str) {
    const arr = str.split('');
    const len = arr.length;
    let i = 0;
    let j = 0;

    // 第一遍将黄灯放到最前面
    while (j < len) {
        if (arr[j] === '黄') {
            swap(arr, i, j);
            i++;
        }
        j++;
    }
    j = i;
    // 第二遍从排序好的黄灯下个位置开始排红灯
    while (j < len) {
        if (arr[j] === '红') {
            swap(arr, i, j);
            i++
        }
        j++;
    }
    return arr.join('');
}

console.log(sort(s));
// 黄黄黄红红红红红蓝蓝蓝 
commented
const getNumByType = () => {
   let obj = {
     '黄': 0,
     '红': 1,
     '蓝': 2
   }
   let str = '红蓝蓝黄红黄蓝红红黄红'
   let lis = str.split('')
   let m = lis.sort((a, b) => obj[a] - obj[b]).join('')
 }