codewar上看到的题目,挑战的题目是:
从一堆数中找到唯一一个奇数或偶数,并告知他的排位(1打头)
’1 2 4 6‘ => 1
‘2 2 1 2 2 4 8’ => 3
’1 3 5 7 8’ => 5
题目简单,答案却依然可分三六九等
初级程序员的方案
1 2 3 4 5 6 7 8
| function iqTest(numbers){ numbers = numbers.split(" ").map(function(el){return parseInt(el)}); var odd = numbers.filter(function(el){ return el % 2 === 1}); var even = numbers.filter(function(el){ return el % 2 === 0}); return odd.length < even.length ? (numbers.indexOf(odd[0]) + 1) : (numbers.indexOf(even[0]) + 1); }
|
这个方案得票很高,非常的直观,但是效率恐怕?
- 使用了模运算判断奇偶数
- filter执行了两次
中级程序员的方案
1 2 3 4 5 6 7
| function iqTest(numbers){ var even = [], odd = []; numbers.split(" ").map((num, idx) => { num & 1 ? odd.push(idx): even.push(idx) }) return (even.length === 1 ? even[0] : odd[0]) + 1 }
|
这个方案好多了,不仅减少了一次循环,而且使用位运算判断奇数偶数。
高级程序员的方案
哪里还能优化呢? 考虑一组数有1000000个,第一个是奇数,其余都是偶数。还需要循环全部的数吗?
1 2 3 4 5 6 7 8 9 10
| function iqTest(numbers){ numbers = numbers.split(' '); var bitsum = ( (numbers[0] & 1) + (numbers[1] & 1) + (numbers[2] & 1) ); var needle = (bitsum < 2) ? 1 : 0; for(var i=0; i<numbers.length; i++){ if ((numbers[i] & 1) == needle){ return i+1; } } }
|
我的方案
性能还好,简洁性就差了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| function isEven(num) { return (num & 1) === 0; } function iqTest(numbers){ // ... let lastEvenIdx = 0; let lastOddIdx = 0; let evencnt =0; let oddcnt =0; let numarr = numbers.split(' '); for(let i=0;i<numarr.length;i++) { if(isEven(Number(numarr[i]))) { evencnt ++; lastEvenIdx = i+1; } else { oddcnt ++; lastOddIdx = i+1; } if(evencnt >= 2 && oddcnt > 0) return lastOddIdx; else if(oddcnt >=2 && evencnt > 0) return lastEvenIdx; } return 0; }
|
其他有趣的方案
利用正则表达式
1 2 3 4
| function iqTest(numbers){ var m = numbers.match(/[02468]\b.*[02468]\b/.test(numbers) ? /\d*[13579]\b/ : /\d*[02468]\b/)[0]; return numbers.split(' ').indexOf(m) + 1; }
|
你有更好的方案吗?
AD