前面說了這麼多,終於可以來刷 LeetCode 了! 像 前一章 說的,刷題沒有任何第三方工具可以使用,必須對語法本身相當熟練(例如 javaScript)。所以這一系列我都會先介紹某個演算法/資料結構概念再進行刷題,今天要刷 Array,所以若沒有看過之前的文章沒關係,但至少要看這篇 陣列 Array
/*
Given an array A of non-negative integers,
return an array consisting of all the even elements of A,
followed by all the odd elements of A.
You may return any answer array that satisfies this condition.
input: 給一個沒有負數的數字陣列
output: 回傳前面是偶數後面是奇數的陣列
Example 1:
Input: [3,1,2,4]
Output: [2,4,3,1]
The outputs [4,2,3,1], [2,4,1,3], and [4,2,1,3] would also be accepted.
Note:
1 <= A.length <= 5000
0 <= A[i] <= 5000
*/
/**
* @param {number[]} A
* @return {number[]}
*/
var sortArrayByParity = function(A) {
};
個人英文也不是高手無法馬上就 100% 理解題目。所以我看完題目後,會更認真看範例從中再回去理解題目是什麼。例如忘了 odd 跟 even 哪個是奇數哪個偶數,看範例就很容易得到解答
Output: [2,4,3,1] → 先偶數 (even) 再奇數 (odd)
這邊通常會想完之後再打掉,想完再打掉,直到覺得可行再來寫。當然也是可以邊寫邊想啦!
// 大概是這種概念
[3, 1, 2, 4]
[ ] ← 3
[3] ← 1
2 → [3, 1]
4 → [2, 3, 1]
[4, 2, 3, 1]
var sortArrayByParity = function(A) {
// 先處理極限值
if(A.length < 2){
return A
};
// 把想法變成程式碼實踐
let temp = []
A.forEach( item => {
item%2==0 ? temp.unshift(item) : temp.push(item)
})
return temp
};
Array 遍歷ㄧ次,所以時間複雜度是 Big O(n)
/*
Given an array of 2n integers, your task is to group these integers into n pairs of integer, say (a1, b1), (a2, b2), ..., (an, bn) which makes sum of min(ai, bi) for all i from 1 to n as large as possible.
input: 給一個偶數的陣列
output: 回傳 min(a1, b1) + ... min(ai, bi) 的最大值
這種中文好難翻譯,先看範例會比較清楚
Example 1:
Input: [1,4,3,2]
Output: 4
Explanation: n is 2, and the maximum sum of pairs is 4 = min(1, 2) + min(3, 4).
Note:
n is a positive integer, which is in the range of [1, 10000].
All the integers in the array will be in the range of [-10000, 10000].
*/
/**
* @param {number[]} nums
* @return {number}
*/
var arrayPairSum = function(nums) {
};
var arrayPairSum = function(nums) {
const len = nums.length;
let result = 0;
nums = nums.sort((a,b) => a-b);
for(let i= 0; i < len; i += 2){
result += Math.min(nums[i], nums[i+1])
}
return result;
};
這題時間複雜度是 Big O(nlogn) (謝謝邦友 huli 更正指教)
這邊只是簡單分享個人思考題目的過程而已,畢竟 LeetCode 需要實際練習才能知道箇中滋味。而 Array 其實相當重要也是最好入門的題目之一 (好歹平常專案還是會碰到的)。他相關題目可是有高達 192 題呢 (而且應該會越來越多 ... )。
下一篇會來介紹跟 Array 不太一樣的資料結構 Set
歡迎追蹤我的部落格,除了技術文也會分享一些在矽谷工作的甘苦。
Array Partition I 那題時間複雜度不是 O(n) 喔,因為有用到排序了,所以應該是 O(nlogn)
然後第一題的解法有點小奇怪
奇怪的第一個點是針對 A.length < 2 的情形,應該不用特別做處理。第二個點是 filter 不該這樣用,如果是面試的話應該會被問說:「為什麼這邊要用 filter?」,比較好的做法是用 foreach 或是 for loop 就好,因為你本來的目的就是遍歷陣列,而不是想要過濾掉東西。
謝謝建議 對我的確寫錯了不應該是 filter 是 forEach,這樣時間複雜度應該就是 Big O(n) 了
我說的其實是不同題XD
時間複雜度我講的是第二題 561. Array Partition I 這個,原文裡面寫:「時間複雜度是 Big O(n),因為時間複雜度會忽略所有係數。」,但要注意的是這一題是「先排序過後」才解的,排序本身的時間複雜度就是 O(nlogn)了,所以整個解法的複雜度就是 O(nlogn)
原來是我誤會了XD 謝謝
第二題的 561. Array Partition I 其實不用 Math.min(),因為排序過了, index 為偶數的就是比較小的數字
在第一題「905. Sort Array By Parity」的部分,我的思考方向跟你有點小不同:
這部分我看了你使用 unshift
,我認為比較不好的原因是,
每次 unshift 需要重新將所有的 index 做調整,
所以實際上 unshift 為 O(n),loop 為 O(n),
所以照此做法平均上可能會是 O(n^2)。
而我一開始想到的是分別放到兩個 array,最後再 concat 起來。
依照此方法,則會是 O(n)+O(n) --> O(n),但會比原本多花點時間建 array。
接下來我又想再做個小改進,覺得可以改成用兩個 pointer 指向前後,
如此可以先用 new Array(length)
先建立一個固定大小的 Array,
認為如此可以再改進一直擴容的問題。
以上一些想法供參考,也歡迎有更多意見一起討論。