剑指offer-倒数第k个节点,镜像二叉树,O(1)时间删除链表节点,

倒数第k个节点

思路:

用两个指针,第一个指针先走k-1步,之后两个节点一同开始走,当第一个节点走到表尾,第二个节点就到了倒数第k个节点。
要注意特殊情况的处理,如传入空指针,k小于链表节点个数。
PS:双指针是常用的方法,找中间节点可以用快慢指针。

代码:


        ListNode* FindNodek(ListNode* head, int k)
{
    ListNode* p = head;
    ListNode* q = NULL;
    if (head == NULL)
    {
        return NULL;
    }
    if (k == 0)
        return NULL;
    for (int i = 0; i < k - 1; i++)
    {   
        if (p->next != NULL)
            p = p->next;
        else
            return NULL;
    }
    q = head;
    while (p->next != NULL)
    {
        p = p->next;
        q = q->next;
    }
    return q;
}

镜像二叉树

思路:

用递归的想法,先序遍历节点,当不为叶子节点时,就交换左右子树(注意不是值)。

代码:

void MirrorTree(TreeNode* root)
{
    if ((root == NULL) || root->left == NULL && root->right == NULL)
        return;
    TreeNode* temp = new TreeNode;//交换的是节点,而不是值
    root->left = root->right;
    root->right = temp;
    MirrorTree(root->left);
    MirrorTree(root->right);
}

O(1)时间删除链表节点

思路:

O(1)时间删除给定节点,可以将给定节点后面的节点复制到本节点,再删除后面的节点。
代码:

void DeleteNode(ListNode* head, ListNode* p)
{
    if (!head || !p)
        return;
    if (p->next != nullptr)
    {
        ListNode* q = p->next;
        p->value = q->value;
        p->next = q->next;
        delete q;

    }
    else if (p = =head)
    {
        delete p;
        head->next = nullptr;

    }
    else
    {
        ListNode* q == head;
        while (q->next != p)
            q = q->next;
        q->next = nullptr;
        delete p;

    }

}

猜你喜欢

转载自www.cnblogs.com/void-lambda/p/12357211.html