什么时候需要使用虚拟头节点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;
}
};