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