[Sword Pointer Offer Special Breakthrough Edition] Queue Chapter - "C"

Preface

Sword refers to the special breakthrough version of the offer (Lekou official website) ——> Click to enter
the column to which this article belongs ——> Click to enter

1. Average value of sliding window

Question analysis

Insert image description here

Idea analysis

 When it is greater than size, the average of the latest size is returned, which is 对列consistent 先进先出. For a better understanding, we replace size here with capacity , and size here is considered to be the current number of elements in the current sliding window .
Therefore, we can solve the problem using pairs of columns. When the size is smaller than the capacity , we only need to queue it. When size is equal to capacity , we need to dequeue and then enqueue. Of course, when entering the queue, we can find the sum by the way. When dequeuing, the sum must be subtracted from the elements of the column.

Column code

typedef struct QNode
{
    
    
    struct QNode *next;
    struct QNode *prev;
    int val;
}QNode;
typedef struct 
{
    
    
    QNode* head;
    int sum;//为了方便记录我们这里采用插一个就记录当前的和
    int capacity;//这是给定的最大容量
    int size;//这是当前的size
}MovingAverage;
QNode* BuyNode(int val)
{
    
    
    QNode* NewNode = (QNode*)malloc(sizeof(QNode));
    NewNode->val = val;
    NewNode->next = NULL;
    NewNode->prev = NULL;
    return NewNode;
}
//需要写一个头插和尾删
void PushFront(QNode** head,int val)
{
    
    
    if(head == NULL)
    {
    
    
        printf("头插传入指针为空!\n");
        return;
    }
    QNode* New = BuyNode(val);
    QNode* Head = *head;
    
    if(Head == NULL)
    {
    
    
        //链表为空
        New->next = New;
        New->prev = New;
    }
    else
    {
    
    
        //进行头插操作
        New->next = Head;
        New->prev = Head->prev;

        
        Head->prev->next = New; 
        Head->prev = New;
    }
    *head = New;
}
void PopBack(QNode** head)
{
    
    
    QNode* Head = *head;
    QNode* Tail = Head->prev;
    //看是否只有一个结点
    if(Tail == Head)
    {
    
    
        *head = NULL;
    }
    else
    {
    
    
        Head->prev = Tail->prev;
        Tail->prev->next = Head;
    }
    free(Tail);
}
void QFree(QNode** head)
{
    
    
    QNode *Head = *head;
    if(Head != NULL)
    {
    
    
        QNode* cur = Head->next;
        while(cur != Head)
        {
    
    
            QNode* next = cur->next;
            free(cur);
            cur = next;
        }
    }
    free(Head);
}

Solution code

MovingAverage* movingAverageCreate(int size) 
{
    
    
    MovingAverage* init = \
     (MovingAverage*)malloc(sizeof(MovingAverage));
     // 说明:\是续行符,这里是为了防止代码过长。
    init->head = NULL;
    init->capacity = size;
    init->size = 0;
    init->sum = 0;

    return init;
}

double movingAverageNext(MovingAverage* obj, int val) 
{
    
    
    PushFront(&(obj->head),val);
    (obj->sum)+=val;
    (obj->size)++;
    //当这里的size会大于capacity
    if(obj->size > obj->capacity)
    {
    
    
        int tail = (obj->head)->prev->val;
        PopBack(&(obj->head));
        (obj->sum)-=tail;
        (obj->size)--;
    }
    double average = (double)(obj->sum)/(obj->size);
    return average;
}

void movingAverageFree(MovingAverage* obj) 
{
    
    
    QFree(&(obj->head));
    free(obj);
}

2. Number of recent requests

Question analysis

Insert image description here

Idea analysis

tThe number of requests returned  at a given time [t-3000,t], plus the t of each request, will 严格递增,and therefore t-3000gradually increase, so there may be 以前的t,not compliant with this state. Therefore, when the first t does not meet this status, the number of requests in this range is reduced by one. The previous t needs to be deleted and consistent 先进先出, so it is adopted 对列. Therefore, we only need to compare 当前的t-3000with 最开始的t, and if it is larger, it will be out of the queue; if it is smaller, it will be put into the queue. The current number of pairs is the number of recent requests.

queue code

typedef struct QNode
{
    
    
    struct QNode* prev;
    struct QNode* next;
    int top;
}QNode;

QNode* BuyNode(int top,int bottom)
{
    
    
    QNode* NewNode = (QNode*)malloc(sizeof(QNode));
    NewNode->top = top;
    NewNode->prev = NULL;
    NewNode->next = NULL;
    return NewNode;
}
void PushFront(QNode** head,int t)
{
    
    
    QNode* New = BuyNode(t,t-3000);
    QNode* Head = *head;
    if(Head == NULL)
    {
    
    
        New->next = New;
        New->prev = New;
    }
    else
    {
    
    
        New->next = Head;
        New->prev = Head->prev;

        Head->prev->next = New;
        Head->prev = New;
    }
    *head = New;
}
void PopBack(QNode** head)
{
    
    
    QNode* Head = *head;
    QNode* Tail = Head->prev;
    if(Head == Tail)
    {
    
    
        *head = NULL;
    }
    else
    {
    
    
        Head->prev = Tail->prev;
        Tail->prev->next = Head;
    }
    free(Tail);
}
void QFree(QNode** head)
{
    
    
    QNode* Head = *head;
    if(Head != NULL)
    {
    
    
        QNode* cur = Head->next;
        while(cur!=Head)
        {
    
    
            QNode* next = cur->next;
            free(cur);
            cur = next;
        } 
    }
    free(Head);
}
int Top(QNode** head)
{
    
    
    return (*head)->prev->top; 
}

bool is_empty(QNode** head)
{
    
    
    if(*head == NULL)
    {
    
    
        return true;
    }
    return false;
}

Solution code

typedef struct 
{
    
    
    QNode* head;
    int count;
}RecentCounter;
RecentCounter* recentCounterCreate() 
{
    
    
    RecentCounter* init =\
    (RecentCounter*)malloc(sizeof(RecentCounter));
    
    init->head = NULL;
    init->count = 0;
    return init;
}
int recentCounterPing(RecentCounter* obj, int t) 
{
    
    
    //先进行出栈,将范围小的出对列
    while(!is_empty(&(obj->head))&& (t-3000) > Top(&(obj->head)))
    {
    
    
        PopBack(&(obj->head));
        (obj->count)--;
    }
    //再将其入栈
    PushFront(&(obj->head),t);
    return ++(obj->count);
}
void recentCounterFree(RecentCounter* obj) 
{
    
    
    QFree(&(obj->head));
    free(obj);
}

3. Add nodes to a complete binary tree

Question analysis

Insert image description here
Theoretical knowledge:

Binary Tree - Theory Chapter
Binary Tree - Sequential Structure
点击即可进入

Supplement:
The conclusion of the complete binary tree used in this question is that the relationship between the child node and the parent node of the complete binary tree stored in an array is ~

  1. Prerequisite: The parent node of the node exists and is not the root node.
  2. Let the subscript of the node be N
  3. Parent node subscript = (N-1)/2

Idea analysis

 Since it is a complete binary tree, we need to traverse it once in level order, and then 完全二叉树转化为顺序结构we can easily insert the node. So how to convert the complete binary tree into a sequential structure?
 Process: First put the root node into the queue, and use 0 subscript to access the first node. If the root node is not empty, add its left node and right node into the queue again. At this time, there are three nodes in the queue. , use the subscript to access the next node, that is, the second node. If the second node is not empty at this time, add its left and right children into the queue again, and repeat the loop until an empty node is accessed.
  When we need to add a node, we only need to record the number of non-empty nodes after traversing. At this time, 非空结点的个数即为添加节点的下标we 上面的结论calculate the subscript of the parent node, access its parent node, and link this node to the parent node. Just go up.

Queue and interface code

typedef struct TreeNode TNode;
typedef struct Queue
{
    
    
    TNode** arr;
    int size;
    int capacity;
}Queue;

void QPushBack(Queue* que,TNode *val)
{
    
    
    if(que->capacity == que->size)
    {
    
    
        int capacity = que->capacity == 0 ? 4 : que->capacity * 2;
        TNode** tmp = (TNode**)realloc\
        (que->arr,sizeof(TNode*)*capacity);
        que->arr = tmp;
        que->capacity = capacity;
    }
    (que->arr)[que->size] = val;
    (que->size)++;
}
void Init(Queue* que)
{
    
    
    que->arr = NULL;
    que->size = 0;
    que->capacity = 0;
}
TNode* BuyNode(int v)
{
    
    
    TNode* NewNode = (TNode*)malloc(sizeof(TNode));
    NewNode->val = v;
    NewNode->left = NULL;
    NewNode->right = NULL;
    return NewNode;
}

Solution code

typedef struct 
{
    
    
    Queue que;
}CBTInserter;

CBTInserter* cBTInserterCreate(struct TreeNode* root) 
{
    
    
    CBTInserter* init = (CBTInserter*)malloc(sizeof(CBTInserter));
    Init(&(init->que));
    QPushBack(&(init->que),root);
    //插入根节点之后,进行层序遍历
    int sut = 0;//记录非空结点的个数
    while((init->que.arr)[sut]!=NULL)
    {
    
    
        TNode* cur = (init->que.arr)[sut];
        TNode* left = cur->left;
        TNode* right = cur->right;
        QPushBack(&(init->que),left);
        QPushBack(&(init->que),right);
        sut++;
    }
    init->que.size = sut;//记录非空结点的个数
    return init;
}

int cBTInserterInsert(CBTInserter* obj, int v)
{
    
    
    //初始化结点
    TNode* NewNode = BuyNode(v);
    int size = obj->que.size;//新节点的下标
    int pare = (size-1)/2;//父节点的下标
    TNode* pa = (obj->que.arr)[pare];//父节点
    if(pa->left == NULL)
    {
    
    
        pa->left = NewNode;
    } 
    else
    {
    
    
        pa->right = NewNode;
    }
    QPushBack(&(obj->que),NewNode);
    return pa->val;
}

struct TreeNode* cBTInserterGet_root(CBTInserter* obj)
{
    
    
    return (obj->que.arr)[0];
}

void cBTInserterFree(CBTInserter* obj) 
{
    
    
    free(obj->que.arr);
    free(obj);
}

4. The maximum value of each level of the binary tree

Question analysis

Insert image description here

Idea analysis

 This question requires layer-order traversal. Our application here is very flexible. First record the number of nodes in the first layer and set it to cur. When performing the alignment, cur is decremented to see if the maximum value of the current layer can be updated. By the way Put the left and right nodes of the dequeue node 非空结点into the queue, record the number of non-empty nodes by the way, and set it to next. When cur decreases to 0, next will be the number of non-empty nodes in the next layer. Update cur is next, and next is updated to 0. By the way, the max of this layer is updated, and the max of the next layer is initialized. cur与next循环更新,即为破题关键.

queue code

typedef struct TreeNode TNode;
typedef struct QNode
{
    
    
    struct QNode* prev;
    struct QNode* next;
    TNode* val;
}QNode;
QNode* BuyNode(TNode*val)
{
    
    
    QNode* NewNode = (QNode*)malloc(sizeof(QNode));
    NewNode->val = val;
    NewNode->next = NULL;
    NewNode->prev = NULL;
    return NewNode;
}
void PushFront(QNode** head, TNode* val)
{
    
    
    QNode* New = BuyNode(val);
    QNode* Head = *head;
    if(Head == NULL)
    {
    
    
        New->next = New;
        New->prev = New; 
    }
    else
    {
    
    
        New->next = Head;
        New->prev = Head->prev;

        Head->prev->next = New;
        Head->prev = New; 
    }
    *head = New;
}
void PopBack(QNode**head)
{
    
    
    QNode* Head = *head;
    QNode* Tail = Head->prev;
    if(Tail == Head)
    {
    
    
        free(Tail);
        *head = NULL;
    }
    else
    {
    
    
        Head->prev = Tail->prev;
        Tail->prev->next = Head;
        free(Tail);
    }
}
bool is_empty(QNode** head)
{
    
    
    if(*head == NULL)
    {
    
    
        return true;
    }

    return false;
}

Solution code

int* largestValues(struct TreeNode* root, int* returnSize)
{
    
    
    int *arr = (int*)malloc(sizeof(int)*10000);
    int size = 0;
    int max = 0;
    QNode* head = NULL;
    int cur = 0;//当前层的个数
    int next = 0;//下一层的个数
    if(root!=NULL)
    {
    
    
        PushFront(&head,root);
        cur = 1;//第一层的个数
        max = root->val;
    }
    while(!is_empty(&head))
    {
    
    
        TNode* tail = head->prev->val;
        if(tail->val > max)
        {
    
    
            max = tail->val;
        }
        TNode* left = tail->left;
        TNode* right = tail->right;
        PopBack(&head);
        cur--;
        if(left != NULL)
        {
    
    
            PushFront(&head,left);
            next++;
        }
        if(right != NULL)
        {
    
    
            PushFront(&head,right);
            next++;
        }
        if(cur == 0)
        {
    
    
            //更新最大值
            arr[size++] = max;

            cur = next;
            next = 0;
            if(head!=NULL)
            {
    
    
                TNode* tail = head->prev->val;
                max = tail->val;
            }
        }
    }
    *returnSize = size;
    return arr;
}

下面的五、六题与第四题雷同。The column codes are also the same and will not be given below.

5. The leftmost value at the bottom of the binary tree

Question analysis

Insert image description here

Idea analysis

The idea is the same as the fourth question, when proceeding 换层时我们需要更新一下最左边的值, then next与cur都等于0at that time , the leftmost value is saved at this time.

code

int findBottomLeftValue(struct TreeNode* root)
{
    
    
    QNode* head = NULL;
    PushFront(&head,root);
    int val_left = root->val;
    int cur = 1;
    int next = 0;
    while(!is_empty(&head))
    {
    
    
        TNode* Tail = head->prev->val;
        TNode* left = Tail->left;
        TNode* right = Tail->right;
        PopBack(&head);
        cur--;

        if(left != NULL)
        {
    
    
            PushFront(&head,left);
            next++;
        }
        if(right != NULL)
        {
    
    
            PushFront(&head,right);
            next++;
        }
        
        if(cur == 0)
        {
    
    
            if(next == 0)
            {
    
    
                //直接跳出循环即可。
                break;
            }

            cur = next;
            next = 0;
            if(head != NULL)
            {
    
    
                TNode* Tail = head->prev->val;
                val_left = Tail->val;
            }

        }
    }
    return val_left;
}

6. Right side view of binary tree

Question analysis

Insert image description here

Idea analysis

 The idea is similar to the fourth question, but here it is, 当cur等于0时,保存此层的最后一个结点的值.

code

int* rightSideView(struct TreeNode* root, int* returnSize)
{
    
    
    QNode* head = NULL;

    int *arr = (int*)malloc(sizeof(int)*100);
    int size = 0;
    int cur = 0;
    int next = 0;
    if(root != NULL)
    {
    
    
        PushFront(&head,root);
        cur = 1;
    }
    while(!is_empty(&head))
    {
    
    
        TNode* Tail = head->prev->val;
        TNode* left = Tail->left;
        TNode* right = Tail->right;
        cur--;
        PopBack(&head);
        if(left != NULL)
        {
    
    
            PushFront(&head,left);
            next++;
        }
        if(right != NULL)
        {
    
    
            PushFront(&head,right);
            next++;
        }
        if(cur == 0)
        {
    
    
            arr[size++] = Tail->val;
            cur = next;
            next = 0;
        }
    }
    *returnSize = size;
    return arr;
}

Summarize

 That’s it for today’s sharing. If you think the article is good,Give it a like and encourage it.! Us 下篇文章再见!

Guess you like

Origin blog.csdn.net/Shun_Hua/article/details/131328537