題目列表
第一題:數組連續數相加求最大和
題目
maxSequence([-2, 1, -3, 4, -1, 2, 1, -5, 4])
// should be 6: [4, -1, 2, 1]
如果最大和小於零就返回零
代碼
// 原始思路:遍歷相加,如果遇到更大和值,就替換掉當前最大和
var maxSequence = function(arr){
// ...
var total = 0;
for (var i = 0; i < arr.length; i++) {
for (var j = i,sum=0; j < arr.length; j++) {
sum += arr[j];
total = Math.max(sum,total)
}
}
return total
}
// 答案區代碼
/**
一、有點不太好懂
解析:
sum 值和目前最小值比較,更小的爲最小值,這個最小值就是也就是目前累加的值
以相加的和想象爲折線圖作爲理解方式,最大的和應該是最大峯值減去最小低谷的值
*/
var maxSequence = function(arr){
var min = 0, ans = 0, i, sum = 0;
for (i = 0; i < arr.length; ++i) {
sum += arr[i];
min = Math.min(sum, min);
ans = Math.max(ans, sum - min);
}
return ans;
}
第二題:根據字符串中的數字排序
題目
Examples
“is2 Thi1s T4est 3a” --> “Thi1s is2 3a T4est”
“4of Fo1r pe6ople g3ood th5e the2” --> “Fo1r the2 g3ood 4of th5e pe6ople”
“” --> “”
代碼
// 原始思路
function order(words){
// ...
return words.split(' ').sort((a,b) =>
a.replace(/[a-z]/gi,'') - b.replace(/[a-z]/gi,'')
).join(' ')
}
// 答案區正則有更簡單的寫法
function order(words){
return words.split(' ').sort(function(a, b){
return a.match(/\d/) - b.match(/\d/);
}).join(' ');
}
第三題:數字處理後排序
題目
“56 65 74 100 99 68 86 180 90” ordered by numbers weights becomes: “100 180 90 56 65 74 68 86 99”
56 = 5+6=11 這樣計算完之後再進行排序,比較規則難受的地方在於如果如果遇到前後兩個相等的情況,需要用字符串的比較規則再對其進行排序
代碼
// 原始思路
function orderWeight(strng) {
// your code
return strng.split(' ').sort((a,b) => {
let ta = a.split('').reduce((c,d)=>(c-(-d))) - b.split('').reduce((e,f)=>(e-(-f)))
switch(true){
case ta < 0: return -1;break;
case ta > 0: return 1;break;
case ta == 0: return a < b ? -1 : 1
}
}).join(' ')
}
// 答案區解決方法
// 一、localeCompare 比較字符串
function orderWeight(strng) {
const sum = (str)=>str.split('').reduce((sum,el)=>(sum+(+el)),0);
function comp(a,b){
let sumA = sum(a);
let sumB = sum(b);
return sumA === sumB ? a.localeCompare(b) : sumA - sumB;
};
return strng.split(' ').sort(comp).join(' ');
}
第四題:正則匹配
題目
至少六個字符
包含小寫字母
包含大寫字母
包含數字
有效密碼只能是字母數字字符。
代碼
// 原始思路
function validate(password) {
console.log(password)
return /.{6,}/.test(password)
&& /[A-Z]+/.test(password)
&& /[a-z]+/.test(password)
&& /[0-9]+/.test(password)
&& !/[^0-9A-z]+/.test(password);
}
// 答案區的正則
/**
[^abc] 查找任何不在方括號之間的字符。
^n 匹配任何開頭爲 n 的字符串。
n$ 匹配任何結尾爲 n 的字符串。
?=n 匹配任何其後緊接指定字符串 n 的字符串。
這個舉例如下方便理解:
var str="Is this all there is";
var patt1=/is(?= all)/g;
匹配到的是 this 中的 is
所以下面的正則意味着不論匹配到什麼都會返回到初始位置
*/
function validate(password) {
return /^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])\w{6,}$/.test(password);
}
第五題:數組比較與去重
題目
有一個序列u,其中u的定義如下:
u[0]= 1是u中的第一個數字。
對於u中的每個x,y = 2 * x + 1和z = 3 * x + 1也必須在u中。
例如:u = [1、3、4、7、9、10、13、15、19、21、22、27,…]
求出 u[n] 的值
代碼
// 原始思路
/**
這裏有個問題就是 i < 5*n 這一塊有待優化,當查詢的n更大時,5就不夠用了
*/
function dblLinear(n) {
// your code
let arr = [1];
for(let i=0;i<5*n;i++){
// 實驗push返回值爲數組長度
arr[arr.push(arr[i]*2 + 1)] = arr[i]*3 + 1;
}
// 去重並過濾
arr = arr.sort((a,b)=>a-b).filter((e,i,arr) => e !== arr[i-1])
return arr[n]
}
// 答案區優秀算法
// 一、爲 2x+1 和 3x+1 分別設置標識,這裏的 eq 用於保證 ai 和 bi 相等時繼續運行
function dblLinear(n) {
var ai = 0, bi = 0, eq = 0;
var sequence = [1];
while (ai + bi < n + eq) {
var y = 2 * sequence[ai] + 1;
var z = 3 * sequence[bi] + 1;
if (y < z) { sequence.push(y); ai++; }
else if (y > z) { sequence.push(z); bi++; }
else { sequence.push(y); ai++; bi++; eq++; }
}
return sequence.pop();
}
// 二、這裏爲源代碼補充了相鄰數字去重,然而實際上運行不到需要去重的那一步,
// 比如 2*15+1 = 3*10+1;當 n 爲 20 時,i 運行到 14 就已經停下了
function dblLinear(n) {
var h = [];
var x2 = 1, x3 = 1;
var i = 0, j = 0;
for (var index = 0; index < n+1; index++)
{
h[index] = x2 < x3 ? x2 : x3;
if (h[index] == x2) x2 = 2 * h[i++] + 1;
if (h[index] == x3) x3 = 3 * h[j++] + 1;
}
h=h.filter((e,i,arr) => e !== arr[i-1])
return h[n];
}
第六題:處理連續數字
題目
對連續的數字進行處理
Example:
solution([-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]);
// returns “-6,-3-1,3-5,7-11,14,15,17-20”
代碼
// 原始思路,使用map拷貝成新數組
// 從後往前檢查,有幾個連續的數,就對這幾個數進行替換
// 使用變量 a 作爲連續數字數量判斷標識
function solution(list){
// TODO: complete solution
var a=0;
var c = list.map(item=>item);
for(var i=list.length-1;i>=0;i--){
if(list[i] - list[i-1] == 1){
a++;
}else {
if(a>1){c.splice(i,a+1,(list[i])+'-'+(list[i+a]))}
a=0;
}
}
return c.toString()
}
// 答案區處理方式差不多
return c.join()
第七題:將零移動到數組末尾
題目
將所有零移動到末尾的算法,同時保留其他元素的順序
moveZeros([false,1,0,1,2,0,1,3,“a”]) // returns[false,1,1,2,1,3,“a”,0,0]
代碼
// 原始思路
var moveZeros = function (arr) {
// TODO: Program me
var i = 0;
arr = arr.filter((item) => {
if(item !== 0) return true;
i++; return false
})
while(i>0){
arr.push(0);
i--
}
return arr
}
// 答案區代碼
// 一、先取出非零的,在取出爲零的,進行拼接
var moveZeros = function (arr) {
return arr.filter(function(x) {return x !== 0}).concat(arr.filter(function(x) {return x === 0;}));
}
第八題:求數組差值和
題目
[
[1,4],
[7, 10],
[3, 5]
]
這些間隔的長度之和爲7。由於[1,4]和[3,5]重疊,我們可以將間隔視爲[1,5],其長度爲4。
Examples:
sumIntervals( [
[1,2],
[6, 10],
[11, 15]
] ); // => 9
sumIntervals( [
[1,4],
[7, 10],
[3, 5]
] ); // => 7
代碼
// 原始思路,循環比較,計算差值再相加,簡直是代碼區的泥石流
// 可讀性差,也不如代碼區的思路簡單
function sumIntervals(intervals){
//TODO
var newArr = intervals.map(item=>item);
if(intervals.length > 1){
for(var i=0;i<newArr.length;i++){
for(var j=i+1;j<newArr.length;j++){
if(newArr[i][1] <= newArr[j][1] && newArr[i][1] >= newArr[j][0]){
if(newArr[i][0] < newArr[j][0]){
newArr[j][0] = newArr[i][0];
}
newArr[i] = [0,0]
}else if(newArr[j][1] <= newArr[i][1] && newArr[j][1] >= newArr[i][0]){
if(newArr[j][0] < newArr[i][0]){
newArr[i][0] = newArr[j][0];
}
newArr[j] = [0,0]
}
}
}
console.log(intervals,newArr)
return newArr.map(a=>a[1]-a[0]).reduce((a,b)=>a+b)
}else{
return newArr[0][1] - newArr[0][0]
}
}
// 答案區代碼
// 一、創建一個新數組,用於存儲區間內數字
// 重複的數字不會存儲進去,這樣最終計算數組的長度就是要求的值
// 美中不足速度有待提高
function sumIntervals(intervals){
var numbers = [];
intervals.forEach(([a,b])=>{
for (a; a<b; a++) {
if (numbers.indexOf(a) == -1) numbers.push(a);
}
});
return numbers.length;
}
第九題:字符串高位補零
題目
Examples:
foo -> foo1
foobar23 -> foobar24
foo0042 -> foo0043
foo9 -> foo10
foo099 -> foo100
代碼
// 原始思路,把數字部分抽出來加一,並對其長度進行高位補零
function incrementString (strng) {
// return incrementedString
const num = strng.split('').filter(item=>/[0-9]$/.test(item)).join('');
return strng.split('').filter(item=>/[^0-9]$/.test(item)).join('')
.concat((''+(+num+1)).length > num.length
? (+num+1)
: (Array(num.length).join(0)+(+num+1)).slice(-num.length))
}
// 答案區的寫法
// 一、一個有趣的寫法
function incrementString(str){
var c = str[str.length-1];
switch(c){
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8': return str.substring(0, str.length-1) + (parseInt(c)+1);
case '9': return incrementString(str.substring(0, str.length-1)) + 0;
default: return str+"1";
}
}
// 二、最簡單的寫法,我想我得好好研究一下正則了
let incrementString = str => str.replace(/([0-8]|\d?9+)?$/, (e) => e ? + e + 1 : 1)
第十題:數組累加
題目
4 * (1 + 1 + 2 + 3 + 5 + 8) = 4 * 20 = 80
perimeter(5) should return 80
perimeter(7) should return 216
代碼
// 原始想法
function perimeter(n) {
let arr = [1,1],i=1;
if(n<1) return 4;
while(i<n){
arr.push(arr[i] + arr[i-1])
i++
}
return 4 * arr.reduce((a,b)=>a+b)
}
// 答案區寫法差不多