貢獻者: 姆咪-MUMI
🧔:interviewer 👶:interviewee
模擬面試錄影(漢)
模擬面試錄影(漢)
模擬面試錄影(英)
🧔:你好,同學我是這次的面試官,我這裡有一道題目想請你作答。我會給你一串陣列裡面有「7,1,5,3,6,4」這六個數字,請你把它當作股票的價格,去尋找一段買賣時機來獲得最大收益。舉剛剛的例子在第二天買入股票,在第五天賣出,獲得最大收益為5;那如果你發現這一串陣列沒有任何收益的話,請你輸出為0
👶:我呢!一開始直覺上會想要用暴力法,類似這樣(開始用小畫家畫圖),用兩層迴圈,假設i是他然後再找j(也就是i後面這一串數字),和它相減來獲得這輪的最大收益(也就是max)。接著i找到下一個數字,依此類推,尋找整個陣列找到它的最大收益
解題過程
👶:就像我一開始所說的我必須要跑兩層迴圈,會分別令n紀錄有幾個數字還有max_profit也就是我圖上的max。最外面那層i要檢查到每一個數字,接著裡面那層因為只要檢查i後面的數字,所以從i+1開始即可
🧔:那同學可以請你分析一下這段程式碼的時間複雜度嗎?
👶:因為要跑兩層迴圈,應該會很接近O(n^2)
🧔:可以請你找一個時間複雜度更低或更快的方法處理?
👶:直覺上除了剛剛的方法,其實還可以朝著Greedy還有dp的方法來解
說明想法
👶:我們設兩個指標一個是最小值(min)一個是最大收益(max),那我先假設它的min是這個,那我就和它後面的相減,來獲得max:-6。接著找到下一個最小值,一直去尋找它的最大收益。
解題過程
👶:就像我剛剛說的會有兩個指標(變數),因為一樣要跑所有的數字,所以從0到prices的size,首先要先判斷它的最小值,接著去找它的最大收益
🧔:感謝你的時間,接下來由我主持這場面試。這裡有一道題,就是經典的maximun subarray,題目描述如上。一個array中,它裡面有很多個subarray,那麼我要你找出這個subarry內元素的數值總和,並且這個總和要是最大值。
例如我給你一個array裡面元素有「-2,1,-3,4,-1,2」,而它的maximum subarray為「4,-1,2」,也就是你要output:5;那如果這個array中只有一個元素的話,直接輸出即可。
👶:好的,(打開小畫家)
一開始我看到這題,我會去假設它有兩個指標(i,j),然後j就往後讓i一個一個去加,去找出這一輪loop的最大sum值(這是第一步)。而我的第二步,去移動這個i重複上面這個動作,依此類推,直到i移動到最後一個元素為止。
👶:一開始會先宣告"res"為答案,初值為array第一個元素。開始跑for迴圈,就像剛剛畫的,我現在要讓i從頭跑到尾(0~nums.size()),因為我每一輪迴圈都要找它的sum,把它重製為0。接著開始實作第一步動作和後面相加並找出最大值,因為只要和後面相加,所以j從i開始
🧔:然後同學可以請你分析一下你寫的這個code的時間複雜度嗎?
👶:由於它跑兩層迴圈為O(N^2),N就是這個array的元素個數
🧔:那可不可以只跑這個陣列遍歷一次就可以了
👶:痾,我想一下喔。如果要這麼做,要朝著greedy還有dp的方向去思考
👶:首先呢!會有兩種情形(一個是和前面subarray合併,另外一個是不要合併),然後再取最大值
(開始用小畫家解釋)
那麼最後這個array的最大值就會是最大subarray的數值總和
(開始打code)
解題過程
👶:先令now_sum(紀錄目前這個subarray的數值總和,初值為第一個元素),接著令max_sum(記錄這個array的最大subarray數值總和),接著跑for迴圈。那麼就可以實作我剛剛說的–-now_sum就去判斷合併/不合併,max_sum去看這個subarray最大值
而我這個code它的時間複雜度就會是 ,因為他只要跑一層迴圈,利用DP的概念去完成要求
🧔:好的,同學。我這裡還有一個follow-up,不曉得你想不想挑戰看看?就是我希望你用divid & conquer來解這道題
👶:divid & conquer阿?!它整體的思維就是把一個很大的問題分成好幾個小問題,先把這個array一分為二,那我要去找出左右半邊最大subarray為多少?那麼我再去看看如果此時我把這兩個合併起來,那我最大的subarray還是右半邊的5
說明策略
👶:我會有lmax(主要記錄左半邊的maximum subarray)、rmax(主要記錄右半邊的maximum subarray)、還有ml和mr(這兩個是從m這個位置的元素往左/右的最大值)
解題過程
👶:一開始我的function會多兩個變數(left和right)。如果left>right代表它跑過頭,return;那如果沒有,就先找到m的位置,接著就令剛剛說的ml和mr,然後是左半邊最大值lmax右半邊最大值rmax,lmax從left到m-1/rmax從m+1到right。接著去求ml的值,用之前的想法往左累加並找出maximun,mr也是;最後去找出左半邊和右半邊哪個最大,再去比較mr+ml+m哪個更大
🧔:
Hello, thank you for waiting. I will be conducting this interview. I have a question for you:
The question is as follows: I will provide you with an array, and your task is to find a pair of elements within this array, where one element is positive and the other is negative, and then find the maximum value among them.
For example, given the array [-1, 2, -3, 3], you should output 3 because it satisfies the criteria. If no such pair is found in the array, please output -1.Additionally, there are no elements equal to 0 in this array.
👶:Well~ Initially, since the order of positive and negative numbers in the array is not guaranteed, it's probably positive one is in front of negative one.Or negative one is in front of positive one.
說明策略
👶:I think I will use nested loops to check. However, since there are no zeros in the array,a number pairing with itself won't occur. So, I can start the loop from 0.
解題過程
👶:I will start by using the 'ans' variable as my answer and initialize it to -1. Next, my first loop will iterate through the entire array. The second loop will do the same. Then, I'll check if 'nums[i]' is greater than 0 and if 'nums[i]' is equal to it's negative(nums[j]). If both of these conditions are met, I'll update the value of 'ans' using the 'max' function
🧔:Is there a way to simplify this code?
👶: Yes, there is a way to simplify it. You can start the loop from i+1, without considering the order, and you don't need to distinguish between nums[i] and nums[j].
👶: By Doing this,it reduce the second loop's execution by half.
🧔:Is there a faster approach?
👶: Well, let me think…
🧔:When it comes to data lookup, what comes to your mind?
👶:I might think the binary tree
🧔:However, if the data size is too large, this number can be quite high. There is a method that can achieve search in O(1) time.
👶:oops,hashtable
說明策略
👶:here are two types of hashtables: hashset and hashmap. Since we only need to check for existence, I would choose hashset.Because a set doesn't allow duplicate elements,it only stores unique elements
解題過程
👶:First, I'll insert the values from the array into a hashtable. Then, I'll check if this hashtable contains a pair of elements that meet the criteria. If it does, I'll update the 'ans' value using the 'max' function.
Because I only need to determine its existence or not, using the count function is sufficient
👶:This approach trades space for time. The minimum space complexity would be O(N) from O(1) since we need to store elements.But the time complexity will be O(n)(for insert) from O(nlogn),and search time for O(1)
.
針對 interviewer 的檢討:
針對 interviewee 的檢討:
優點
可改進的地方
00:56 05:20 在舉例說明時,可以直接打在word上比較清楚,不用再開一個小畫家。
04:40 回答時間複雜度時可以有自信一點,不用說"應該會很接近" O(n^2) ,可以直接說因為使用兩個for迴圈,所以時間複雜度是O(n^2)。
嘗試引導面試者去思考更好的解法
在面試者提出解法時,面試官其實可以要求面試者針對測資一起搭配著說明,也能一同驗證該解決方案是否可行
針對你的121. Best Time to Buy and Sell Stock我覺得你的 DP 想法很不錯,嘗試使用兩個指標紀錄最小值及最大收益
後來我嘗試使用您的想法遇到一些問題,以下為我參考您的想法
會產生以下問題
Line 8: Char 23: runtime error: signed integer overflow: 7 - -2147483648 cannot be represented in type 'int' (solution.cpp)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:17:23
我認為是 price - min
時造成 overflow,超過有號整數能表示的範圍了
以下為,改進版本
我舉個例子說明,您的測資為[7,1,5,3,6,4]
在 price = 7 時,min = 7, profit = price - min = 0; max profit = 0
在 price = 1 時,min = 1, profit = price - min = 0; max profit = 0
在 price = 5 時,min = 1, profit = price - min = 4; max profit = 4
在 price = 3 時,min = 1, profit = price - min = 2; max profit = 4
在 price = 6 時,min = 1, profit = price - min = 5; max profit = 5
在 price = 4 時,min = 1, profit = price - min = 3; max profit = 5
最後返回 max profit = 5