?347. 前 K 個高頻元素
題目鏈接:347. 前 K 個高頻元素
難度:中等
刷題狀態:1刷
新知識:
解題過程
思考
示例 1:
輸入: nums = [1,1,1,2,2,3], k = 2 輸出: [1,2]
沒思路,看答案
題解分析
參考題解鏈接:240. 搜索二維矩陣 II(貪心,清晰圖解)
詳細分析如下,時間復雜度:O(nlogn)
/*** @param {number[]} nums* @param {number} k* @return {number[]}*/
var topKFrequent = function(nums, k) {//使用map統計每個元素出現的次數let map=new Map()for(let num of nums){if(!map.has(num)) map.set(num,0)map.set(num,map.get(num)+1)}//map變成arry再排序let res=[]let sort=Array.from(map).sort((a,b)=>b[1]-a[1]).forEach(([key,val])=>{if(!k) returnk--res.push(key)})return res
};
手搓答案(無非廢話版)
/** * @param {number[]} nums* @param {number} k* @return {number[]}*/var topKFrequent=function(nums,k){let res=[],map=new Map()for(let n of nums){if(!map.has(n)) map.set(n,0)map.set(n,map.get(n)+1)}Array.from(map).sort((a,b)=>b[1]-a[1]).forEach(([key,val])=>{if(!k) return k--res.push(key)})return res}
總結
?拿下,如果要用最小棧的方法,那就很復雜了,,我看不懂
?295. 數據流的中位數
題目鏈接:??????????????295. 數據流的中位數
難度:困難
刷題狀態:1刷
新知識:
-?優先隊列(MaxPriorityQueue 和 MinPriorityQueue)
-?this.right.enqueue(num); // 將新元素加入大頂堆
-?this.right.dequeue() //彈出堆頂元素
-?this.right.front()?//front 方法返回堆頂元素而不移除它
-?this.left.size()和length一樣
解題過程
思考
輸入 ["MedianFinder", "addNum", "addNum", "findMedian", "addNum", "findMedian"] [[], [1], [2], [], [3], []] 輸出 [null, null, null, 1.5, null, 2.0]
定義類的題目,不會,看答案
題解分析
參考題解鏈接:???????如何自然引入大小堆?簡潔寫法!(Python/Java/C++/Go/JS/Rust)
詳細分析如下
var MedianFinder = function() {//優先隊列(MaxPriorityQueue 和 MinPriorityQueue)this.left = new MaxPriorityQueue(); // 小頂堆,用于存儲較小的一半this.right = new MinPriorityQueue(); // 大頂堆,用于存儲較大的一半
};MedianFinder.prototype.addNum = function(num) {if (this.left.size() === this.right.size()) {this.right.enqueue(num); // 將新元素加入大頂堆this.left.enqueue(this.right.dequeue()); // 將小頂堆的堆頂元素(即 right 中的最小元素)移到大頂堆,以保持 left 中的元素始終不大于 right 中的元素。} else {this.left.enqueue(num);// 將新元素加入小頂堆this.right.enqueue(this.left.dequeue()); // 將大頂堆的堆頂元素(即 left 中的最大元素)移到小頂堆,以保持 right 中的元素始終不小于 left 中的元素。}
};MedianFinder.prototype.findMedian = function() {//front 方法返回堆頂元素而不移除它if (this.left.size() > this.right.size()) {return this.left.front();}return (this.left.front() + this.right.front()) / 2;
};
手搓答案(無非廢話版)
var MedianFinder=function(){this.left=new MaxPriorityQueue()this.right=new MinPriorityQueue()
}MedianFinder.prototype.addNum=function(num){if(this.left.size()==this.right.size()){this.right.enqueue(num)this.left.enqueue(this.right.dequeue())}else{this.left.enqueue(num)this.right.enqueue(this.left.dequeue())}
}MedianFinder.prototype.findMedian=function(){if(this.left.size()>this.right.size()){return this.left.front()}else{return (this.left.front()+this.right.front())/2.0}
}
總結
?新知識優先隊列,元素的出隊順序不是按照它們進入隊列的順序,而是根據它們的優先級。
????????121. 買賣股票的最佳時機
題目鏈接:??????????????121. 買賣股票的最佳時機
難度:簡單
刷題狀態:1刷
新知識:
解題過程
思考
示例 1:
輸入:[7,1,5,3,6,4] 輸出:5 解釋:在第 2 天(股票價格 = 1)的時候買入,在第 5 天(股票價格 = 6)的時候賣出,最大利潤 = 6-1 = 5 。注意利潤不能是 7-1 = 6, 因為賣出價格需要大于買入價格;同時,你不能在買入前賣出股票。
貪心算法類型題目
題解分析
參考題解鏈接:???????買賣股票的最佳時機
詳細分析如下,
/*** @param {number[]} prices* @return {number}*/
var maxProfit = function(prices) {let minprice=Infinity,maxprofit=0for(let p of prices){//比較利潤最大值maxprofit=Math.max(p-minprice,maxprofit)//更新最小價格minprice=Math.min(minprice,p)}return maxprofit
};
手搓答案(無非廢話版)
/*** @param {number[]} prices* @return {number}*/var maxProfit=function(prices){let minp=Infinity,res=0for(let p of prices){res=Math.max(p-minp,res)minp=Math.min(minp,p)}return res}
總結
?拿下,基礎貪心算法題
????????55. 跳躍游戲
題目鏈接:?????????????????????55. 跳躍游戲
難度:中等
刷題狀態:1刷
新知識:
解題過程
思考
示例?1:
輸入:nums = [2,3,1,1,4] 輸出:true 解釋:可以先跳 1 步,從下標 0 到達下標 1, 然后再從下標 1 跳 3 步到達最后一個下標。
題解分析
參考題解鏈接:??????????????【跳躍游戲】別想那么多,就挨著跳吧
詳細分析如下,
/*** @param {number[]} nums* @return {boolean}*/
var canJump = function(nums) {//step表示當前位置能到的最遠下標let step=0for(let i=0;i<nums.length;i++){if(step>=nums.length-1) return true//提前結束if(i>step) return false//全部循環完了還是走不到step=Math.max(step,i+nums[i])}
};
手搓答案(無非廢話版)
/*** @param {number[]} nums* @return {boolean}*/var canJump=function(nums){let step=0,n=nums.lengthfor(let i=0;i<n;i++){if(step>=n-1) return trueif(step<i) return falsestep=Math.max(step,i+nums[i])}}
總結
?拿下
????????45. 跳躍游戲 II
題目鏈接:?????????????????????45. 跳躍游戲 II
難度:中等
刷題狀態:1刷
新知識:
解題過程
思考
示例 1:
輸入: nums = [2,3,1,1,4] 輸出: 2 解釋: 跳到最后一個位置的最小跳躍數是2
。從下標為 0 跳到下標為 1 的位置,跳?1
?步,然后跳?3
?步到達數組的最后一個位置。
題解分析
參考題解鏈接:??????????????【跳躍游戲 II】別想那么多,就挨著跳吧 II
詳細分析如下,
/*** @param {number[]} nums* @return {number}*/
var jump = function(nums) {//end是跳躍邊界let res=0,end=0,step=0for(let i=0;i<nums.length-1;i++){step=Math.max(step,i+nums[i])if(i==end){//說明已經到邊界了,更新邊界為當前能到達的最遠距離end=step//走了一步res++}}return res
};
手搓答案(無非廢話版)
/*** @param {number[]} nums* @return {number}*/var jump=function(nums){let res=0,end=0,step=0,n=nums.lengthfor(let i=0;i<n-1;i++){step=Math.max(step,i+nums[i])if(i==end){end=stepres++}}return res}
總結
重點理解end的作用,end相當于在每一段(一步)中找最大值
循環條件?i < nums.length - 1
?的使用是為了避免在最后一個元素時進行不必要的跳躍檢查。
不需要在最后一個元素跳躍:
- 目標是到達數組的最后一個位置,而不是超過它。