2023年力扣高頻演算法面試題6鍊錶

2021-10-07 02:27:26 字數 2696 閱讀 8313

之前在csdn寫過一篇 鍊錶與快慢指標 的筆記(判斷鍊錶是否有環、找到環的入口、反轉鍊錶):

請編寫乙個函式,使其可以刪除某個鍊錶中給定的(非末尾)節點,你將只被給定要求被刪除的節點。

分析:之前有同學去哈深面試也問過類似的問題。沒有給我們鍊錶的起點,只給我們了乙個要刪的節點,跟我們以前遇到的情況不太一樣,我們之前要刪除乙個節點的方法是要有其前乙個節點的位置,然後將其前乙個節點的next連向要刪節點的下乙個,然後delete掉要刪的節點即可。這道題的處理方法是先把當前節點的值用下乙個節點的值覆蓋了,然後我們刪除下乙個節點即可

吐槽:誰能想到還可以用替身攻擊,還可以把下乙個的複製到當前節點,然後把下乙個節點的刪掉,神奇!!!

class solution 

};

給定乙個鍊錶,每個節點包含乙個額外增加的隨機指標,該指標可以指向鍊錶中的任何節點或空節點。

要求:返回這個鍊錶的深拷貝,必須返回給定頭的拷貝作為對轉殖列表的引用。

其實,,,完全沒看懂這個題。。。

解答:使用遞迴的解法,寫起來相當的簡潔,還是需要乙個 hashmap 來建立原鍊錶結點和拷貝鍊錶結點之間的對映。在遞迴函式中,首先判空,若為空,則返回空指標。然後就是去 hashmap 中查詢是否已經在拷貝鍊錶中存在了該結點,是的話直接返回。否則新建乙個拷貝結點 res,然後建立原結點和該拷貝結點之間的對映,然後就是要給拷貝結點的 next 和 random 指標賦值了,直接分別呼叫遞迴函式即可,參見**如下:

/*

// definition for a node.

class node

node(int _val, node* _next, node* _random)

};*/

class solution

node* helper(node* node, unordered_map& m)

};

編寫乙個程式,找到兩個單鏈表相交的起始節點。

要求:如果兩個鍊錶沒有交點,返回 null.在返回結果後,兩個鍊錶仍須保持原有的結構。可假定整個鍊錶結構中沒有迴圈。程式盡量滿足 o(n) 時間複雜度,且僅用 o(1) 記憶體。

這個題真的是easy等級!!!然而我真的沒寫出來,哭。一開始想的是反轉鍊錶,這樣就可以從頭開始比較,結果題目要求鍊錶必須保持原有的結構。

解析:方法一:分別遍歷兩個鍊錶,得到分別對應的長度。然後求長度的差值,把較長的那個鍊錶向後移動這個差值的個數,然後一一比較即可

class solution  else 

while (heada && headb && heada != headb)

return (heada && headb) ? heada : null;

}int getlength(listnode* head)

return cnt;

}};

方法二:雖然題目中強調了鍊錶中不存在環,但是我們可以用環的思想來做,我們讓兩條鍊錶分別從各自的開頭開始往後遍歷,當其中一條遍歷到末尾時,我們跳到另乙個條鍊錶的開頭繼續遍歷。兩個指標最終會相等,而且只有兩種情況,一種情況是在交點處相遇,另一種情況是在各自的末尾的空節點處相等。為什麼一定會相等呢,因為兩個指標走過的路程相同,是兩個鍊錶的長度之和,所以一定會相等。

class solution 

return a;

}};

在 o(n log n) 時間複雜度和常數級空間複雜度下,對鍊錶進行排序。

分析:看到時間複雜度o(nlgn)最先想到的就是把鍊錶的資料存到vector,用sort進行排序,然後把排好序的資料重新建成乙個鍊錶…很明顯這個方法效率太低.

歸併排序:歸併排序的核心其實是分治法 divide and conquer,就是將鍊錶從中間斷開,分成兩部分,左右兩邊再分別呼叫排序的遞迴函式 sortlist(),得到各自有序的鍊錶後,再進行 merge(),這樣整體就是有序的了。

class solution 

pre->next = null;

return merge(sortlist(head), sortlist(slow));

}listnode* merge(listnode* l1, listnode* l2) else

}};

補充幾個其他型別演算法題:

nums.erase(unique(nums.begin(),nums.end()),nums.end());

return nums.size();

方法二:leetcode官網給的答案是用雙指標做:陣列完成排序後,我們可以放置兩個指標i和j,其中i是慢指標,而j是快指標。只要nums[i]==nums[j],我們就增加j以跳過重複項。當我們遇到 nums[j]!=nums[i]時,跳過重複項的執行已經結束,因此我們必須把它nums[j]的值複製到nums[i+1]。然後遞增i,接著我們將再次重複相同的過程,直到j到達陣列的末尾為止。

class solution 

j++;

}return i+1;

}};

2023年力扣高頻演算法面試題9樹

給定乙個二叉搜尋樹,編寫乙個函式 kthsmallest 來查詢其中第 k個最小的元素。假設 k 總是有效的,1 k 二叉搜尋樹元素個數。高階 如果二叉搜尋樹經常被修改 插入 刪除操作 並且你需要頻繁地查詢第 k 小的值,你將如何優化 kthsmallest 函式?解題思路 利用find記錄是否找到...

2023年力扣高頻演算法面試題4動態規劃

給定長度為 n 的整數陣列 nums,其中 n 1,返回輸出陣列 output 其中 output i 等於 nums 中除 nums i 之外其餘各元素的乘積。說明 請不要使用除法,且在 o n 時間複雜度內完成此題。分析 對於某乙個數字,如果我們知道其前面所有數字的乘積,同時也知道後面所有的數乘...

2023年力扣高頻演算法面試題1數學 位運算

給定乙個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。要求 線性時間複雜度 不使用額外空間 解答 典型的位運算,相同的兩個數異或為0,擴充套件形式為,找出給定非空整數陣列中只出現一次的兩個整數。int singlenumber vector nums ...