【Leecode 随笔】

在这里插入图片描述

🌈你好呀!我是 山顶风景独好
🎈欢迎踏入我的博客世界,能与您在此邂逅,真是缘分使然!😊
🌸愿您在此停留的每一刻,都沐浴在轻松愉悦的氛围中。
📖这里不仅有丰富的知识和趣味横生的内容等您来探索,更是一个自由交流的平台,期待您留下独特的思考与见解。🌟
🚀让我们一起踏上这段探索与成长的旅程,携手挖掘更多可能,共同进步!💪✨

题目一:两数之和(Two Sum)

题目描述:

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

题目分析:

这是一个典型的哈希表应用问题。我们需要快速判断某个数是否已经出现过,并且需要记录该数出现的位置。哈希表(在C语言中通常使用结构体结合数组或链表实现)能够提供O(1)的查找时间复杂度,非常适合解决此类问题。

解题思路:

创建一个哈希表,用于存储数组中已经遍历过的元素及其索引。
遍历数组,对于每个元素,计算与目标值的差值。
检查差值是否已经在哈希表中存在,如果存在,则返回差值的索引和当前元素的索引。
如果差值不存在于哈希表中,则将当前元素及其索引添加到哈希表中。
重复上述步骤,直到找到答案或遍历完整个数组。

示例代码:

#include <stdio.h>  
#include <stdlib.h>  
  
// 定义哈希表节点  
typedef struct HashNode {  
    int key;  
    int value;  
    struct HashNode* next;  
} HashNode;  
  
// 哈希表大小  
#define HASH_SIZE 1000  
  
// 创建哈希表  
HashNode* hashTable[HASH_SIZE];  
  
// 哈希函数  
int hash(int key) {  
    return key % HASH_SIZE;  
}  
  
// 向哈希表中添加元素  
void addToHashTable(int key, int value) {  
    int index = hash(key);  
    HashNode* newNode = (HashNode*)malloc(sizeof(HashNode));  
    newNode->key = key;  
    newNode->value = value;  
    newNode->next = hashTable[index];  
    hashTable[index] = newNode;  
}  
  
// 从哈希表中查找元素  
int findInHashTable(int key) {  
    int index = hash(key);  
    HashNode* current = hashTable[index];  
    while (current != NULL) {  
        if (current->key == key) {  
            return current->value;  
        }  
        current = current->next;  
    }  
    return -1;  
}  
  
// 两数之和函数  
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {  
    // 初始化哈希表和返回结果  
    for (int i = 0; i < HASH_SIZE; i++) {  
        hashTable[i] = NULL;  
    }  
    *returnSize = 2;  
    int* result = (int*)malloc(2 * sizeof(int));  
  
    // 遍历数组  
    for (int i = 0; i < numsSize; i++) {  
        int complement = target - nums[i];  
        int index = findInHashTable(complement);  
        if (index != -1) {  
            result[0] = index;  
            result[1] = i;  
            return result;  
        }  
        addToHashTable(nums[i], i);  
    }  
  
    // 如果没有找到结果,释放内存并返回NULL  
    free(result);  
    *returnSize = 0;  
    return NULL;  
}  
  
int main() {  
    int nums[] = {2, 7, 11, 15};  
    int target = 9;  
    int returnSize;  
    int* result = twoSum(nums, 4, target, &returnSize);  
    if (result != NULL) {  
        printf("Index1: %d, Index2: %d\n", result[0], result[1]);  
        free(result);  
    } else {  
        printf("No solution found.\n");  
    }  
    return 0;  
}

题目二:合并两个有序链表(Merge Two Sorted Lists)

题目描述:

将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

题目分析:

这是一个链表操作的基础问题,主要考察对链表节点的遍历和新建。由于两个链表都是有序的,我们可以使用双指针法,分别指向两个链表的头部,比较两个指针所指向的节点值,将较小的节点添加到新链表中,并移动对应指针,直到遍历完所有节点。

解题思路:

创建一个虚拟头节点(dummy node),用于简化链表操作。
初始化两个指针,分别指向两个链表的头部。
比较两个指针所指向的节点值,将较小的节点连接到新链表的尾部,并移动对应指针。
如果某个链表遍历完了,直接将另一个链表的剩余部分连接到新链表的尾部。
返回虚拟头节点的下一个节点作为合并后的链表头。

示例代码:

#include <stdio.h>  
#include <stdlib.h>  
  
// 定义链表节点  
typedef struct ListNode {  
    int val;  
    struct ListNode *next;  
} ListNode;  
  
// 合并两个有序链表函数  
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {  
    // 创建虚拟头节点  
    ListNode* dummy = (ListNode*)malloc(sizeof(ListNode));  
    dummy->val = 0;  
    dummy->next = NULL;  
    ListNode* current = dummy;  
  
    // 遍历两个链表  
    while (l1 != NULL && l2 != NULL) {  
        if (l1->val <= l2->val) {  
            current->next = l1;  
            l1 = l1->next;  
        } else {  
            current->next = l2;  
            l2 = l2->next;  
        }  
        current = current->next;  
    }  
  
    // 连接剩余部分  
    if (l1 != NULL) {  
        current->next = l1;  
    } else {  
        current->next = l2;  
    }  
  
    // 返回合并后的链表头  
    ListNode* mergedList = dummy->next;  
    free(dummy);  
    return mergedList;  
}  
  
// 辅助函数:创建链表节点  
ListNode* createListNode(int val) {  
    ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));  
    newNode->val = val;  
    newNode->next = NULL;  
    return newNode;  
}  
  
// 辅助函数:打印链表  
void printList(ListNode* head) {  
    while (head != NULL) {  
        printf("%d -> ", head->val);  
        head = head->next;  
    }  
    printf("NULL\n");  
}  
  
int main() {  
    // 创建两个有序链表  
    ListNode* l1 = createListNode(1);  
    l1->next = createListNode(2);  
    l1->next->next = createListNode(4);  
  
    ListNode* l2 = createListNode(1);  
    l2->next = createListNode(3);  
    l2->next->next = createListNode(4);  
  
    // 合并链表  
    ListNode* mergedList = mergeTwoLists(l1, l2);  
  
    // 打印合并后的链表  
    printList(mergedList);  
  
    // 释放内存(此处省略,实际使用时需注意)  
    return 0;  
}

题目三:有效的括号(Valid Parentheses)

题目描述:

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。

题目分析:

这是一个典型的栈应用问题。我们可以利用栈的后进先出(LIFO)特性,遍历字符串,当遇到左括号时压入栈,当遇到右括号时检查栈顶元素是否为对应的左括号,如果是则弹出栈顶元素,否则返回false。最后,如果栈为空,则说明所有括号都正确匹配,返回true;否则,返回false。

解题思路:

创建一个空栈。
遍历字符串,对于每个字符:
如果是左括号(‘(’,‘{’,‘[’),将其压入栈。
如果是右括号(‘)’,‘}’,‘]’),检查栈是否为空或栈顶元素是否为对应的左括号,如果不是,则返回false。
遍历结束后,检查栈是否为空,如果为空则说明所有括号都正确匹配,返回true;否则,返回false。

示例代码:

#include <stdio.h>  
#include <stdlib.h>  
#include <stdbool.h>  
  
// 定义栈节点  
typedef struct StackNode {  
    char val;  
    struct StackNode *next;  
} StackNode;  
  
// 栈操作函数  
StackNode* createStackNode(char val) {  
    StackNode* newNode = (StackNode*)malloc(sizeof(StackNode));  
    newNode->val = val;  
    newNode->next = NULL;  
    return newNode;  
}  
  
void push(StackNode** top, char val) {  
    StackNode* newNode = createStackNode(val);  
    newNode->next = *top;  
    *top = newNode;  
}  
  
char pop(StackNode** top) {  
    if (*top == NULL) {  
        return '\0'; // 返回空字符表示栈为空  
    }  
    StackNode* temp = *top;  
    char val = temp->val;  
    *top = temp->next;  
    free(temp);  
    return val;  
}  
  
bool isEmpty(StackNode* top) {  
    return top == NULL;  
}  
  
// 有效的括号函数  
bool isValid(char * s) {  
    StackNode* stack = NULL;  
    while (*s != '\0') {  
        if (*s == '(' || *s == '{' || *s == '[') {  
            push(&stack, *s);  
        } else if (*s == ')' || *s == '}' || *s == ']') {  
            if (isEmpty(stack)) {  
                return false;  
            }  
            char top = pop(&stack);  
            if ((*s == ')' && top != '(') ||   
                (*s == '}' && top != '{') ||   
                (*s == ']' && top != '[')) {  
                return false;  
            }  
        } else {  
            // 字符串中包含非法字符,根据题目描述,应返回false  
            return false;  
        }  
        s++;  
    }  
    return isEmpty(stack);  
}  
  
int main() {  
    char s[] = "([{}])";  
    if (isValid(s)) {  
        printf("String is valid.\n");  
    } else {  
        printf("String is not valid.\n");  
    }  
    return 0;  
}

✨ 这就是今天要分享给大家的全部内容了,我们下期再见!😊
🏠 我在CSDN等你哦!我的主页😍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山顶风景独好

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值