這其實是一道變形的鍊錶反轉題,大致描述如下:
給定乙個單鏈表的頭節點 head,實現乙個調整單鏈表的函式,使得每k個節點之間為一組進行逆序,並且從鍊錶的尾部開始組起,頭部剩餘節點數量不夠一組的不需要逆序。(不能使用佇列或者棧作為輔助) 例如: 鍊錶:1->2->3->4->5->6->7->8->null, k = 3。那麼 6->7->8,3->4->5,1->2各位一組。調整後:1->2->5->4->3->8->7->6->null。其中 1,2不調整,因為不夠一組。
這道題咋一看,挺簡單的,就是單鏈表分段逆序問題。正常情況下,遍歷鍊錶都是從頭結點開始,但題中指定從尾部開始分組,而單鏈表是沒法反向遍歷的。所以,把此題分解成幾個子問題,理解起來就簡單了,分解後如下:
這裡先實現2個功能作為備用:鍊錶逆序和分段逆序。
這裡用遞迴來實現,應用求解子問題
的思路,來拆分實現。
(1)拆分鍊錶。把f(n)拆分成f(n-1) + 1
(2)求解f(n-1)。
(3)將結點1
鏈結道f(n-1)尾部。
用**實現為:
// 逆序單鏈表
node*
inversetab
(node *phead)
分段的過程,可以順序遍歷求解,也可以應用遞迴求解,前者屬於常規方法,再次不再贅述。以下描述的是遞迴方式:
(1)將鏈結拆分為2部分。一段長度為m的鍊錶和一段長度為n-m的鍊錶。
(2)前半段直接呼叫inversetab
,後半段按子問題求解。
用**實現為:
// 從頭部開始,分段逆序
node*
sectioninversefromhead
(int clen, node *phead)
ptemp = ptemp-
>next;
}// 後半段逆序
pchead = ptemp-
>next;
pchead =
sectioninversefromhead
(clen, pchead)
;// 前半段逆序
ptemp-
>next =
null
; node *pnewhead =
inversetab
(phead)
;// 連起來
phead-
>next = pchead;
return pnewhead;
}
回到原問題,可分解為:逆序 —— 分段逆序 —— 逆序。這樣看,問題便迎刃而解了,直接上**:
// 從尾部開始,分段逆序
node*
sectioninversefromtail
(int clen, node *phead)
位元組跳動面試題
位元組跳動面試題 http協議 http協議是乙個應用層的協議,由請求和響應構成,使用統一資源識別符號來傳遞資料和建立連線 一次http請求的基本流程一般是,在建立tcp連線後,由客戶端向服務端發起一次請求 request 而伺服器在接收到以後返回給客戶端乙個響應 response 所以我們看到的h...
位元組跳動面試題
假如有兩台伺服器 server1和server2 這兩台伺服器上分別部署了相同的前端靜態檔案,index.html index.js 如果server1中的靜態資源被更新了,那麼此時會出現什麼問題?如何解決?通過控制 伺服器,讓客戶無感平滑公升級 root 當前頁面共有 files.length 個...
位元組跳動面試題
1 請分析以下 執行結果 async function a return result var p a p.abort 2 手寫乙個節流函式 手寫節流函式3 什麼是裝箱和拆箱 裝箱和拆箱操作,能夠在值型別和引用型別中架起一做橋梁。換言之,可以輕鬆的實現值型別與引用型別的互相轉換。裝箱是將值型別轉換為...