数据结构与算法学习之力扣面试刷题篇

学以致用,单纯的学习不去进行使用那么是不会有提高的,对于数据结构和算法的学习,我们不仅需要掌握到它的核心和原理,更应该学以致用,将所学习到的知识点运用到相关的代码之中,将我学习数据结构和算法时所练习的力扣题附在这里大家一起讨论和学习。

一:数组面试题

  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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
算法数据结构它们分别涵盖了以下主要内容: 数据结构(Data Structures): 逻辑结构:描述数据元素之间的逻辑关系,如线性结构(如数组、链表)、树形结构(如二叉树、堆、B树)、图结构(有向图、无向图等)以及集合和队列等抽象数据类型。 存储结构(物理结构):描述数据在计算机中如何具体存储。例如,数组的连续存储,链表的动态分配节点,树和图的邻接矩阵或邻接表表示等。 基本操作:针对每种数据结构,定义了一系列基本的操作,包括但不限于插入、删除、查找、更新、遍历等,并分析这些操作的时间复杂度和空间复杂度。 算法算法设计:研究如何将解决问的步骤形式化为一系列指令,使得计算机可以执行以求解问算法特性:包括输入、输出、有穷性、确定性和可行性。即一个有效的算法必须能在有限步骤内结束,并且对于给定的输入产生唯一的确定输出。 算法分类:排序算法(如冒泡排序、快速排序、归并排序),查找算法(如顺序查找、二分查找、哈希查找),图论算法(如Dijkstra最短路径算法、Floyd-Warshall算法、Prim最小生成树算法),动态规划,贪心算法,回溯法,分支限界法等。 算法分析:通过数学方法分析算法的时间复杂度(运行时间随数据规模增长的速度)和空间复杂度(所需内存大小)来评估其效率。 学习算法数据结构不仅有助于理解程序的内部工作原理,更能帮助开发人员编写出高效、稳定和易于维护的软件系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值