【算法訓(xùn)練營day1】LeetCode704. 二分查找 LeetCode27. 移除元素LeetCode704. 二分查找【【算法訓(xùn)練營day1】LeetCode704. 二分查找 LeetCode27. 移除元素】題目鏈接:704. 二分查找
初次嘗試看到題目標(biāo)題是二分查找 , 所以嘗試使用二分查找的思想 , 代碼思路是一直循環(huán)二分 , 直到兩個(gè)指針相等 , 再判定所指元素是否等于target , 這樣對于任何輸入都需要二分至盡頭才能得出結(jié)論 , 果不其然提交后超時(shí) 。
class Solution {public:int search(vector<int>& nums, int target) {int low = 0, up = nums.size() - 1;while (true) {if (target <= nums[(low+up)/2]) {up = (low + up) / 2;}else {low = (low + up) / 2 + 1;}if (low == up) {return target == nums[low] ? low : -1;}}}};看完代碼隨想錄后的想法意識到了不需要對于任何輸入都二分到盡頭 , 可以在二分的過程中判斷target是否與二分的中間點(diǎn)相等 , 如果相等就可以直接返回中間點(diǎn)的下標(biāo)(當(dāng)然這是在數(shù)組元素都不重復(fù)的前提下) 。這是符合邏輯的 , 畢竟如果在二分判定的過程中已經(jīng)找到了和target相等元素的下標(biāo) , 何必繼續(xù)二分到盡頭呢?直接返回不就完事了!
關(guān)于題解中講到的循環(huán)不變量 , 也就是左閉右閉等的問題 , 我感覺對我個(gè)人不是難點(diǎn) , 在初次嘗試中就有類似的思考過程 , 感覺對于邊界開閉的留意已經(jīng)是一種習(xí)慣了 , 故在此不再贅述 。
class Solution {public:int search(vector<int>& nums, int target) {int low = 0, up = nums.size() - 1;// 左閉右閉while (low <= up) {int mid = (low + up) / 2;if (target < nums[mid]) up = mid - 1;else if (target > nums[mid]) low = mid + 1;else return mid;}return -1;}};LeetCode27. 移除元素題目鏈接:27. 移除元素
初次嘗試思路是使用暴力解法 , 直接兩個(gè)for循環(huán) , 外層遍歷數(shù)組 , 內(nèi)層尋找等于val的元素并更新數(shù)組 。
class Solution {public:int removeElement(vector<int>& nums, int val) {int numslen = nums.size();for (int i = 0; i < numslen; i++) {if (nums[i] == val) {for (int j = i + 1; j < numslen; j++) {nums[j-1] = nums[j];}numslen--;i--;}}return numslen;}};然后想到當(dāng)有連續(xù)多個(gè)等于val的元素時(shí) , 每個(gè)都要更新一次實(shí)在是平添時(shí)間復(fù)雜度 , 于是修改了一下 , 當(dāng)遇到連續(xù)多個(gè)等于val的元素時(shí) , 判定一下有幾個(gè) , 然后一次性更新數(shù)組 , 看似優(yōu)化了 , 其實(shí)換湯不換藥 , 仍然是嵌套著的for循環(huán) , 沒有大的優(yōu)化 。
class Solution {public:int removeElement(vector<int>& nums, int val) {int numslen = nums.size();for (int i = 0; i < numslen; i++) {int k = 0;for (int j = i; j < numslen; j++) {if (nums[j] == val) k++;else break;}if (k > 0) {for (int j = i + k; j < numslen; j++) {nums[j-k] = nums[j];}numslen -= k;}}return numslen;}};看完代碼隨想錄后的想法雙指針真是yyds!其實(shí)看到題解視頻的開頭我就突然明白怎么用雙指針了 , 定義一個(gè)慢指針和一個(gè)快指針 , 快指針負(fù)責(zé)遍歷整個(gè)數(shù)組 , 找出可以留下來的元素 , 每找到一個(gè)就把它告訴慢指針 , 慢指針只需要聽令 , 把可以留下來的元素放到現(xiàn)在的坑里 , 然后+1跳到下一個(gè)坑即可 。之所以有快慢指針之分是因?yàn)槊看蝔or循環(huán) , 快指針都會+1 , 而慢指針看情況+1(當(dāng)快指針指向可以留下來的元素的時(shí)候) , 所以慢指針一定不快于快指針 。
class Solution {public:int removeElement(vector<int>& nums, int val) {int numslen = nums.size();int slow = 0;for (int fast = 0; fast < numslen; fast++) {if (nums[fast] != val) {nums[slow++] = nums[fast];}}return slow;}};
經(jīng)驗(yàn)總結(jié)擴(kuò)展閱讀
- CAN隨機(jī)度測試
- AVX圖像算法優(yōu)化系列二: 使用AVX2指令集加速查表算法。
- 盒裝豆腐放冰箱能放幾天
- 感情熬到盡頭就分開的星座
- 哪些星座女假分手常常變真分手
- 冰美式和冰拿鐵的區(qū)別
- 黑芝麻煮粥可以直接放進(jìn)煮嗎
- 木姜子的食用方法
- 青島啤酒節(jié)白天開嗎
- 在愛人面前會變得蠢蠢的星座
