当前位置: 首页 > article >正文

C言算法面试:分类与高频题解析

C言算法面试:分类与高频题解析

算法在编程面试中是必考的内容,熟练掌握常见的算法类型和解题思路是通往 offer 的关键。本文将对算法面试题进行分类,总结高频题目,并给出用 C 语言实现的示例代码。


一、算法面试题分类

1. 数组与字符串

  • 特点:线性数据结构,容易产生边界问题。
  • 常见考点
    • 双指针
    • 滑动窗口
    • 排序与搜索
高频题:
  1. 两数之和
    给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的两个整数,并返回它们的数组下标。

代码实现

#include <stdio.h>
#include <stdlib.h>

// 哈希表结构体
typedef struct {
    int key;
    int value;
} HashNode;

int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
    HashNode* hashTable = (HashNode*)malloc(numsSize * sizeof(HashNode));
    int hashSize = 0;

    for (int i = 0; i < numsSize; i++) {
        int complement = target - nums[i];
        for (int j = 0; j < hashSize; j++) {
            if (hashTable[j].key == complement) {
                int* result = (int*)malloc(2 * sizeof(int));
                result[0] = hashTable[j].value;
                result[1] = i;
                *returnSize = 2;
                free(hashTable);
                return result;
            }
        }
        hashTable[hashSize].key = nums[i];
        hashTable[hashSize].value = i;
        hashSize++;
    }

    *returnSize = 0;
    free(hashTable);
    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;
}

2. 链表

  • 特点:动态数据结构,考察指针操作。
  • 常见考点
    • 快慢指针
    • 链表的反转
    • 环检测
高频题:
  1. 反转链表
    给定一个单链表,反转链表并返回反转后的头节点。

代码实现

#include <stdio.h>
#include <stdlib.h>

typedef struct ListNode {
    int val;
    struct ListNode* next;
} ListNode;

// 反转链表函数
struct ListNode* reverseList(struct ListNode* head) {
    struct ListNode* prev = NULL;
    struct ListNode* current = head;

    while (current != NULL) {
        struct ListNode* nextTemp = current->next;
        current->next = prev;
        prev = current;
        current = nextTemp;
    }
    return prev;
}

// 测试代码
void printList(ListNode* head) {
    while (head != NULL) {
        printf("%d -> ", head->val);
        head = head->next;
    }
    printf("NULL\n");
}

int main() {
    ListNode* head = (ListNode*)malloc(sizeof(ListNode));
    head->val = 1;
    head->next = (ListNode*)malloc(sizeof(ListNode));
    head->next->val = 2;
    head->next->next = (ListNode*)malloc(sizeof(ListNode));
    head->next->next->val = 3;
    head->next->next->next = NULL;

    printf("Original List: ");
    printList(head);

    ListNode* reversed = reverseList(head);
    printf("Reversed List: ");
    printList(reversed);

    return 0;
}

3. 栈与队列

  • 特点:先进后出(栈)与先进先出(队列)。
  • 常见考点
    • 括号匹配
    • 单调栈
    • 滑动窗口最大值
高频题:
  1. 有效的括号
    给定一个只包括 ()[]{} 的字符串,判断字符串是否有效。

代码实现

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

bool isValid(char* s) {
    char* stack = (char*)malloc(strlen(s) * sizeof(char));
    int top = -1;

    for (int i = 0; s[i] != '\0'; i++) {
        char c = s[i];
        if (c == '(' || c == '{' || c == '[') {
            stack[++top] = c;
        } else {
            if (top == -1) {
                free(stack);
                return false;
            }
            char topChar = stack[top--];
            if ((c == ')' && topChar != '(') ||
                (c == '}' && topChar != '{') ||
                (c == ']' && topChar != '[')) {
                free(stack);
                return false;
            }
        }
    }

    bool result = (top == -1);
    free(stack);
    return result;
}

int main() {
    char* s = "({[]})";
    if (isValid(s)) {
        printf("The string is valid.\n");
    } else {
        printf("The string is invalid.\n");
    }
    return 0;
}

4. 动态规划

  • 特点:通过状态转移方程解决问题。
  • 常见考点
    • 背包问题
    • 最长子序列/子数组
    • 零钱兑换
高频题:
  1. 最长公共子序列
    给定两个字符串,返回它们的最长公共子序列的长度。

代码实现

#include <stdio.h>
#include <string.h>

int longestCommonSubsequence(char* text1, char* text2) {
    int m = strlen(text1), n = strlen(text2);
    int dp[m + 1][n + 1];

    for (int i = 0; i <= m; i++) {
        for (int j = 0; j <= n; j++) {
            if (i == 0 || j == 0) {
                dp[i][j] = 0;
            } else if (text1[i - 1] == text2[j - 1]) {
                dp[i][j] = dp[i - 1][j - 1] + 1;
            } else {
                dp[i][j] = (dp[i - 1][j] > dp[i][j - 1]) ? dp[i - 1][j] : dp[i][j - 1];
            }
        }
    }
    return dp[m][n];
}

int main() {
    char* text1 = "abcde";
    char* text2 = "ace";
    printf("The length of LCS is %d\n", longestCommonSubsequence(text1, text2));
    return 0;
}

二、总结

  • 核心思路:清晰的逻辑和代码优化是面试的关键。
  • 实战建议:熟悉常见算法类型及高频题目,确保代码实现无误。

通过本文的讲解,希望你能够在算法面试中更加自信!


http://www.kler.cn/a/523576.html

相关文章:

  • 架构技能(六):软件设计(下)
  • 1.27补题 回训练营
  • 大一计算机的自学总结:异或运算
  • MySQL通过binlog恢复数据
  • Linux之内存管理前世今生(一)
  • [内网安全] 内网渗透 - 学习手册
  • 【算法】快速排序1
  • 探秘 TCP TLP:从背景到实现
  • Python中的asyncio:高效的异步编程模型
  • Python设计模式 - 组合模式
  • 使用 MSYS2 qemu 尝鲜Arm64架构国产Linux系统
  • 电感的Q值+如何判断变压器好坏
  • 【题解】Codeforces Round 996 C.The Trail D.Scarecrow
  • 数据结构(精讲)----树(应用篇)
  • C++/stack_queue
  • ComfyUI中基于Fluxgym训练Flux的Lora模型
  • Spring事件驱动
  • 蛇年说蛇,平添乐趣
  • 大模型不同版本的区别解析
  • 苹果AR眼镜:产品规划与战略路线深度解析
  • 2025年美赛B题-结合Logistic阻滞增长模型和SIR传染病模型研究旅游可持续性-成品论文
  • LTV预估 | 深度学习PLTV之开山鼻祖ZILN
  • LLM - 大模型 ScallingLaws 的设计 100B 预训练方案(PLM) 教程(5)
  • SpringBoot内置Tomcat启动原理
  • FLTK - FLTK1.4.1 - demo - animated - v1
  • Spring Boot 实现文件上传和下载