什麼時候需要使用虛擬頭節點dummy,當頭節點會變得時候。
思路就是快慢指針:快指針先走n步,注意由於要刪除第k個,所以要找到前面一個,所以快指針只用走到最後一個位置。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int k) {
ListNode* dummy = new ListNode(-1);
dummy->next = head;
auto p = dummy, q = dummy;
while(k--){
if(p==NULL) return NULL;
p = p->next;
}
while(p->next!=NULL){
p = p->next;
q = q->next;
}
q->next = q->next->next;
return dummy->next;
}
};
利用中序遍歷一定是升序遍歷
不需要遍歷完整顆數,只需要遍歷前k個就返回
遞歸實現:
class Solution {
public:
int res, k;
int kthSmallest(TreeNode* root, int k) {
this->k = k;
dfs(root);
return res;
}
bool dfs(TreeNode* root){
if(root==NULL) return false;
if(dfs(root->left)) return true;
if(--k==0){
res = root->val;
return true;
}
return dfs(root->right);
}
};
非遞歸:
class Solution {
public:
int kthSmallest(TreeNode* root, int k) {
stack<TreeNode*> st;
TreeNode* cur = root;
while(cur||!st.empty()){
while(cur){
st.push(cur);
cur = cur->left;
}
cur = st.top();
st.pop();
if(--k==0) return cur->val;
cur = cur->right;
}
return -1;
}
};