老規矩,題目鏈接:https://leetcode-cn.com/problems/can-place-flowers/
這是一道簡單題,解題最重要的部分就是抽象,將問題的解抽象爲除法運算,求出兩個1
之間的0
的個數,-1
後/2
並向下取整就能得到這兩個1
之間可以種的花的數目,最後做判斷,即爲題解。
本人想到兩種解法,基本原理類似,如果別的小夥伴還有更好的解決辦法或是覺得我的方法不正確,歡迎大家在評論區提出來~
解法1:
export default (arr, n) => {
let cnt = 0;
let max = 0;
let len = arr.length;
// first中保存第一個1出現的下標
let first = arr.indexOf(1);
// last中保存最後一個1出現的下標
let last = arr.lastIndexOf(1);
// 核心算法:返回兩個1之間可以種的花的數目
let MAX = (sum) => {
return Math.floor((sum - 1) / 2);
}
// 記錄兩個1之間0的個數並求可以種的花的數目,加到max中
for (let i = first + 1; i < last + 1; i++) {
if (arr[i] === 0) {
cnt++;
} else {
max += MAX(cnt);
cnt = 0;
}
}
if (first === -1) {
// 若數組全爲0,則可以種的花的數目直接由數組長度/2並向上取整
max = Math.ceil(len / 2);
} else {
// 若數組不全爲0,則需要考慮開頭和結尾可以種的花的數目,用開頭和結尾的0的個數/2並向下取整,加到max中
max += (Math.floor(first / 2) + Math.floor((len - 1 - last) / 2));
}
// 判斷n是否小於或等於可種花的總數,是則返回true,否則返回false
if (n <= max) {
return true;
} else {
return false;
}
}
解法1思路如下:
首先將數組arr
頭部和尾部的0
全部去掉,只計算第一個1
和最後一個1
之間可以種的花的數目(至於爲什麼要這樣做,因爲頭和尾的0
只需要判斷一邊是否有1
,而第一個1
和最後一個1
之間的0
就需要判斷兩側是否有1
),然後就是一個純數學問題,找規律,兩個1
之間連續3個0
就能種1朵花,連續5個0
就能種2朵……以此類推,發現連續0
的個數/2
然後向下取整就能得到這兩個1
之間可以種的花的數目,最後就能求得第一個1
和最後一個1
之間可以種的花的數目,然後再來計算首尾可以種的花的數目,求得總數max
,與參數n
做比較,如果n <= max
則返回true
,否則返回false
,即爲題解。
解法2:
export default (arr, n) => {
let max = 0;
// 向數組的首尾都添加一個0
arr.unshift(0);
arr.push(0);
// 遍歷整個數組
for (let i = 1, len = arr.length; i < len - 1; i++) {
// 當下標爲i的元素爲0時,判斷其左右兩側是否爲0,是則計數器max++,且指針i++
if (!arr[i]) {
if (arr[i - 1] === 0 && arr[i + 1] === 0) {
max++;
// 這是一個縮短運行時長的方法,可有可無,不影響結果
if (max === n) {
return true;
}
i++;
}
}
}
// 判斷n是否小於或等於可種花的總數,是則返回true,否則返回false
return n <= max ? true : false;
}
解法2思路如下:
先將數組的首尾都補上一個0
方便後面使用同樣的條件來判斷是否可以種下一朵花,然後遍歷整個數組,判斷下標爲i
的元素是否爲0
且左右兩側是否也爲0
,是則計數器max++
,且指針i++
(爲什麼指針i
還要自加一次?因爲確定該元素和其左右兩側元素都爲0
後,右側的0
就不能再填1
了),最後求得總數max
,與參數n
做比較,如果n <= max
則返回true
,否則返回false
,即爲題解。
小結:
這道題只要將問題成功抽象了,基本上就解出來了,但是這題裏面坑有點多,必須考慮數組首尾的0
、數組元素全爲0
以及數組只有1個元素的情況。
解題筆記:
- indexOf方法可以返回參數在數組中第一次出現的下標,同理lastIndexOf方法可以返回參數在數組中最後一個次出現的下標
- Math.ceil方法可以返回一個數向上取整的結果,Math.floor方法可以返回一個數向下取整的結果
- 解題過程中可以加入一些條件使得耗費時間減少