碼字不易蔓倍,對(duì)你有幫助 點(diǎn)贊/轉(zhuǎn)發(fā)/關(guān)注 支持一下作者
微信搜公眾號(hào):不會(huì)編程的程序圓
看更多干貨,獲取第一時(shí)間更新
【1200 題】系列 Github :https://github.com/hairrrrr/1200_Problem
推薦閱讀原文:
https://mp.weixin.qq.com/s/JJrPxiCKEVnYB8vuUlQEug
@[toc]
0022 環(huán)形鏈表 II
給定一個(gè)鏈表,返回鏈表開始入環(huán)的第一個(gè)節(jié)點(diǎn)偶翅。 如果鏈表無環(huán)默勾,則返回 null。
為了表示給定鏈表中的環(huán)倒堕,我們使用整數(shù) pos 來表示鏈表尾連接到鏈表中的位置(索引從 0 開始)灾测。 如果 pos 是 -1,則在該鏈表中沒有環(huán)垦巴。
說明:不允許修改給定的鏈表媳搪。
C 解法:
快慢指針法:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode* fast = head, *slow = head;
while(1){
if(fast == NULL || fast->next == NULL)
return NULL;
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
break;
}
fast = head;
while(fast != slow){
fast = fast->next;
slow = slow->next;
}
return fast;
}
0023 數(shù)組形式的整數(shù)加法
https://leetcode-cn.com/problems/add-to-array-form-of-integer/
C :
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* addToArrayForm(int* A, int ASize, int K, int* returnSize){
int i, j, AddSize;
int a[4] = {0}; // K 只有 5 位且 A 數(shù)組大小至少為 1
int* newArr;
i = ASize - 1;
while(K != 0 && i >= 0){
K = A[i] + K;
A[i] = K % 10;
K /= 10;
i--;
}
// 如果 K == 0,說明沒有進(jìn)位問題且A數(shù)組大小夠用
if(K == 0){
*returnSize = ASize;
return A;
}
// A數(shù)組大小不夠用骤宣,需要擴(kuò)容
// 我的思路是:先將多余的位從低位到高位存儲(chǔ)在數(shù)組a中秦爆;然后malloc一個(gè)合適大小的數(shù)組,將a中的位按從高到低存儲(chǔ)在新數(shù)組中憔披,然后再將A中的位復(fù)制到新數(shù)組中
i = 0;
while(K != 0){
a[i++] = K % 10;
K /= 10;
}
AddSize = i;
newArr = (int*)malloc(sizeof(int) * (AddSize + ASize));
for(i = AddSize - 1, j = 0; i >= 0; i--, j++)
newArr[j] = a[i];
for(i = 0; i < ASize; i++, j++)
newArr[j] = A[i];
*returnSize = AddSize + ASize;
return newArr;
}
0024 復(fù)制帶隨機(jī)指針的鏈表
https://leetcode-cn.com/problems/copy-list-with-random-pointer/
**C **
/**
* Definition for a Node.
* struct Node {
* int val;
* struct TreeNode *next;
* struct TreeNode *random;
* };
*/
struct Node* copyRandomList(struct Node* head) {
if(head == NULL)
return NULL;
struct Node* orig_node, *clone_node, *newHead;
// 1. 復(fù)制結(jié)點(diǎn)
orig_node = head;
while(orig_node != NULL){
clone_node = (struct Node*)malloc(sizeof(struct Node));
clone_node->val = orig_node->val;
clone_node->next = orig_node->next;
orig_node->next = clone_node;
orig_node = clone_node->next;
}
// 2. 復(fù)制隨機(jī)指針
orig_node = head;
while(orig_node != NULL){
orig_node->next->random = (orig_node->random == NULL) ? NULL : orig_node->random->next;
orig_node = orig_node->next->next;
}
// 3. 拆鏈
orig_node = head;
clone_node = orig_node->next;
newHead = clone_node;
while(orig_node != NULL){
orig_node->next = orig_node->next->next;
clone_node->next = (clone_node->next == NULL)? NULL : clone_node->next->next;
orig_node = orig_node->next;
clone_node = clone_node->next;
}
return newHead;
}
0025 對(duì)鏈表進(jìn)行插入排序
https://leetcode-cn.com/problems/insertion-sort-list/
插入排序的動(dòng)畫演示如上等限。從第一個(gè)元素開始,該鏈表可以被認(rèn)為已經(jīng)部分排序(用黑色表示)芬膝。
每次迭代時(shí)望门,從輸入數(shù)據(jù)中移除一個(gè)元素(用紅色表示),并原地將其插入到已排好序的鏈表中锰霜。
插入排序算法:
插入排序是迭代的筹误,每次只移動(dòng)一個(gè)元素,直到所有元素可以形成一個(gè)有序的輸出列表癣缅。
每次迭代中厨剪,插入排序只從輸入數(shù)據(jù)中移除一個(gè)待排序的元素,找到它在序列中適當(dāng)?shù)奈恢糜汛妫⑵洳迦搿?br>
重復(fù)直到所有輸入數(shù)據(jù)插入完為止祷膳。
示例 1:
輸入: 4->2->1->3
輸出: 1->2->3->4
示例 2:
輸入: -1->5->3->4->0
輸出: -1->0->3->4->5
**C **
解法如圖:
https://leetcode-cn.com/problems/insertion-sort-list/comments/93262
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* insertionSortList(struct ListNode* head){
if(head == NULL || head->next == NULL)
return head;
struct ListNode dummyHead;
struct ListNode* prev = head, *cur = head->next;
dummyHead.next = head;
while(cur != NULL){
if(cur->val < prev->val){
struct ListNode* find = &dummyHead;
while(find->next->val < cur->val){
find = find->next;
}
prev->next = cur->next;
cur->next = find->next;
find->next = cur;
cur = prev->next;
}
else{
prev = prev->next;
cur = cur->next;
}
}
return dummyHead.next;
}
0026 有效的括號(hào)
https://leetcode-cn.com/problems/valid-parentheses/
給定一個(gè)只包括 '(',')'屡立,'{'直晨,'}','['侠驯,']' 的字符串抡秆,判斷字符串是否有效。
有效字符串需滿足:
左括號(hào)必須用相同類型的右括號(hào)閉合吟策。
左括號(hào)必須以正確的順序閉合儒士。
注意空字符串可被認(rèn)為是有效字符串。
示例 1:
輸入: "()"
輸出: true
示例 2:
輸入: "()[]{}"
輸出: true
示例 3:
輸入: "(]"
輸出: false
示例 4:
輸入: "([)]"
輸出: false
示例 5:
輸入: "{[]}"
輸出: true
C
解法如圖:
https://leetcode-cn.com/problems/valid-parentheses/solution/shun-xu-zhan-bian-li-zi-fu-chuan-pi-pei-by-zhi-an-/
bool isValid(char * s){
if(s == NULL)
return true;
int len = strlen(s);
char* stack = (char*)malloc(sizeof(char) * len);
int i, top = -1;
// 這說明 len 是奇數(shù) if 的判斷表達(dá)式和 len % 2 != 0 同理
if(len & 1 == 1){
free(stack);
return false;
}
for(i = 0; i < len; i++){
if(s[i] == '{' || s[i] == '[' || s[i] == '(')
stack[++top] = s[i];
// 輸入的不是左括號(hào)且楅菁幔空
else if(top == -1){
free(stack);
return false;
}
// 利用了括號(hào)的ASCII碼值着撩,如果匹配則讓右括號(hào)出棧
else if(s[i] == stack[top] + 1 || s[i] == stack[top] + 2)
top--;
else{
free(stack);
return false;
}
}
free(stack);
return top == -1;
}
0027 用棧實(shí)現(xiàn)隊(duì)列
https://leetcode-cn.com/problems/implement-queue-using-stacks
使用棧實(shí)現(xiàn)隊(duì)列的下列操作:
push(x) -- 將一個(gè)元素放入隊(duì)列的尾部诅福。
pop() -- 從隊(duì)列首部移除元素。
peek() -- 返回隊(duì)列首部的元素拖叙。
empty() -- 返回隊(duì)列是否為空氓润。
示例:
MyQueue queue = new MyQueue();
queue.push(1);
queue.push(2);
queue.peek(); // 返回 1
queue.pop(); // 返回 1
queue.empty(); // 返回 false
說明:
你只能使用標(biāo)準(zhǔn)的棧操作 -- 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的語言也許不支持棧薯鳍。你可以使用 list 或者 deque(雙端隊(duì)列)來模擬一個(gè)棧咖气,只要是標(biāo)準(zhǔn)的棧操作即可。
假設(shè)所有操作都是有效的 (例如挖滤,一個(gè)空的隊(duì)列不會(huì)調(diào)用 pop 或者 peek 操作)崩溪。
C
以下是模板:
typedef struct {
} MyQueue;
/** Initialize your data structure here. */
MyQueue* myQueueCreate() {
}
/** Push element x to the back of queue. */
void myQueuePush(MyQueue* obj, int x) {
}
/** Removes the element from in front of queue and returns that element. */
int myQueuePop(MyQueue* obj) {
}
/** Get the front element. */
int myQueuePeek(MyQueue* obj) {
}
/** Returns whether the queue is empty. */
bool myQueueEmpty(MyQueue* obj) {
}
void myQueueFree(MyQueue* 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);
*/
解法:
注意: 第三步邏輯有點(diǎn)問題。入隊(duì)直接入A棧即可斩松。(因?yàn)槌鲫?duì)會(huì)先將B棧清空后才會(huì)再從A棧導(dǎo)入B棧)
我分了 4 個(gè)文件寫伶唯,stack.h,stack.c,stackQueue.h,stackQueue.c,這里就放后兩個(gè)文件,想看詳細(xì)的去 Github 上看惧盹。
stackQueue.h
#ifndef STACK_QUEUE
#define STCK_QUEUE
#include"stack.h"
#define QUEUE_SIZE 50
typedef int DataType;
typedef struct {
Stack* stackIn;
Stack* stackOut;
} MyQueue;
/** Initialize your data structure here. */
MyQueue* myQueueCreate();
/** Push element x to the back of queue. */
void myQueuePush(MyQueue* obj, DataType x);
/** Removes the element from in front of queue and returns that element. */
DataType myQueuePop(MyQueue* obj);
/** Get the front element. */
DataType myQueuePeek(MyQueue* obj);
/** Returns whether the queue is empty. */
bool myQueueEmpty(MyQueue* obj);
bool myQueueFull(MyQueue* obj);
void myQueueFree(MyQueue* obj);
/**
* Your MyQueue struct will be instantiated and called as such:
* MyQueue* obj = myQueueCreate();
* myQueuePush(obj, x);
* DataType param_2 = myQueuePop(obj);
* DataType param_3 = myQueuePeek(obj);
* bool param_4 = myQueueEmpty(obj);
* myQueueFree(obj);
*/
#endif
stackQueue.c
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include"stackQueue.h"
#include"stack.h"
// 兩個(gè)棧的轉(zhuǎn)換乳幸,static 類似 private 的用法
static void myQueueTransfer(Stack* from, Stack* to) {
while(!stackIsEmpty(from))
stackPush(to, stackPop(from));
}
MyQueue* myQueueCreate() {
MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
obj->stackIn = stackInit(QUEUE_SIZE);
obj->stackOut = stackInit(QUEUE_SIZE);
return obj;
}
void myQueuePush(MyQueue* obj, DataType x) {
if (!myQueueFull(obj)) {
stackPush(obj->stackIn, x);
}
}
DataType myQueuePop(MyQueue* obj) {
if (!myQueueEmpty(obj)) {
if (!stackIsEmpty(obj->stackOut))
return stackPop(obj->stackOut);
myQueueTransfer(obj->stackIn, obj->stackOut);
return stackPop(obj->stackOut);
}
else {
exit(EXIT_FAILURE);
}
}
DataType myQueuePeek(MyQueue* obj) {
if (!myQueueEmpty(obj)) {
if (!stackIsEmpty(obj->stackOut))
return stackPeek(obj->stackOut);
myQueueTransfer(obj->stackIn, obj->stackOut);
return stackPeek(obj->stackOut);
}
else {
exit(EXIT_FAILURE);
}
}
bool myQueueEmpty(MyQueue* obj) {
return stackSize(obj->stackIn) && stackSize(obj->stackOut);
}
bool myQueueFull(MyQueue* obj) {
return stackSize(obj->stackIn) + stackSize(obj->stackOut) == QUEUE_SIZE;
}
void myQueueFree(MyQueue* obj) {
stackDestory(obj->stackIn);
stackDestory(obj->stackOut);
obj->stackIn = obj->stackOut = NULL;
free(obj);
}
0028 用隊(duì)列實(shí)現(xiàn)棧
https://leetcode-cn.com/problems/implement-stack-using-queues/
使用隊(duì)列實(shí)現(xiàn)棧的下列操作:
push(x) -- 元素 x 入棧
pop() -- 移除棧頂元素
top() -- 獲取棧頂元素
empty() -- 返回棧是否為空
注意:
你只能使用隊(duì)列的基本操作-- 也就是 push to back, peek/pop from front, size, 和 is empty 這些操作是合法的。
你所使用的語言也許不支持隊(duì)列钧椰。 你可以使用 list 或者 deque(雙端隊(duì)列)來模擬一個(gè)隊(duì)列 , 只要是標(biāo)準(zhǔn)的隊(duì)列操作即可粹断。
你可以假設(shè)所有操作都是有效的(例如, 對(duì)一個(gè)空的棧不會(huì)調(diào)用 pop 或者 top 操作)。
C
總共四個(gè)文件嫡霞,這里寫兩個(gè)文件內(nèi)容姿染,剩下的請去 Github 上查看
queue_stack.h
#ifndef QUEUE_STACK
#define QUEUE_STACK
#include"queue.h"
#include<stdbool.h>
typedef int DataType;
typedef struct {
Queue q;
} MyStack;
/** Initialize your data structure here. */
MyStack* myStackCreate();
/** Push element x onto stack. */
void myStackPush(MyStack* obj, DataType x);
/** Removes the element on top of the stack and returns that element. */
DataType myStackPop(MyStack* obj);
/** Get the top element. */
DataType myStackTop(MyStack* obj);
/** Returns whether the stack is empty. */
bool myStackEmpty(MyStack* obj);
void myStackFree(MyStack* obj);
/**
* Your MyStack struct will be instantiated and called as such:
* MyStack* obj = myStackCreate();
* myStackPush(obj, x);
* DataType param_2 = myStackPop(obj);
* DataType param_3 = myStackTop(obj);
* bool param_4 = myStackEmpty(obj);
* myStackFree(obj);
*/
#endif
queue_stack.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"queue_stack.h"
#include"queue.h"
#include<stdlib.h>
#include<stdbool.h>
MyStack* myStackCreate() {
MyStack* obj = (MyStack*)malloc(sizeof(MyStack));
queueInit(&obj->q);
return obj;
}
void myStackPush(MyStack* obj, DataType x) {
queuePush(&obj->q, x);
}
DataType myStackPop(MyStack* obj) {
DataType size = queueSize(&obj->q);
// 讓隊(duì)尾前的元素出隊(duì)然后入隊(duì),最后讓隊(duì)尾出隊(duì)
while (size > 1) {
int front = queuePop(&obj->q);
queuePush(&obj->q, front);
size--;
}
return queuePop(&obj->q);
}
DataType myStackTop(MyStack* obj) {
return obj->q.rear->data;
}
bool myStackEmpty(MyStack* obj) {
return queueIsEmpty(&obj->q);
}
void myStackFree(MyStack* obj) {
queueDestory(&obj->q);
free(obj);
}
0029 設(shè)計(jì)循環(huán)隊(duì)列
https://leetcode-cn.com/problems/design-circular-queue/
設(shè)計(jì)你的循環(huán)隊(duì)列實(shí)現(xiàn)秒际。 循環(huán)隊(duì)列是一種線性數(shù)據(jù)結(jié)構(gòu),其操作表現(xiàn)基于 FIFO(先進(jìn)先出)原則并且隊(duì)尾被連接在隊(duì)首之后以形成一個(gè)循環(huán)狡汉。它也被稱為“環(huán)形緩沖器”娄徊。
循環(huán)隊(duì)列的一個(gè)好處是我們可以利用這個(gè)隊(duì)列之前用過的空間。在一個(gè)普通隊(duì)列里盾戴,一旦一個(gè)隊(duì)列滿了寄锐,我們就不能插入下一個(gè)元素,即使在隊(duì)列前面仍有空間尖啡。但是使用循環(huán)隊(duì)列橄仆,我們能使用這些空間去存儲(chǔ)新的值。
你的實(shí)現(xiàn)應(yīng)該支持如下操作:
MyCircularQueue(k): 構(gòu)造器衅斩,設(shè)置隊(duì)列長度為 k 盆顾。
Front: 從隊(duì)首獲取元素。如果隊(duì)列為空畏梆,返回 -1 您宪。
Rear: 獲取隊(duì)尾元素奈懒。如果隊(duì)列為空,返回 -1 宪巨。
enQueue(value): 向循環(huán)隊(duì)列插入一個(gè)元素磷杏。如果成功插入則返回真。
deQueue(): 從循環(huán)隊(duì)列中刪除一個(gè)元素捏卓。如果成功刪除則返回真极祸。
isEmpty(): 檢查循環(huán)隊(duì)列是否為空。
isFull(): 檢查循環(huán)隊(duì)列是否已滿怠晴。
示例:
MyCircularQueue circularQueue = new MyCircularQueue(3); // 設(shè)置長度為 3
circularQueue.enQueue(1); // 返回 true
circularQueue.enQueue(2); // 返回 true
circularQueue.enQueue(3); // 返回 true
circularQueue.enQueue(4); // 返回 false遥金,隊(duì)列已滿
circularQueue.Rear(); // 返回 3
circularQueue.isFull(); // 返回 true
circularQueue.deQueue(); // 返回 true
circularQueue.enQueue(4); // 返回 true
circularQueue.Rear(); // 返回 4
提示:
所有的值都在 0 至 1000 的范圍內(nèi);
操作數(shù)將在 1 至 1000 的范圍內(nèi)龄寞;
請不要使用內(nèi)置的隊(duì)列庫汰规。
循環(huán)隊(duì)列是滿還是空的判斷方法其實(shí)值得我們思考:
- 如果存放循環(huán)隊(duì)列的數(shù)組每個(gè)元素都可以是隊(duì)列的一部分,那么我們需要提供一個(gè)變量來記錄隊(duì)列的大小物邑。
- 如果我們不想使用變量來記錄隊(duì)列的大小溜哮,我們需要讓數(shù)組的一個(gè)元素始終不屬于隊(duì)列。那么隊(duì)列為空時(shí):
front == rear
色解;隊(duì)列為滿時(shí):(rear + 1) % k(數(shù)組大小) == front
如何理解第二種情況的公式呢茂嗓?
如圖第一種情況:這種情況比較普通,這時(shí)候其實(shí)不用模數(shù)組的大小科阎,只要 rear + 1 == front
即可判滿
第二種情況:rear + 1 會(huì)越界述吸,這時(shí)候我們才需要對(duì)數(shù)組大小求模
為了方便起見,我們直接對(duì)數(shù)組大小求模即可锣笨。
C
我們先來做第一種方法蝌矛,即整個(gè)數(shù)組都可以用來存放隊(duì)列元素。
myCircularQueue.h
#ifndef MY_CIRCULAR_QUEUE
#define MY_CIRCULAR_QUEUE
#include<stdbool.h>
typedef int DataType;
typedef struct {
int* queue;
int front;
int rear;
int queue_size;
int capacity;
} MyCircularQueue;
/** Initialize your data structure here. Set the size of the queue to be k. */
MyCircularQueue* myCircularQueueCreate(DataType k);
/** Insert an element into the circular queue. Return true if the operation is successful. */
bool myCircularQueueEnQueue(MyCircularQueue* obj, DataType value);
/** Delete an element from the circular queue. Return true if the operation is successful. */
bool myCircularQueueDeQueue(MyCircularQueue* obj);
/** Get the front item from the queue. */
DataType myCircularQueueFront(MyCircularQueue* obj);
/** Get the last item from the queue. */
DataType myCircularQueueRear(MyCircularQueue* obj);
/** Checks whether the circular queue is empty or not. */
bool myCircularQueueIsEmpty(MyCircularQueue* obj);
/** Checks whether the circular queue is full or not. */
bool myCircularQueueIsFull(MyCircularQueue* obj);
void myCircularQueueFree(MyCircularQueue* 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);
*/
#endif
myCircularQueue.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"myCircularQueue.h"
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
MyCircularQueue* myCircularQueueCreate(DataType k) {
MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
obj->queue = (int*)malloc(sizeof(int) * k);
obj->capacity = k;
obj->front = obj->rear = 0;
obj->queue_size = 0;
return obj;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, DataType value) {
if (myCircularQueueIsFull(obj))
return false;
obj->queue[obj->rear] = value;
obj->rear = (obj->rear + 1) % obj->capacity;
obj->queue_size++;
return true;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj))
return false;
obj->front = (obj->front + 1) % obj->capacity;
obj->queue_size--;
return true;
}
DataType myCircularQueueFront(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj))
return -1;
return obj->queue[obj->front];
}
DataType myCircularQueueRear(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj))
return -1;
if(obj->rear - 1 < 0)
return obj->queue[obj->capacity - 1];
return obj->queue[obj->rear - 1];
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->queue_size == 0;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return obj->queue_size == obj->capacity;
}
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->queue);
obj->queue = NULL;
free(obj);
}
第二種方法:
myCircularQueue2.h
#ifndef MY_CIRCULAR_QUEUE
#define MY_CIRCULAR_QUEUE
#include<stdbool.h>
typedef int DataType;
typedef struct {
int* queue;
int front;
int rear;
int capacity;
} MyCircularQueue;
/** Initialize your data structure here. Set the size of the queue to be k. */
MyCircularQueue* myCircularQueueCreate(DataType k);
/** Insert an element into the circular queue. Return true if the operation is successful. */
bool myCircularQueueEnQueue(MyCircularQueue* obj, DataType value);
/** Delete an element from the circular queue. Return true if the operation is successful. */
bool myCircularQueueDeQueue(MyCircularQueue* obj);
/** Get the front item from the queue. */
DataType myCircularQueueFront(MyCircularQueue* obj);
/** Get the last item from the queue. */
DataType myCircularQueueRear(MyCircularQueue* obj);
/** Checks whether the circular queue is empty or not. */
bool myCircularQueueIsEmpty(MyCircularQueue* obj);
/** Checks whether the circular queue is full or not. */
bool myCircularQueueIsFull(MyCircularQueue* obj);
void myCircularQueueFree(MyCircularQueue* 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);
*/
#endif
myCircularQueue2.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"myCircularQueue.h"
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
MyCircularQueue* myCircularQueueCreate(DataType k) {
MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
obj->queue = (int*)malloc(sizeof(int) * (k + 1)); // 需要多一個(gè)元素用來判別隊(duì)列空還是滿
// 注意:這里我們給 capacity 賦值是 k 而不是 k + 1错英,后面需要取模數(shù)組長度時(shí)需要注意
obj->capacity = k;
obj->front = obj->rear = 0;
return obj;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, DataType value) {
if (myCircularQueueIsFull(obj))
return false;
obj->queue[obj->rear] = value;
obj->rear = (obj->rear + 1) % (obj->capacity + 1);
return true;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj))
return false;
obj->front = (obj->front + 1) % (obj->capacity + 1);
return true;
}
DataType myCircularQueueFront(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj))
return -1;
return obj->queue[obj->front];
}
DataType myCircularQueueRear(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj))
return -1;
if(obj->rear - 1 < 0)
return obj->queue[obj->capacity];
return obj->queue[obj->rear - 1];
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->front == obj->rear;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return ((obj->rear + 1) % (obj->capacity + 1) == obj->front);
}
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->queue);
obj->queue = NULL;
free(obj);
}
反思
1)鏈表后面的題還是有一定難度的入撒,有點(diǎn)像奧數(shù)題,總之在寫代碼之前一定要先考慮清楚椭岩,這道題:
- 需不需要處理頭結(jié)點(diǎn)(使用傀儡結(jié)點(diǎn))
- 快慢指針(雙指針)法是否可以應(yīng)用茅逮?
- 邏輯問題思考清楚,必要時(shí)需要建立等式判哥。
2)0026 題只是簡單的應(yīng)用了棧的思想献雅,關(guān)于棧更高級(jí)的應(yīng)用還在后面
3)關(guān)于隊(duì)列我們需要注意:
- 入隊(duì):我們需要判斷當(dāng)前是否是空隊(duì),如果是塌计,我們需要改變 front
- 出隊(duì):我們需要判斷 front 是否成為了空指針挺身,如果是,我們需要置空 rear
4)LeetCode 上 Heap-Over-Flow 報(bào)錯(cuò)可以考慮一下是否是數(shù)組越界造成的锌仅。
看更詳細(xì)的題目目錄: https://github.com/hairrrrr/1200_Problem
不要忘記 star 呦~
歡迎大家在 評(píng)論區(qū)/私信 提出問題/指正錯(cuò)誤瞒渠,謝謝觀看良蒸。
我是程序圓,我們下次再見伍玖。