[請益] (ByteDance 面試) 兩種不同寫法的複雜度分析

軟工

1381073

事情是這樣的,今天下午面了 ByteDance 2023 的缺 (Algorithm Engineer)

考了 leetcode 3. Longest Substring Without Repeating Characters
(https://reurl.cc/WqNV8k)

我的解法:
https://i.imgur.com/o5wrRMo.png


我原本寫上面那個解法,兩個差異就是 for 裡面放一個 while 跟只用一個 while

面試官說我的解法不是 O(N),是 O(N^2),跟他吵了半小時之後就把解改成下面的。

想問我是不是真的哪裡陷入誤區?

我原本以為他是想看我反應 & 如何解釋,吵到一半發現他是真的不認為我的解法正確

面試官的說法 & 我的回答:

Q1: 你這個 while 應該改成 if 才對,不然會是 O(N^2)

A1: 改成 if 的話會錯,因為我必須"一直"縮左界直到目前的 window 內沒有重複的字符

Q2: 但你這個 for 是 O(N),while 也是 O(N),乘起來是 O(N^2),我要 O(N) 的解

A2: 我的 l 不會超過 r,兩者都是最多從 0 跑到 N (l+=1 總共最多跑 N 次),是分開的不能用乘法

而且複雜度分析的本來就是 upper bound,你要說 O(N^2) 也對,但我的分析方法可以壓到 O(N)


Q3: 我知道你的意思,但是我們只看 while,是不是最糟跑到 O(N)? 然後 for 也是 O(N),這樣分析是不是 O(N^2)

A3: 不是,你分析不能只看某一段 code,我是整個考慮進去所以壓的複雜度還是 O(N)

Q4: 這不是我要的最優解 (然後跳針回 Q2)

A4: 不然這樣講好了,你舉一個 worst case 例子給我我 dry run 給你看他不會是 O(N^2)


然後大概就是說類似這種 case s='qwertaa',遇到第二個 a 的時候他說我的 while 會是 O(N)

A5: 但是遇到的時候 l 也不會超過 r,不會存在一個情況使得 while 會需要每次都跑 O(N),他"總共"需要執行的次數最多就是 N

Q6: 我要的最優解是 O(N),不是 O(2N) (然後繼續跳針回 Q2),我覺得我們對算法複雜度的理解不一樣

A6: O(2N) 跟 O(N) 是一樣的 (然後他說他知道,但這不是他要的最優解)

接著大概就是一直重複跳針回 Q2 然後我一直用不同的方法去解釋跟他說這個是 O(N)

我直接請他舉一個 worst case 會是 O(N^2) 的例子我 dry run,他還是說我是 O(N^2), O(Nk), O(Nn) 之類的,就不是 O(N)

最後我就說總之你不想要 for 裡面有 while 的解對吧?然後就寫了下面那段 code 給他就下一題了..

如果他一開始就說不要用兩個迴圈寫應該就沒什麼問題,但他一直強調那個不是最優,而且是 O(N^2)

就跟他吵了半個小時...

我實際去 leetcode 跑了兩種算法,時間都差不多,到底哪裡有問題QQ



--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.204.135.123 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/Soft_Job/M.1669800213.A.900.html
me3565001樓原本的寫法就很直觀的是sliding window O(2N) = O(N) 11/30 17:35
me3565002樓我第一次寫這題也是這樣下手 11/30 17:35
me3565003樓怎麼感覺面試官只是要你寫出他要的最佳解 11/30 17:36
我自己是認為兩種解法差別只是在 r 在什麼時候做 +=1,但拆解開來是一樣的 我能理解他可能不想看到 for 裡面有 while,但是他給的理由是這樣寫是 O(N^2) 我就不能理解了
me3565004樓確實不可能是O(N^2) 11/30 17:41
me3565005樓他可能只是想講說你第一個解法在用while把l右移這部分 11/30 17:50
me3565006樓可以直接透過vector記他上次出現的idx一次就移到位 11/30 17:50
me3565007樓我看起來你第二個解法也是2N就是了 11/30 17:52
我改成下面那個他就給過= =
me3565008樓真的假的? 底下那個不是2N嗎? 11/30 18:00
me3565009樓其他題方便分享一下大概是什麼方面的嗎? 感謝 11/30 18:01
permutation 跟nms(object detection那個) 還有 kalman filter,後兩者我說我只知道概念不知道詳細演算法他就跳過不考了
doranako10樓第一種是跟第二種跑的迴圈數是一樣,第一種我覺得比較 11/30 18:08
doranako11樓好懂,因為就是遇到重複要把左邊界內縮到重複字元的位 11/30 18:08
doranako12樓 11/30 18:08
heap556613樓這是n^2沒錯喔 複雜度是指成長速度 不是絕對的數字 11/30 18:22
用邏輯直接算出他的最多可能執行次數也是一種分析方法,跟是不是成長速度沒有關係
hobnob14樓倒數第三句表示你可能不明白大公司為何考你刷題:面試官「 11/30 18:23
hobnob15樓認定」你一開始就會給最佳解,否則表示你練習得不到位,只 11/30 18:23
hobnob16樓求通過測資。不要問為什麼,因為「有人」做得到給最佳解, 11/30 18:23
hobnob17樓既然有人做得到,為什麼工作機會要給做不到的你? 11/30 18:23
heap556618樓如果輸入是qwertaa這種字串不斷重複 11/30 18:24
hobnob19樓確實你的第一個寫法是n^2。但我相信你可以跟ByteDance面 11/30 18:25
能解釋一下為什麼是 n^2 嗎?我是真不懂,實際測試也是時間差不多,leetcode 的測資應該還沒有那麼弱吧
hobnob20樓試一定有能力跟其他大公司面試,剛好你碰到比較鐵頭的面 11/30 18:25
hobnob21樓試官而已,祝你未來順利 11/30 18:25
heap556622樓有十分之n的位置的while會跑長度十分之n 11/30 18:26
heap556623樓乘起來是100分之n平方 還是n平方喔 11/30 18:27
但我的左界跟右界的更新次數都是O(N),為什麼會是 O(N^2)? 你不能用乘法啊,你用 n/10 * n/10 代表左界超過右界繼續算下去,但這不會成立,set 是空的他就會跳出去了
watashino24樓worst case就是2N阿 11/30 18:30
watashino25樓這樣複雜度怎麼可能是N平方 11/30 18:30
watashino26樓heap大這是沒考慮到left不可能超過right吧 11/30 18:34
me35650027樓底下的寫法就上面的換種寫法不是嗎? 哪裡來的N^2 11/30 18:36
watashino28樓另外hobnob大講的跟我理解的不同 11/30 18:37
watashino29樓通常是在面試過程中改進成最佳解才是一個好的面試官想 11/30 18:38
而且這兩個解根本一樣... 我只能猜說他覺得 for 裡面有 while 可能在實際寫 code 不是一個好習慣?
watashino30樓要的吧 11/30 18:38
更多請益
[請益] 視訊面試約在晚上很正常嗎?
[請益] 文組offer請益
[請益] 非本科offer請益
[請益] 程式怎麼選擇與入門?
[請益] 如何有效益的維護data loader
[請益] 職涯請教
[請益] 刷完 LeetCode 如何找工作
[請益] 關於Aha這間公司