數據結構與算法學習之力扣面試刷題篇(持續更新)

學以致用,單純的學習不去進行使用那麼是不會有提高的,對於數據結構和算法的學習,我們不僅需要掌握到它的核心和原理,更應該學以致用,將所學習到的知識點運用到相關的代碼之中,將我學習數據結構和算法時所練習的力扣題附在這裏大家一起討論和學習。

一:數組面試題

  1. 原地移除數組中所有的元素val,要求時間複雜度爲O(N),空間複雜度爲O(1)。OJ鏈接

題解:

int removeElement(int* nums, int numsSize, int val){
    int i;
    int j=0,k=0;
    for(i=0;i<numsSize;i++)
    {
        if(nums[i]!=val)
        {
            nums[j++]=nums[i];
        }
        else
            k+=1;
    }
    numsSize-=k;
    return numsSize;
}
  1. 刪除排序數組中的重複項。OJ鏈接
    題解:

  2. 合併兩個有序數組。OJ鏈接

題解:

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
    for(int i=0;i<n;i++){
		int j=m-1;
		for(;j>=0;j--){
			if(nums2[i]<nums1[j]){
				nums1[j+1]=nums1[j];
			}else{
                break;
            }
		}
		nums1[j+1]=nums2[i];
		m++;
	}
}
  1. 旋轉數組。OJ鏈接
    題解:

  2. 數組形式的整數加法。OJ鏈接
    題解:

二:鏈表面試題

  1. 刪除鏈表中等於給定值 val 的所有節點。OJ鏈接
    題解:
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* removeElements(struct ListNode* head, int val){
    struct ListNode* cur=head;
    struct ListNode* perv=NULL;
    while(cur){
        if(cur->val==val){
            struct ListNode*next=cur->next;
            if(cur==head){
                head=next;
            }
            else{
                perv->next=next;
            }
            cur=next;
        }
        else{
            perv=cur;
            cur=cur->next;
        }
    }
    return head;
}
  1. 反轉一個單鏈表。OJ鏈接

題解:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* reverseList(struct ListNode* head){
    struct ListNode* newH, *cur, *next;
    newH = NULL;
    cur = head;
    while(cur)
    {
        //首先保存next節點
        next = cur->next;
        //頭插
        cur->next = newH;
        newH = cur;
        //操作下一個節點
        cur = next;
    }
    return newH;
}
  1. 給定一個帶有頭結點 head 的非空單鏈表,返回鏈表的中間結點。如果有兩個中間結點,則返回第二個中間結點。OJ鏈接

題解:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* middleNode(struct ListNode* head){
    struct ListNode* fast, * slow;
    fast = slow = head;
    while (fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
    }
    return slow;
}
  1. 輸入一個鏈表,輸出該鏈表中倒數第k個結點。OJ鏈接

題解:

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
           ListNode* fast, * slow;
        fast = slow = pListHead;
        while (k--)
        {
            if (fast)
                fast = fast->next;
            else
                return NULL;
        }
        while (fast)
        {
            slow = slow->next;
            fast = fast->next;
        }
        return slow;
    }
};
  1. 將兩個有序鏈表合併爲一個新的有序鏈表並返回。新鏈表是通過拼接給定的兩個鏈表的所有節點組成的。OJ鏈接

題解:

實現方法1
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
            struct ListNode* newT, * newH, * tmp;
    if (l1 == NULL)
        return l2;
    if (l2 == NULL)
        return l1;
    /*
    //確定新的頭結點
    if(l1->val <= l2->val)
    {
        newH = newT = l1;
        l1 = l1->next;
    }
    else
    {
        newH = newT = l2;
        l2 = l2->next;
    }
    //合併
    while(l1 && l2)
    {
        if(l1->val <= l2->val)
        {
            newT->next = l1;
            l1 = l1->next;
        }
        else
        {
            newT->next = l2;
            l2 = l2->next;
        }
        newT = newT->next;
    }
    //拼接剩餘節點
    if(l1)
        newT->next = l1;
    if(l2)
        newT->next = l2;
    return newH;
    */
    //創建帶有頭結點的鏈表
    newH = newT = (struct ListNode*) malloc(sizeof(struct ListNode));
    while (l1 && l2)
    {
        if (l1->val <= l2->val)
        {
            newT->next = l1;
            l1 = l1->next;
        }
        else
        {
            newT->next = l2;
            l2 = l2->next;
        }
        newT = newT->next;
    }
    //拼接剩餘節點
    if (l1)
        newT->next = l1;
    if (l2)
        newT->next = l2;

    //釋放臨時空間
    tmp = newH;
    newH = newH->next;
    free(tmp);

    return newH;
    }
};
實現方法2
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
    if(l1==NULL){
        return l2;
    }
    if(l2==NULL){
        return l1;
    }
    struct ListNode* cur=NULL;
    if(l1->val <= l2->val ){
        l1->next = mergeTwoLists(l1->next,l2);
        cur = l1;
    }else{
        l2->next = mergeTwoLists(l2->next,l1);
        cur =  l2;
    }
    return cur;
}
  1. 以給定值x爲基準將鏈表分割成兩部分,所有小於x的結點排在大於或等於x的結點之前。OJ鏈接

題解:

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {
        // write code here
        struct ListNode* Lcur,*LcurN,*Gcur,*GcurN,*cur;
        Lcur=LcurN=(struct ListNode*)malloc(sizeof(struct ListNode));
        Gcur=GcurN=(struct ListNode*)malloc(sizeof(struct ListNode));
        if(pHead==NULL){
            return NULL;
        }
        cur=pHead;
        while(cur){
        if(cur->val<x){
            Lcur->next=cur;
            Lcur=Lcur->next;
        }
        else{
            Gcur->next=cur;
            Gcur=Gcur->next;
        }
            cur=cur->next;
        }
        Gcur->next=NULL;
        Lcur->next=GcurN->next;
        Lcur=LcurN;
        Gcur=GcurN;
        LcurN=LcurN->next;
        free(Lcur);
        free(Gcur);
        return LcurN;
    }
};
  1. 鏈表的迴文結構。OJ鏈接

題解:

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
public:
    bool chkPalindrome(ListNode* A) {
        // write code here
        struct ListNode* slow,*fast;
        if(A==NULL||A->next==NULL){
            return true;
        }
        slow=A;
        fast=A;
        while(fast&&fast->next){
            slow=slow->next;
            fast=fast->next->next;
        }
        struct ListNode* cur,*perv;
        perv=NULL;
        cur=slow;
        struct ListNode* next;
        while(cur){
            next=cur->next;
            cur->next=perv;
            perv=cur;
            cur=next;
        }
        cur=perv;
        while(A&&cur){
            if(A->val!=cur->val){
                return false;
            }
            A=A->next;
            cur=cur->next;
        }
        free(perv);
        free(next);
        return true;
    }
};
  1. 輸入兩個鏈表,找出它們的第一個公共結點。OJ鏈接

題解:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    if(headA==NULL||headB==NULL)return NULL;
    struct ListNode* pA=headA;
    struct ListNode* pB=headB;
    while(pA!=pB)//遍歷兩個鏈表
    {
        pA=pA==NULL?headB:pA->next;//構造鏈表D
        pB=pB==NULL?headA:pB->next;//構造鏈表C
        
    }
    return pA;
    }
};
  1. 給定一個鏈表,判斷鏈表中是否有環。OJ鏈接

題解:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) {
        struct ListNode* fast,*slow;
        if(head==NULL){
            return false;
        }
        fast=slow=head;
        while(fast&&fast->next){
            fast=fast->next->next;
            slow=slow->next;
            if(slow==fast){
                return true;
            }
        }
        return false;
    }
};
  1. 給定一個鏈表,返回鏈表開始入環的第一個節點。 如果鏈表無環,則返回 NULL。OJ鏈接

題解:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */

struct ListNode*hasCycle(ListNode* head) {
        struct ListNode* fast, * slow;
        //設定快慢指針來進行查找
        if (head == NULL) {
            //首先判空
            return NULL;
        }
        fast = slow = head;
        //讓快慢指針全部指向鏈表頭地址
        while (fast && fast->next) {
            //快指針所指向的地址不爲空
            fast = fast->next->next;
            //快指針向後走兩步
            slow = slow->next;
            //慢指針向後走一步
            if (slow == fast) {
                //若相等則輸出正確
                return fast;
            }
        }
        return NULL;
    }
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        struct ListNode* cur;
        cur=hasCycle(head);
        if(cur){
            while(cur!=head){
                cur=cur->next;
                head=head->next;
            }
            return cur;
        }
        return NULL;
    }
};
  1. 給定一個鏈表,每個節點包含一個額外增加的隨機指針,該指針可以指向鏈表中的任何節點或空節點,要求返回這個鏈表的深度拷貝。OJ鏈接

題解:

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;
    Node* random;
    
    Node(int _val) {
        val = _val;
        next = NULL;
        random = NULL;
    }
};
*/

class Solution {
public:
    Node* copyRandomList(Node* head) {
        if(head==NULL){
            return head;
            //進行判空操作
        }
        struct Node* cur,*next,*copy;
        //創建三個指針變量
        //複製
        cur=head;
        //讓cur指針指向頭鏈表
        while(cur){
            //複製操作
            next=cur->next;
            //將下一個鏈表的位置保存在next;
            struct Node*Copy=(struct Node*)malloc(sizeof(struct Node));
            //重新申請一個新的鏈表大小空間
            Copy->val=cur->val;
            //將其中的內容也進行復制
            cur->next=Copy;
            //將新複製的鏈表地址給與cur的next
            Copy->next=next;
            //將之前所保存的next的位置賦給copy的next
            cur=next;
            //使得cur後移到next
        }
        cur=head;
        //重新使得cur指向鏈表的頭位置
        while(cur){
            //拷貝random
            copy=cur->next;
            //將cur的next位置的地址給copy
            next=copy->next;
            //將copy所指向的next地址保存到next
            if(cur->random){
                //若不爲空,則將random的指向複製到新複製的鏈表之中,使得其新複製的指向後面新複製的
                copy->random=cur->random->next;
            }
            else{
                copy->random=NULL;
                //否則指向爲空
            }
            cur=next;
            //使得cur再次後移到他原鏈表的後一位
        }
        cur=head;
        struct Node* NewHead=cur->next;
        //創建新的鏈表指針,指向第二個鏈表地址
        while(cur){
            copy=cur->next;
            //將cur的next位置賦給copy
            next=copy->next;
            //copy的next地址位置保存在next之中
            cur->next=next;
            //next賦予到cur的next之中
            if(next){
                //將next的下一個鏈表給到copy的next
                copy->next=next->next;
            }
            cur=next;
            //同理
        }
        return NewHead;
        //返回拆鏈出來的鏈表首位
    }
};
  1. 對鏈表進行插入排序。OJ鏈接

題解:

  1. 在一個排序的鏈表中,存在重複的結點,請刪除該鏈表中重複的結點,重複的結點不保留,返回鏈表頭指針。OJ鏈接

題解:

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* deleteDuplication(ListNode* pHead)
    {
        struct ListNode* cur,*perv,*bol,*temp;
        if(pHead==NULL||pHead->next==NULL){
            return pHead;
        }
        perv=NULL;
        cur=pHead;
        bol=cur->next;
        while(bol){
            if(bol->val==cur->val){
                while(bol&&bol->val==cur->val){
                    bol=bol->next;
                }
                while(cur!=bol){
                    temp=cur->next;
                    free(cur);
                    cur=temp;
                }
                if(perv==NULL){
                    pHead=cur;
                }
                else{
                    perv->next=cur;
                }
                if(bol){
                    bol=bol->next;
                }
            }
            else{
                perv=cur;
                cur=bol;
                bol=bol->next;
            }
         }
        return pHead;
    }
};
  1. 其他 LeetCodeOJ鏈接 + 牛客OJ鏈接

三:棧和隊列

  1. 括號匹配問題。OJ鏈接
    題解:
//順序表實現棧
typedef char Type;

typedef struct Stack
{
	Type* _array;
	size_t _size;
	size_t _capacity;
}Stack;

void stackInit(Stack* st, size_t n);

void stackPush(Stack* st, Type data);
void stackPop(Stack* st);
Type stackTop(Stack* st);

size_t stackSize(Stack* st);
int stackEmpty(Stack* st);

void stackDestory(Stack* st);

void stackInit(Stack* st, size_t n)
{
	st->_array = (Type*)malloc(sizeof(Type)* n);
	st->_capacity = n;
	st->_size = 0;
}

void stackPush(Stack* st, Type data)
{
	//檢查容量
	if (st->_size == st->_capacity)
	{
		st->_capacity *= 2;
		st->_array = (Type*)realloc(st->_array, st->_capacity * sizeof(Type));
	}
	//尾插
	st->_array[st->_size++] = data;
}
void stackPop(Stack* st)
{
	//尾刪
	if (st->_size)
		--st->_size;
}
Type stackTop(Stack* st)
{
	return st->_array[st->_size - 1];
}

size_t stackSize(Stack* st)
{
	return st->_size;
}
int stackEmpty(Stack* st)
{
	if (st->_size == 0)
		return 1;
	return 0;
}

void stackDestory(Stack* st)
{
	free(st->_array);
	st->_array = NULL;
	st->_size = st->_capacity = 0;
}

bool isValid(char * s){
    //左右括號的映射
    static char map[][2] = {{'(', ')'},
     {'[', ']'}, {'{', '}'}};
    Stack st;
    stackInit(&st, 10);
    
    //遍歷字符串, 左括號入棧, 右括號匹配
    while(*s)
    {
        int i = 0;
        //flag: 是否找到一個左括號
        int flag = 0;
        //判斷是否爲左括號
        for(; i < 3;++i)
        {
            if(*s == map[i][0])
            {
                //左括號入棧
                stackPush(&st, *s);
                ++s;
                flag = 1;
                break;
            }
        }
        //循環走完,說明不是一個左括號
        //if(i == 3)
        if(flag == 0)
        {
            //讓當前的右括號匹配棧頂元素
            if(stackEmpty(&st))
                return false;
            char topChar = stackTop(&st);
        
            
            //找出對應的右括號在map的位置
            for(int j = 0; j < 3; ++j)
            {
                if(*s == map[j][1])
                {
                    if(topChar == map[j][0])
                    {
                        //左右匹配
                        stackPop(&st);
                        ++s;
                        break;
                    }
                    else
                        return false;
                }
            }
            
        }

    }

    if(stackEmpty(&st))
        return true;
    return false;
}
  1. 用隊列實現棧。OJ鏈接
    題解:
typedef int QDataType;

typedef struct QNode
{
	struct QNode* _next;
	QDataType _data;
}QNode;

typedef struct Queue
{
	QNode* _front;
	QNode* _rear;
	int _size;
}Queue;

void queueInit(Queue* q);

QNode* creatNode(QDataType data);

void queuePush(Queue* q, QDataType data);

void queueFrontPush(Queue* q,QDataType data);

void queuePop(Queue* q);

QDataType queueFront(Queue* q);

QDataType queueBack(Queue* q);

int queueSize(Queue* q);

int queueEmpty(Queue* q);

void queueDestory(Queue* q);

void queueInit(Queue* q)
{
	//初始化空隊列
	q->_front = q->_rear = NULL;
	q->_size = 0;
}

QNode* creatNode(QDataType data)
{
	QNode* node = (QNode*)malloc(sizeof(QNode));
	node->_data = data;
	node->_next = NULL;
	return node;
}


//隊列隊頭入隊
void queueFrontPush(Queue* q,QDataType data){
    QNode* node =creatNode(data);
    //空隊列
    if(q->_front==NULL){
        q->_front=q->_rear=node;
    }
    else{
        node->_next=q->_front;
        q->_front=node;
    }
    ++q->_size;
}

//隊頭出隊
void queuePop(Queue* q)
{
	if (q->_front)
	{
		QNode* next = q->_front->_next;
		free(q->_front);
		q->_front = next;
		//刪除之後是否爲空表
		if (q->_front == NULL)
			q->_rear = NULL;
		--q->_size;
	}
}

//獲取隊頭元素
QDataType queueFront(Queue* q)
{
	return q->_front->_data;
}
//獲取隊尾元素
QDataType queueBack(Queue* q)
{
	return q->_rear->_data;
}

int queueSize(Queue* q)
{
	/*
	int num = 0;
	QNode* cur = q->_front;
	while (cur)
	{
		++num;
		cur = cur->_next;
	}
	return num;
	*/
	return q->_size;
}

int queueEmpty(Queue* q)
{
	if (q->_front == NULL)
		return 1;
	return 0;
}

void queueDestory(Queue* q)
{
	QNode* cur = q->_front;
	while (cur)
	{
		QNode* next = cur->_next;
		free(cur);
		cur = next;
	}
	q->_front = q->_rear = NULL;
	q->_size = 0;
}


typedef struct {
    Queue q;
} MyStack;

/** Initialize your data structure here. */

MyStack* myStackCreate() {
    MyStack* ms=(MyStack*)malloc(sizeof(MyStack));
    queueInit(&ms->q);
    return ms;
}

/** Push element x onto stack. */
void myStackPush(MyStack* obj, int x) {
    queueFrontPush(&obj->q,x);
}

/** Removes the element on top of the stack and returns that element. */
int myStackPop(MyStack* obj) {
    int ret;
    ret=queueFront(&obj->q);
    queuePop(&obj->q);
    return ret;
}

/** Get the top element. */
int myStackTop(MyStack* obj) {
    return queueFront(&obj->q);
}

/** Returns whether the stack is empty. */
bool myStackEmpty(MyStack* obj) {
    return queueEmpty(&obj->q);
    
}

void myStackFree(MyStack* obj) {
    queueDestory(&obj->q);
    free(obj);
}

/**
 * Your MyStack struct will be instantiated and called as such:
 * MyStack* obj = myStackCreate();
 * myStackPush(obj, x);
 
 * int param_2 = myStackPop(obj);
 
 * int param_3 = myStackTop(obj);
 
 * bool param_4 = myStackEmpty(obj);
 
 * myStackFree(obj);
*/
  1. 用棧實現隊列。OJ鏈接
    題解:
typedef int Type;

typedef struct Stack
{
	Type* _array;
	size_t _size;
	size_t _capacity;
}Stack;

void stackInit(Stack* st, size_t n);

void stackPush(Stack* st, Type data);
void stackPop(Stack* st);
Type stackTop(Stack* st);

size_t stackSize(Stack* st);
int stackEmpty(Stack* st);

void stackDestory(Stack* st);

void stackInit(Stack* st, size_t n)
{
	st->_array = (Type*)malloc(sizeof(Type)* n);
	st->_capacity = n;
	st->_size = 0;
}

void stackPush(Stack* st, Type data)
{
	//檢查容量
	if (st->_size == st->_capacity)
	{
		st->_capacity *= 2;
		st->_array = (Type*)realloc(st->_array, st->_capacity * sizeof(Type));
	}
	//尾插
	st->_array[st->_size++] = data;
}
void stackPop(Stack* st)
{
	//尾刪
	if (st->_size)
		--st->_size;
}
Type stackTop(Stack* st)
{
	return st->_array[st->_size - 1];
}

size_t stackSize(Stack* st)
{
	return st->_size;
}
int stackEmpty(Stack* st)
{
	if (st->_size == 0)
		return 1;
	return 0;
}

void stackDestory(Stack* st)
{
	free(st->_array);
	st->_array = NULL;
	st->_size = st->_capacity = 0;
}


typedef struct {
    Stack Push;
    Stack Pop;
} MyQueue;

/** Initialize your data structure here. */

MyQueue* myQueueCreate() {
    MyQueue* ms=(MyQueue*)malloc(sizeof(MyQueue));
    stackInit(&ms->Push,10);
    stackInit(&ms->Pop,10);
    return ms;
}

/** Push element x to the back of queue. */
void myQueuePush(MyQueue* obj, int x) {
    stackPush(&obj->Push,x);
}

/** Removes the element from in front of queue and returns that element. */
int myQueuePop(MyQueue* obj) {
    int ret;
    if(stackEmpty(&obj->Pop)){
        while(stackEmpty(&obj->Push)!=1){
            ret=stackTop(&obj->Push);
            stackPop(&obj->Push);
            stackPush(&obj->Pop,ret);
        }
    }
    ret=stackTop(&obj->Pop);
    stackPop(&obj->Pop);
    return ret;
}

/** Get the front element. */
int myQueuePeek(MyQueue* obj) {
    if(stackEmpty(&obj->Pop)){
    while(stackEmpty(&obj->Push)!=1){
        int ret=stackTop(&obj->Push);
        stackPop(&obj->Push);
        stackPush(&obj->Pop,ret);
        }
    }
    return stackTop(&obj->Pop);
}

/** Returns whether the queue is empty. */
bool myQueueEmpty(MyQueue* obj) {
    return stackEmpty(&obj->Push)&&stackEmpty(&obj->Pop);
    
}

void myQueueFree(MyQueue* obj) {
    stackDestory(&obj->Pop);
    stackDestory(&obj->Push);
    free(obj);
}

/**
 * Your MyQueue struct will be instantiated and called as such:
 * MyQueue* obj = myQueueCreate();
 * myQueuePush(obj, x);
 
 * int param_2 = myQueuePop(obj);
 
 * int param_3 = myQueuePeek(obj);
 
 * bool param_4 = myQueueEmpty(obj);
 
 * myQueueFree(obj);
*/
  1. 設計循環隊列。OJ鏈接
    題解:
typedef struct {
	int front;
	int rear;
	int size;
	int k;
	int* array;
} MyCircularQueue;

/** Initialize your data structure here. Set the size of the queue to be k. */

MyCircularQueue* myCircularQueueCreate(int k) {
	MyCircularQueue* mq = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
	mq->array = (int*)malloc(sizeof(int)* k);
	mq->front = mq->rear = 0;
	mq->size = 0;
	mq->k = k;
	return mq;
}

/** Insert an element into the circular queue. Return true if the operation is successful. */
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
	if (obj->size == obj->k)
		return false;
	//尾插
	obj->array[obj->rear++] = value;
	//保證循環結構
	if (obj->rear == obj->k)
		obj->rear = 0;
	obj->size++;
	return true;
}

/** Delete an element from the circular queue. Return true if the operation is successful. */
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
	if (obj->size == 0)
		return false;
	//頭刪
	++obj->front;
	if (obj->front == obj->k)
		obj->front = 0;
	--obj->size;
	return true;
}

/** Get the front item from the queue. */
int myCircularQueueFront(MyCircularQueue* obj) {
	if (obj->size == 0)
		return -1;
	return obj->array[obj->front];
}

/** Get the last item from the queue. */
int myCircularQueueRear(MyCircularQueue* obj) {
	if (obj->size == 0)
		return -1;
	if (obj->rear == 0)
		return obj->array[obj->k - 1];
	return obj->array[obj->rear - 1];
}

/** Checks whether the circular queue is empty or not. */
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
	if (obj->size == 0)
		return true;
	return false;
}

/** Checks whether the circular queue is full or not. */
bool myCircularQueueIsFull(MyCircularQueue* obj) {
	if (obj->size == obj->k)
		return true;
	return false;
}

void myCircularQueueFree(MyCircularQueue* obj) {
	free(obj->array);
	free(obj);
}

/**
 * Your MyCircularQueue struct will be instantiated and called as such:
 * MyCircularQueue* obj = myCircularQueueCreate(k);
 * bool param_1 = myCircularQueueEnQueue(obj, value);
 
 * bool param_2 = myCircularQueueDeQueue(obj);
 
 * int param_3 = myCircularQueueFront(obj);
 
 * int param_4 = myCircularQueueRear(obj);
 
 * bool param_5 = myCircularQueueIsEmpty(obj);
 
 * bool param_6 = myCircularQueueIsFull(obj);
 
 * myCircularQueueFree(obj);
*/

四:二叉樹

  1. 單值二叉樹。OJ鏈接
    題解:
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

bool isU(struct TreeNode* root, int key)
{
    if(root == NULL)
        return true;

    return root->val == key
    && isU(root->left, key)
    && isU(root->right, key);
}

bool isUnivalTree(struct TreeNode* root){
    return isU(root, root->val);
}
  1. 二叉樹最大深度。OJ鏈接

題解:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */




int maxDepth(struct TreeNode* root){
    if(root==NULL){
        return 0;
    }
    int l=maxDepth(root->left);
    int r=maxDepth(root->right);
    return l>r?l+1:r+1;
}
  1. 翻轉二叉樹。OJ鏈接

題解:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

void _invert(struct TreeNode* root)
{
    if(root)
    {
        //翻轉左右孩子
        struct TreeNode* tmp = root->left;
        root->left = root->right;
        root->right = tmp;
        //子樹翻轉
        _invert(root->left);
        _invert(root->right);
    }
}

struct TreeNode* invertTree(struct TreeNode* root){
    _invert(root);
    return root;
}
  1. 檢查兩棵樹是否相同OJ鏈接

題解:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */


bool isSameTree(struct TreeNode* p, struct TreeNode* q){
    //同時走到空, 結構相同
    if(q == NULL && p == NULL)
        return true;
    //沒有同時走到空, 結構不同
    if(q == NULL || p == NULL)
        return false;
    // 對應位置的值以及子結構是否相同
    return p->val == q->val
    && isSameTree(p->left, q->left)
    && isSameTree(p->right, q->right);
}
  1. 對稱二叉樹OJ鏈接

題解:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

bool isSy(struct TreeNode* p, struct TreeNode* q){
    //同時走到空, 結構相同
    if(q == NULL && p == NULL)
        return true;
    //沒有同時走到空, 結構不同
    if(q == NULL || p == NULL)
        return false;
    // 對應位置的值以及子結構是否相同
    return p->val == q->val
    && isSy(p->left, q->right)
    && isSy(p->right, q->left);
}

bool isSymmetric(struct TreeNode* root){
    if(root == NULL)
        return true;
    return isSy(root->left, root->right);
}
  1. 二叉樹的前序遍歷OJ鏈接

題解:

/*
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
int getSize(struct TreeNode* root)
{
    if(root == NULL)
        return 0;
    return getSize(root->left) 
    + getSize(root->right) + 1;
}

void _preorderT(struct TreeNode* root, int* array, int* idx)
{
    if(root)
    {
        //當前節點, 索引用指針
        array[*idx] = root->val;
        ++(*idx);
        //左子樹
        _preorderT(root->left, array, idx);
        //右子樹
        _preorderT(root->right, array, idx);

    }
}

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* preorderTraversal(struct TreeNode* root, int* returnSize){
    int* array = (int*) malloc(sizeof(int) * getSize(root));
    //遍歷,保存節點
    *returnSize = 0;
    _preorderT(root, array, returnSize);
    return array;
}
  1. 二叉樹的中序遍歷OJ鏈接

題解:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
int getSize(struct TreeNode* root)
{
    if(root == NULL)
        return 0;
    return getSize(root->left) 
    + getSize(root->right) + 1;
}

void _inorderT(struct TreeNode* root, int* array, int* idx)
{
    if(root)
    {
        //左子樹
        _inorderT(root->left, array, idx);

        //當前節點, 索引用指針
        array[*idx] = root->val;
        ++(*idx);

        //右子樹
        _inorderT(root->right, array, idx);

    }
}

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* inorderTraversal(struct TreeNode* root, int* returnSize){
    int* array = (int*) malloc(sizeof(int) * getSize(root));
    //遍歷,保存節點
    *returnSize = 0;
    _inorderT(root, array, returnSize);
    return array;
}
  1. 二叉樹的後續遍歷OJ鏈接

題解:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
int getSize(struct TreeNode* root)
{
    if(root == NULL)
        return 0;
    return getSize(root->left) 
    + getSize(root->right) + 1;
}

void _postorderT(struct TreeNode* root, int* array, int* idx)
{
    if(root)
    {
        //左子樹
        _postorderT(root->left, array, idx);

        //右子樹
        _postorderT(root->right, array, idx);

        //當前節點, 索引用指針
        array[*idx] = root->val;
        ++(*idx);
    }
}

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* postorderTraversal(struct TreeNode* root, int* returnSize){
    int* array = (int*) malloc(sizeof(int) * getSize(root));
    //遍歷,保存節點
    *returnSize = 0;
    _postorderT(root, array, returnSize);
    return array;
}
  1. 另一棵樹的子樹OJ鏈接

題解:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */


bool isSameTree(struct TreeNode* p, struct TreeNode* q){
    //同時走到空, 結構相同
    if(q == NULL && p == NULL)
        return true;
    //沒有同時走到空, 結構不同
    if(q == NULL || p == NULL)
        return false;
    // 對應位置的值以及子結構是否相同
    return p->val == q->val
    && isSameTree(p->left, q->left)
    && isSameTree(p->right, q->right);
}

bool isSubtree(struct TreeNode* s, struct TreeNode* t){
    //任何樹都包含空樹
    if(t == NULL)
        return true;
    //空樹不包含非空的樹
    if(s == NULL)
        return false;

    if(isSameTree(s, t))
        return true;
    //判斷左右子樹是否包含相同的結構
    return isSubtree(s->left, t) || isSubtree(s->right, t);
}
  1. 判斷一棵二叉樹是否時平衡二叉樹。OJ鏈接

題解:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

int  getH(struct TreeNode* root)
{
	if (root == NULL)
		return 0;
	int l = getH(root->left);
	int r = getH(root->right);
	return l > r ? l + 1 : r + 1;
}

bool isBalanced(struct TreeNode* root){
	//遍歷每一個節點,判斷節點左右子樹的高度差是否不超過1
	if (root == NULL)
		return true;
	int l = getH(root->left);
	int r = getH(root->right);
	return abs(l - r) < 2
		&& isBalanced(root->left)
		&& isBalanced(root->right);
}
  1. 二叉樹的構建及遍歷OJ鏈接

題解:

#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
	struct Node* left;
	struct Node* right;
	char val;
}Node;

/*
Node* creatTree(char* str, int* idx)
{
if(str[*idx] != '#')
{
//建立根節點
Node* root = (Node*) malloc(sizeof(Node));
root->val = str[*idx];
++(*idx);
root->left = creatTree(str, idx);
++(*idx);
root->right = creatTree(str, idx);
return root;
}
else
return NULL;
}
*/
Node* creatTree(char** str)
{
	if (*(*str) != '#')
	{
		//建立根節點
		Node* root = (Node*)malloc(sizeof(Node));
		root->val = *(*str);
		++(*str);
		root->left = creatTree(str);
		++(*str);
		root->right = creatTree(str);
		return root;
	}
	else
		return NULL;
}

void inOrder(Node* root)
{
	if (root)
	{
		inOrder(root->left);
		printf("%c ", root->val);
		inOrder(root->right);
	}
}

int main()
{
	//char str[101] = {0};
	char* str = (char*)malloc(sizeof(char)* 101);
	scanf("%s", str);
	int idx = 0;
	//Node* root = creatTree(str, &idx);
	Node* root = creatTree(&str);

	inOrder(root);
	printf("\n");
	return 0;
}

五:排序

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章