数据结构相关
83. 删除排序链表中的重复元素(2024/3/16)
https://leetcode.cn/problems/remove-duplicates-from-sorted-list/
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* deleteDuplicates(struct ListNode* head) {
typedef struct ListNode * Node;
Node node = head; // 不能直接对head指针进行操作,否则无法返回头结点。
while(node && node->next){
if(node->val == node->next->val){
Node tmp = node->next;
node->next = tmp->next;
free(tmp);
}else{
node = node->next; // 这里加else的原因是重复的元素可能不止两个,比如1,1,1,在对比当前结点和后面一个结点完毕后,如果有重复,删除后再对比当前节点和后继节点,这样可以保证无论有多少个重复都可以被删除。
}
if(node == NULL) break;
}
return head;
}
206. 反转链表(2024/3/16)
https://leetcode.cn/problems/reverse-linked-list/
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head) {
// 核心问题就是把前趋节点存起来
struct ListNode * newHead = NULL; // 需要返回的链表头结点
while(head){ // 从头结点一直到最后一个
struct ListNode * tmp = head; // 将当前结点暂存
head = head->next; // 必须在此刻移动指针,因为下面需要操作当前结点的next结点
tmp->next = newHead; // 当前结点的后继结点指向前一个节点(使用newHead存储,第一次为NULL,第二次为第一个结点)
newHead = tmp; // 存储当前结点,下次循环 作为前一个结点的指针
}
return newHead;
}
61. 旋转链表(2024/3/16)
https://leetcode.cn/problems/rotate-list/
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* rotateRight(struct ListNode* head, int k) {
if(k == 0 || head == NULL) return head; // 如果空表、无需移动的情况直接返回
int count = 1; // 计算表长
struct ListNode * node = head; // 不能直接操作head
while(node->next){
count++;
node = node->next;
}
if(k%count == 0) return head; // 如果k刚好是表长,那么也无需移动
node->next = head; // 将链表头尾相连起来,变成循环链表
int c = count - (k%count); // 拿到旋转之后的头结点 在当前链表中 前面的元素个数
node = head; // 从头结点开始遍历
while(--c) node = node->next; // 移动到 新链表的尾结点,也就是新链表头结点的前一个结点
head = node->next; // 头结点指向 尾结点的后继结点也就是新的头结点
node->next = NULL; // 将其循环从这里切断
return head;
}
20. 有效的括号(2024/3/17)
https://leetcode.cn/problems/valid-parentheses/
使用栈结构实现。
typedef char E;
struct Stack{
E element;
struct Stack* next;
};
typedef struct Stack * Node;
void initStack(Node head){
head->next = NULL;
}
int pushStack(Node head,E element){
Node node = malloc(sizeof(struct Stack));
if(node == NULL) return 0;
node->element = element;
node->next = head->next;
head->next = node;
return 1;
}
E popStack(Node head){
Node tmp = head->next;
E element = tmp->element;
head->next = tmp->next;
free(tmp);
return element;
}
bool isEmpty(Node head){
return head->next == NULL;
}
bool isValid(char* s) {
unsigned long length = strlen(s);
if(length % 2 !=0) return false; // 奇数一定不匹配
struct Stack head;
initStack(&head);
while(*s){
if(*s == '(' || *s == '{' || *s == '['){
pushStack(&head,*s);
}else{
if(isEmpty(&head)) return false; // 如果为空栈,第一个元素就是右括号,那么也无法匹配 直接返回
if(*s == ')' && popStack(&head) != '(') return false;
else if(*s == '}' && popStack(&head) != '{') return false;
else if(*s == ']' && popStack(&head) != '[') return false;
}
*s++;
}
return isEmpty(&head); // 如果表内还有元素,则没有完全匹配。
}