第 135 题:算法题
yygmind opened this issue · 77 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)
/**
* 根据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(''), ['红', '黄', '蓝'])
);
GitHub markdown 语法高亮写法普及推广下: https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown
写的比较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')));
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 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))
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, '蓝')
}
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('')
一行代码嘻嘻
慢慢往下看,总是有惊喜!
算法题目,想了个原地改变数组的办法:
- 把黄色都移动到前面
- 把蓝色都移动到后面
- 剩下的自然都是红色,不用管了就
// 黄,红,蓝
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('')));
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
}, [])
}
算法题目,想了个原地改变数组的办法:
- 把黄色都移动到前面
- 把蓝色都移动到后面
- 剩下的自然都是红色,不用管了就
// 黄,红,蓝 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(''))
"红蓝蓝黄红黄蓝红红黄红".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('');
}
'红蓝蓝黄红黄蓝红红黄红'.split('').sort((a,b) => {if(a=='黄' || b=='蓝'){return -1}}).join('')
算法题目,想了个原地改变数组的办法:
- 把黄色都移动到前面
- 把蓝色都移动到后面
- 剩下的自然都是红色,不用管了就
// 黄,红,蓝 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)。
解法二 - 挡板法
我们可以把数组分成三部分,前部(全部是 0),中部(全部是 1)和后部(全部是 2)三个部分。每一个元素(红白蓝分别对应 0、1、2)必属于其中之一。将前部和后部各排在数组的前边和后边,中部自然就排好了。
我们用三个指针,设置两个指针 begin 指向前部的末尾的下一个元素(刚开始默认前部无 0,所以指向第一个位置),end 指向后部开头的前一个位置(刚开始默认后部无 2,所以指向最后一个位置),然后设置一个遍历指针 current,从头开始进行遍历。
形象地来说地话就是有两个挡板,这两个挡板实现我们不知道,我们的目标就是移动挡板到合适位置,并且使得挡板每一部分都是合适的颜色。
还是以题目给的样例来说,初始化挡板位置为最左侧和最右侧:
读取第一个元素是 2,它应该在右边,那么我们移动右边地挡板。
带有背景色的圆圈 1 是第一步的意思。
并将其和移动挡板后挡板右侧地元素进行一次交换,这意味着“被移动挡板右侧地元素已就位”。
。。。
整个过程大概是这样的:
这种思路的时间复杂度也是$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));
// 黄黄黄红红红红红蓝蓝蓝
const getNumByType = () => {
let obj = {
'黄': 0,
'红': 1,
'蓝': 2
}
let str = '红蓝蓝黄红黄蓝红红黄红'
let lis = str.split('')
let m = lis.sort((a, b) => obj[a] - obj[b]).join('')
}