題外話
刷了一段時間的codewars的JavaScript題目之后,它給我最大的感受就是,會幫助你迅速的提升你希望練習的語言的API的熟悉程度,Array對象、String對象等原生方法,構造函數、一些算法題等。每次submit之后,看看自己的代碼,再看看別人寫的代碼。發現自己寫的代碼和實現實現思路簡直弱爆了。於是,每次都會在submi完之后,會看看Top five的答案,理解大牛們的解題思路(大多數情況下,代碼會使用ES6的語法,非常簡潔),然后train again。按照這種方法,練習了將近20來天的時間。這是我在codewars上的成果,5kyu,刷了93題,有一些題目實在想不到,就unlock solutions了。因此Honor Completed Kata並不是100%。
最近開始玩leetcode了,換個plaform主要是因為leetcode上的題目大多都是各大互聯網公司的面試題目,而且大多偏向算法。恰巧我最近迫切的想要提高這方面的能力。於是轉移了plaform,雖然我有些不舍:"( 。但是我還是會持續玩codewars的/
1-20 leetcode個人解題思路
實現思路:創建一個空數組,寫兩層循環。第二層循環的變量初始化是基於第一次循環的。接着做判斷,如果nums[i] + nums[j] === target,就退出循環。
//舊思路,由於網友的提出,該算法的時間復雜度為O(n^2)
var twoSum = function(nums, target) {
let index = [];
for (let i = 0; i < nums.length; i++) {
for (let j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] === target) {
index.push(i);
index.push(j);
break;
}
}
}
return index;
};
//新思路:
var twoSum = function(nums, target) {
let arr = [],
obj = {},
len = nums.length;
for (let i = 0; i < len; i++) {
if (obj[target - nums[i]] !== undefined) {
arr[0] = obj[target - nums[i]];
arr[1] = i;
return arr;
}
obj[nums[i]] = i;
}
};
ZigZag Conversion(Difficulty: Easy; Tags: String)
首先,要想完成這道題目,需要明白的是。ZigZag pattern與給定的行數有什么關系。
很簡單,只有2行、3行、4行時zigzag的形狀分別如下
這個題目主要的思路是明白給定的行數與每行中需要提取的字母位置之間的關系。
- 當只有一行時,直接返回原字符串
- 當大於一行時,第一行和最后一行的規律相同,即(假定指定行數是n,此時n>1)每個圓圈(代碼一個值)都是每隔[ n - (n - 2) ] * (n - 1)個位置出現一次
- 除了第一行和最后一行,中間行數圓圈的分布也有規律:畫藍色箭頭的后一個值與前一個值相差 2 * (n - 1)個位置,畫綠色箭頭的兩個值也遵循這個規律。因此,實現代碼如下
var convert = function(s, numRows) {
if (numRows === 1) return s;
let str = '';
let num = (numRows - (numRows - 2)) * (numRows - 1); //2
for (let i = 1; i <= numRows; i++) {
for (let j = i - 1; j < s.length; j += num) {
if (i === 1 || i === numRows) {
str += s.slice(j, j + 1);
} else {
str += s.slice(j, j + 1);
str += s.slice(j + num - (2 * (i - 1)), j + num - (2 * (i - 1)) + 1);
}
}
}
return str;
};
console.log(convert("123456789", 2)); //135792468
console.log(convert("123456789", 3)); //159246837
console.log(convert("123456789", 4)); //172683594
console.log(convert("1234567891234567891234", 5)); //1982817937261463524543
這道題目挺有意思,題目很直接,讓我們將input的指reverse。但是有要求,就是當reverse的值如果超過32bit,就要返回0。
思路是使用JS的或運算|,即位運算符,將reverse的值轉換成32位,然后再與原值作比較。
Math.pow(2, 32)|0
返回0 (Math.pow(2, 32) + 1)|0
返回1。因此解題邏輯為
var reverse = function(x) {
let str1 = x.toString().match(/[0-9]/g).reverse().join('');
let str2 = x.toString().match(/[^0-9]/g) === null ? '' : x.toString().match( /[^0-9]/g).join('');
let num1 = Number(str2 + str1)|0; //reverse and transform to 32bit
let num2 = Number(str2 + str1);
return num1 === num2 ? num2 : 0;
};
這個題目,主要考察對數據類型NaN的理解和對方法isNaN()的理解,同時考察對Number、parseInt、parseFloat方法的區別。這里簡單的聲明一下。
NaN
NaN,即非數值(Not a Number)是一個特殊的數值,這個數值用於表示一個本來要返回數值的操作數
未返回數值的情況(這樣就不會拋出錯誤了)。任何數值除以0會返回NaN。
NaN與任何值都不相等,包括NaN本身。因此console.log(NaN === NaN) // false
isNaN是用來判斷參數是否“不是數值”。
parseInt
parseInt和parseFloat用於將字符串轉換為數值類型,而Number用於轉換任何數據類型,這里主要介紹一下parseInt。
parseInt會忽略字符串前面的空格,直至找到一個非空格字符。如果第一個字符不是數字字符或者負號或者正號,parseInt會返回NaN。也就是說,用parseInt()轉換空字符串會返回NaN(Number()對空字符返回0)如果第一個字符是數字字符,parseInt()會繼續解析第二個字符,直到解析完所有后續字符或者遇到了一個非數字字符。例如,"1234blue"會被轉換為1234,因為"blue"會被完全忽略。類似地,"22.5"會被轉換為22,因為小數點並不是有效的數字字符;'-123'會被轉換為-123,因為第一個字符是負號,而后面的字符都是數字;'-+123'會返回NaN,因為第一個字符是-,而第二個字符卻是+,不符合正常的數值模式。
因此,此題的解題思路如下:
var myAtoi = function(str) {
let symbol = '';
str = str.replace(/^\s+|\s+$/g, '');//去除兩端空格
str = isNaN(parseInt(str)) ? 0 : parseInt(str);
if (str > Math.pow(2, 31) - 1) {
return Math.pow(2, 31) - 1;
} else if (str < - Math.pow(2, 31)) {
return - Math.pow(2, 31);
} else {
return str;
}
};
持續更新中...