题记(三)

本文讨论了链表中的环检测、回文判断、奇偶重排以及有序链表去重等问题,同时也涵盖了二叉树的前序、后序遍历及深度计算,还包括字符串处理和队列实现。这些算法涉及数据结构和递归操作,旨在提高效率和逻辑处理能力。
摘要由CSDN通过智能技术生成

目录

BM6 判断链表中是否有环

BM13 判断一个链表是否为回文结构

BM14 链表的奇偶重排 

BM16 删除有序链表中重复的元素-II

BM10 两个链表的第一个公共结点 

BM25 二叉树的后序遍历 

字符串拷贝 

BM28 二叉树的最大深度

BM29 二叉树中和为某一值的路径(一) 

BM7 链表中环的入口结点 

链表翻转 

BM34 判断是不是二叉搜索树

BM35 判断是不是完全二叉树 

BM36 判断是不是平衡二叉树

BM42 用两个栈实现队列 

BM47 寻找第K大

BM48 数据流中的中位数 

笔试题1. LED灯控制​

笔试题2. 最大优美序列​

笔试题3. 小红走字符串

笔试题4. 回文串​

BM6 判断链表中是否有环

 用快慢指针,快指针比慢指针每次多走一步,最后判断,如果快慢指针相同,就是有环 

bool hasCycle(struct ListNode* head ) {

    // write code here

    if (head==NULL||head->next==NULL) return false;

    struct ListNode *slow = head, *fast = head;

    while (fast && fast->next) {

         slow = slow->next;

         fast = fast->next->next;

         if (slow == fast) return true;

        }

     return false;

BM13 判断一个链表是否为回文结构

快慢指针(找中间结点)+链表反转+判断是否相等 

/**
 * struct ListNode {
 *    int val;
 *    struct ListNode *next;
 * };
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */

/**
 * 
 * @param head ListNode类 the head
 * @return bool布尔型
 */

//求链表的中间结点

struct ListNode* middleNode(struct ListNode* pHead ) {
    struct ListNode *fast, *slow;
    fast = slow = pHead;
    while(fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
    }
    return slow;
}

//反转链表

struct ListNode* ReverseList(struct ListNode* pHead ) {
    struct ListNode* cur = pHead;
    struct ListNode* newhead = NULL;
    while(cur)
    {
        struct ListNode* next = cur->next;
        //头插
        cur->next = newhead;
        newhead = cur;
        cur = next;
    }
    return newhead;
}

bool isPail(struct ListNode* head ) {
    struct ListNode* mid = middleNode(head);
    struct ListNode* rhead = ReverseList(mid);
    struct ListNode* cur = head;
    struct ListNode* curR = rhead;
    while(cur && curR)
    {
        if(cur->val != curR->val)
            return false;
        else{
            cur = cur->next;
            curR = curR->next;
        }
    }
    return true;
}

BM14 链表的奇偶重排 

首先,我们可以使用两个指针来分别指向奇数位节点和偶数位节点的头部。然后,我们可以使用一个指针来遍历整个链表,并根据节点的编号将节点连接到相应的位置上。

具体的实现步骤如下:

  1. 如果链表为空或者只有一个节点,则直接返回链表头部。
  2. 创建两个指针 odd 和 even 分别指向奇数位节点的头部和偶数位节点的头部,初始值分别为链表的第一个节点和第二个节点。
  3. 创建一个指针 curr 用于遍历链表,初始值为链表的第三个节点。
  4. 创建两个指针 oddTail 和 evenTail 分别指向奇数位节点的尾部和偶数位节点的尾部,初始值分别为 odd 和 even。
  5. 创建一个变量 count 并初始化为 3,用于记录当前遍历的节点的编号。
  6. 遍历链表,直到 curr 为空:
    1. 如果 count 是奇数,则将 curr 连接到 oddTail 的后面,并更新 oddTail 为 curr。
    2. 如果 count 是偶数,则将 curr 连接到 evenTail 的后面,并更新 evenTail 为 curr。
    3. 更新 curr 为 curr 的下一个节点。
    4. 更新 count 的值为 count + 1。
  7. 将 even 连接到 oddTail 的后面。
  8. 将 oddTail 的下一个节点置为空,以避免出现循环链表。
  9. 返回 odd。

 // 定义一个函数,输入一个链表头结点,返回重排后的链表头结点
struct ListNode* oddEvenList(struct ListNode* head) {
    // 如果链表为空或者只有一个节点,则直接返回链表头部。
    if (head == NULL || head->next == NULL) {
        return head;
    }   
    // 定义两个指针 odd 和 even 分别指向奇数位节点的头部和偶数位节点的头部,初始值分别为链表的第一个节点和第二个节点。
    struct ListNode* odd = head;
    struct ListNode* even = head->next;    
    // 定义一个指针 curr 用于遍历链表,初始值为链表的第三个节点。
    struct ListNode* curr = head->next->next;    
    // 定义两个指针 oddTail 和 evenTail 分别指向奇数位节点的尾部和偶数位节点的尾部,初始值分别为 odd 和 even。
    struct ListNode* oddTail = odd;
    struct ListNode* evenTail = even;  
    // 定义一个变量 count 并初始化为 3,用于记录当前遍历的节点的编号。
    int count = 3; 
    // 遍历链表,直到 curr 为空:
    while (curr != NULL) {
        // 如果 count 是奇数,则将 curr 连接到 oddTail 的后面,并更新 oddTail 为 curr。
        if (count % 2 == 1) {
            oddTail->next = curr;
            oddTail = curr;
        } 
        // 如果 count 是偶数,则将 curr 连接到 evenTail 的后面,并更新 evenTail 为 curr。
        else {
            evenTail->next = curr;
            evenTail = curr;
        }        
        // 更新 curr 为 curr 的下一个节点。
        curr = curr->next;
        // 更新 count 的值为 count + 1。
        count++;
    }    
    // 将 even 连接到 oddTail 的后面。
    evenTail->next = NULL;
    oddTail->next = even;    
    // 返回 odd 作为重排后的链表的头结点。
    return odd;
}

BM16 删除有序链表中重复的元素-II

首先判断链表是否为空或者只有一个节点,如果是,则直接返回原链表。然后创建一个虚拟头节点,将其指向原链表的头节点。接着定义一个指针prev,初始时指向虚拟头节点。然后开始遍历链表,判断当前节点和下一个节点的值是否相同。如果相同,则删除所有重复元素,即将prev的next指针指向下一个不同值的节点。如果不同,则指针prev指向下一个节点。最后返回删除重复元素后的链表的头节点。

struct ListNode* deleteDuplicates(struct ListNode* head ) {
    // 如果链表为空或者只有一个节点,直接返回原链表
    if (head == NULL || head->next == NULL) {
       return head;
    }    
    struct ListNode *dummy = (struct ListNode*)malloc(sizeof(struct ListNode)); // 创建虚拟头节点
    dummy->next = head;
    struct ListNode *prev = dummy; // 指向当前节点的前一个节点    
    // 遍历链表,判断当前节点和下一个节点的值是否相同
    while (prev->next != NULL && prev->next->next != NULL) {
        // 如果相同,则删除所有重复元素
        if (prev->next->val == prev->next->next->val) {
            int val = prev->next->val;
            while (prev->next != NULL && prev->next->val == val) {
                prev->next = prev->next->next;//将几个重复的数字中的最后一个也删掉
            }
        } else {
            // 如果不同,则指针指向下一个节点
            prev = prev->next;
        }
    }   
    return dummy->next; // 返回删除重复元素后的链表

BM2 链表内指定区间反转 

首先,遍历链表找到m位置的节点,并记录其前驱节点pre和当前节点cur。

然后,从m位置开始,将后面的节点逐个插入到pre节点之后,直到插入到n位置为止。

最后,将m位置的节点的next指针指向n位置的节点的next指针,将n位置的节点的next指针指向m位置之后插入的节点。

struct ListNode* reverseBetween(struct ListNode* head, int m, int n) {

    if (head == NULL || head->next == NULL) {

        return head;

    }  

    struct ListNode* dummy = (struct ListNode*)malloc(sizeof(struct ListNode));

    dummy->next = head;

    struct ListNode* pre = dummy;    

    // 找到要反转的前一个结点

    for (int i = 0; i < m - 1; i++) {

        if (pre == NULL) {

            return head;

        }

        pre = pre->next;

    }    

    struct ListNode* cur = pre->next;

    struct ListNode* temp;  

    // 反转链表

    for (int i = 0; i < n - m; i++) {

        if (cur == NULL || cur->next == NULL) {

            return head;

        }

        temp = cur->next;

        cur->next = temp->next;

        temp->next = pre->next;

        pre->next = temp;

    }    

    struct ListNode* newHead = dummy->next;

    free(dummy);

    return newHead;

}

struct ListNode* reverseBetween(struct ListNode* head, int m, int n) {
    if (head == NULL || head->next == NULL || m == n) {
        return head;
    }  
    // 创建一个虚拟头节点dummy,并将其next指针指向head
    struct ListNode dummy;
    dummy.next = head;    
    // 定义pre指针和cur指针,用于记录当前节点和前驱节点
    struct ListNode* pre = &dummy;
    struct ListNode* cur = head;    
    // 找到m位置的节点及其前驱节点
    for (int i = 1; i < m; i++) {
        pre = cur;
        cur = cur->next;
    }    
    // 记录m位置的节点和前驱节点
    struct ListNode* preM = pre;
    struct ListNode* nodeM = cur;    
    // 翻转m到n位置之间的节点
    pre = cur;
    cur = cur->next;
    for (int i = m; i < n; i++) {
        struct ListNode* next = cur->next;
        cur->next = pre;
        pre = cur;
        cur = next;
    }    
    // 记录n位置的节点和后继节点
    struct ListNode* nodeN = pre;
    struct ListNode* postN = cur;    
    // 连接翻转后的链表
    preM->next = nodeN;
    nodeM->next = postN;    
    // 返回虚拟头节点dummy的next指针,即翻转后的链表
    return dummy.next;

BM10 两个链表的第一个公共结点 

struct ListNode* FindFirstCommonNode(struct ListNode* pHead1, struct ListNode* pHead2 ) {

    // write code here

    if(pHead1==NULL || pHead2==NULL)//链表有一者为空,返回结果为空,可节省特例判断时间

        return NULL;

    struct ListNode* p1=pHead1;

    struct ListNode* p2=pHead2;

    while(p1!=p2)

    {

       // if(p1==NULL && p2==NULL)//无公共节点,在遍历完成后,p1,p2均指向NULL,即也退出循环,此判断可以省去

       //     return NULL;

        p1=p1==NULL?pHead2:p1->next;

        p2=p2==NULL?pHead1:p2->next;

    }

    return p1;

}

BM23 二叉树的前序遍历 

BM25 二叉树的后序遍历 

void preOrderTraversal(struct TreeNode* node, int* ret, int* returnSize) {

    if(!node) return;

    ret[(*returnSize)++] = node->val;

    preOrderTraversal(node->left, ret, returnSize);

    preOrderTraversal(node->right, ret, returnSize);

}

int* preorderTraversal(struct TreeNode* root, int* returnSize){

    int* ret = (int*)malloc(sizeof(int) * 100);

    *returnSize = 0;

    preOrderTraversal(root, ret, returnSize);

    return ret;

}

void postOrder(struct TreeNode* node, int* ret, int* returnSize) {

    if(!node) return;

    postOrder(node->left, ret, returnSize);

    postOrder(node->right, ret, returnSize);

    ret[(*returnSize)++] = node->val;

}

int* postorderTraversal(struct TreeNode* root, int* returnSize){

    int* ret= (int*)malloc(sizeof(int) * 100);

    *returnSize = 0;

    postOrder(root, ret, returnSize);

    return ret;

字符串拷贝 

把字符串str2中最多count个字符拷贝到字符串str1中,并返回str1。如果str2中少于count个字符,那么就用'\0'来填充,直到满足count个字符为止。

char *strncpy(char *str1, const char *str2, int count);

#include <stdio.h>
char *strncpy(char *str1, const char *str2, int count) {
    int i;
    for (i = 0; str2[i] != '\0' && i < count; i++) {
        str1[i] = str2[i];
    }
    while (i < count) {
        str1[i++] = '\0';
    }
    return str1;
}
int main() {
    char str1[100];
    const char *str2 = "Hello, world!";
    int count = 15;
    strncpy(str1, str2, count);
    printf("str1: %s\n", str1);
    return 0;
}

BM26 求二叉树的层序遍历 

1.判断根节点是否为空

2.新建一个队列

3.新建一个二维数组和一个一维数组,分别存放总的元素和每层元素

4.

BM28 二叉树的最大深度

int maxDepth(struct TreeNode* root ) {

    // write code here

if(root==NULL)

    {

      return 0;  

    }

    int leftDepth=maxDepth(root->left);//根节点左子树的深度

    int rightDepth=maxDepth(root->right);//根节点右子树的深度

    return leftDepth>rightDepth?leftDepth+1:rightDepth+1;//最大深度即为左右子树深度大的那一个数加1(加上根节点)

}

BM29 二叉树中和为某一值的路径(一) 

bool hasPathSum(struct TreeNode* root, int sum ) {

    // write code here

    if(root==NULL)

    {

        return false;

    }

    if(root->left==NULL&&root->right==NULL&&sum-root->val==0)

    {

        return true;

    }

    return hasPathSum(root->left,sum-root->val)||hasPathSum(root->right,sum-root->val);//递归左右子树

}

BM7 链表中环的入口结点 

struct ListNode* EntryNodeOfLoop(struct ListNode* pHead ) {

    // write code here

    struct ListNode* fast = pHead;

    struct ListNode* slow = pHead;

    while(fast != NULL && fast->next != NULL){

        fast = fast->next->next;

        slow = slow->next;

        if (slow == fast) {

                struct ListNode* index1 = fast;

                struct ListNode* index2 = pHead;

                while (index1 != index2) {

                    index1 = index1->next;

                    index2 = index2->next;

                }

                return index2; // 返回环的入口

            }

        }

        return NULL;

}

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

void reversestring(char* str)

{

    int len = strlen(str);

    int left = 0;

    int right = len - 1;

    while (left < right)

    {

        char temp = str[left];

        str[left] = str[right];

        str[right] = temp;

        left++;

        right--;

    }

}

char firstchar(char* str)

{

    int hash[128] = { 0 };

    int len = strlen(str);

    for (int i = 0; i < len; i++)

    {

        hash[str[i]]++;

    }

    for (int i = 0; i < len; i++)

    {

        if (hash[str[i]] == 1)

        {

             return str[i];

        }

    }

    return '\0';

}

int main()

{

    char str[100];

    scanf("%s", &str);

    reversestring(str);

    printf("%s ", str);

    char first = firstchar(str);

    if (first != '\0')

    {

        printf("%c\n", first);

    }

    else

    {

        printf("failed.\n");

    }

    return 0;

链表翻转 

#include<stdio.h>

#include<stdlib.h>

struct ListNode {

    int data;          

    struct ListNode* next; 

};

struct ListNode* reverseList(struct ListNode* head)

{

    struct ListNode* pre = NULL;

    struct ListNode* cur = head;

    struct ListNode* next = NULL;

    while (cur)

    {

        next = cur->next;

        cur->next = pre;

        pre = cur;

        cur = next;

    }

    return pre;

}

struct ListNode* createList(int n)

{

    struct ListNode* head = NULL;

    struct ListNode* tmp = NULL;

    struct ListNode* p = NULL;

    int i;

    for (i = 0; i < n; i++)

    {

        tmp=(struct ListNode*)malloc(sizeof(struct ListNode));

        scanf("%d", &(tmp->data));

        tmp->next = NULL;

        if (head == NULL) {

            head = tmp;

        }

        else {

            p = head;

            while (p->next != NULL) {

                p = p->next;

            }

            p->next = tmp;

        }

    }

    return head;

}

struct ListNode* printList(struct ListNode* head)

{

    struct ListNode* p = head;

    while (p)

    {

        printf("%d", p->data);

        p = p->next;

    }

    printf("\n");

}

int main()

{

    int n;

    printf("链表结点个数为:");

    scanf("%d", &n);

    struct ListNode* head = NULL;

    head = createList(n);

    head = reverseList(head);

    printf("反转后的链表为:");

    printList(head);

    return 0;

}

BM34 判断是不是二叉搜索树

 /*

 * struct TreeNode {

 *  int val;

 *  struct TreeNode *left;

 *  struct TreeNode *right;

 * };

 *

 * C语言声明定义全局变量请加上static,防止重复定义

 */

/**

 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可

 *

 *

 * @param root TreeNode类

 * @return bool布尔型

 */

#include <limits.h>

#include <stdbool.h>

bool isValidBSTFunc(struct TreeNode* root, int left, int right) {

    if (root == NULL) {

        return true;

    }

    if (left > root->val || root->val > right) {

        return false;

    }

    return isValidBSTFunc(root->left, left, root->val)&&isValidBSTFunc(root->right, root->val, right);

}

bool isValidBST(struct TreeNode* root ) {

    // write code here

    return isValidBSTFunc(root, INT_MIN, INT_MAX);

}

BM35 判断是不是完全二叉树 

1.如果是空树,返回0

2.如果不是空树,初始化一个数组做队,用于层序遍历树(包含头和尾,并且头节点入队)

3.当队不是空的时候

。如果当前结点左空,右不空,既不是完全二叉树,返回0;

。如果当前节点左右都不是空,那么将其左右节点入队,队列头结点出队;

。如果当前结点 左不空且右空,或者,左右都空,那么只有队列中此节点之后的所有结点都没有子节点,即都是叶子结点,才是完全二叉树(如果当前结点有左节点,那么把左节点入队);

。从队中当前结点之后一个结点检查;

4.判断结点是不是叶子结点,如果是叶子结点,那么出队头结点,检查下一个结点。

 

/**

 * struct TreeNode {

 *  int val;

 *  struct TreeNode *left;

 *  struct TreeNode *right;

 * };

 *

 * C语言声明定义全局变量请加上static,防止重复定义

 */

/**

 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可

 *

 *

 * @param root TreeNode类

 * @return bool布尔型

 */

#include <stdbool.h>

bool isCompleteTree(struct TreeNode* root ) {

    // write code here  

    //如果是空树,返回0

    if(root==NULL){

        return 0;

    }

    //如果不是空树,初始化一个数组做队,用于层序遍历树

    struct TreeNode* queue[100];

    int head=0;

    int tail=0;

    queue[tail++]=root;//头结点入队

   

    //当队不是空的时候

    while(head!=tail){

        struct TreeNode* node=queue[head];

        //如果当前结点左空,右不空,既不是完全二叉树

        if(node->left==NULL && node->right!=NULL){

            return 0;

        }

        //如果当前节点左右都不是空,那么将其左右节点入队,队列头结点出队

        if(node->left!=NULL && node->right!=NULL){

            queue[tail++]=node->left;

            queue[tail++]=node->right;

            head++;

        }

        //如果当前结点 左不空且右空,或者,左右都空,那么只有队列中此节点之后的所有结点都没有子节点,

        //即都是叶子结点,才是完全二叉树

        if((node->left!=NULL && node->right==NULL)||(node->left==NULL && node->right==NULL)){

            //如果当前结点有左节点,那么把左节点入队

            if(node->left!=NULL && node->right==NULL){

                queue[tail++]=node->left;

            }

           

            head+=1;//从队中当前结点之后一个结点检查

           

            //一旦进入此if,那么必将一直执行下面的while直到返回值

            while(head!=tail){

                struct TreeNode* node=queue[head];

                //判断结点是不是叶子结点,如果是叶子结点,那么出队头结点,检查下一个结点

                if(node->left==NULL && node->right==NULL){

                    head++;

                }else{//如果不是叶子结点,返回0

                    return 0;

                }

            }

            return 1;

        }

    }

    return 1;

}

BM36 判断是不是平衡二叉树

 

/**

 * struct TreeNode {

 *  int val;

 *  struct TreeNode *left;

 *  struct TreeNode *right;

 * };

 *

 * C语言声明定义全局变量请加上static,防止重复定义

 */

/**

 *

 * @param pRoot TreeNode类

 * @return bool布尔型

 */

 //获得树的深度的函数

int getDepth(struct TreeNode* Root){

    if(Root==NULL){

        return 0;

    }

    int depth;

    int ldepth=getDepth(Root->left);

    int rdepth=getDepth(Root->right);

    depth=ldepth>rdepth?ldepth+1:rdepth+1;

    return depth;

}

bool IsBalanced_Solution(struct TreeNode* pRoot ) {

    // write code here

    //空树返回1

    if(pRoot==NULL){

        return 1;

    }

    //判断以当前结点为根的树是不是平衡树

    int leftdepth=getDepth(pRoot->left);

    int rightdepth=getDepth(pRoot->right);

    int diff=leftdepth-rightdepth;

    if(diff>1||diff<-1){

        return 0;

    }

    //递归判断每个结点

    return IsBalanced_Solution(pRoot->left) && IsBalanced_Solution(pRoot->right);

}

BM42 用两个栈实现队列 

BM47 寻找第K大

//简单做法

int compar(const void*p1,const void*p2)

{

    return ((*(int *)p1)-(*(int *)p2));

}

int findKth(int* a, int aLen, int n, int K ) {

    // write code here

    qsort(a,n,sizeof(int),compar);

    return a[n-K];

}

//快速排序

int partition(int* a, int low, int high){
    int p = a[low]; // 将数组的第一个元素作为基准值
    while(low < high){ // 当低位指针小于高位指针时循环
        while(low < high && a[high] <= p) high--; // 从高位开始向低位寻找第一个小于基准值的元素
        a[low] = a[high]; // 将找到的小于基准值的元素放到低位指针位置,此时高位指针位置为空
        while(low < high && a[low] >= p) low++; // 从低位开始向高位寻找第一个大于基准值的元素
        a[high] = a[low]; // 将找到的大于基准值的元素放到高位指针位置,此时低位指针位置为空
    }
    a[low] = p; // 将基准值放回数组中,此时基准值左边的元素都小于等于它,右边的元素都大于等于它
    return low; // 返回基准值的位置
}

int quicksort(int* a, int low, int high, int K){
    int p;
    if(low < high){ // 当低位小于高位时递归调用快速排序
        p = partition(a, low, high); // 对当前区间进行划分
        if(p == K){ // 如果基准值的位置等于K,则直接返回
            return p;
        }else if(p < K){ // 如果基准值的位置小于K,则在右子区间继续寻找第K大数
            quicksort(a, p+1, high, K);
        }else{ // 如果基准值的位置大于K,则在左子区间继续寻找第K大数
            quicksort(a, low, p-1, K);
        }
    }
    return p; // 返回基准值的位置
}

int findKth(int* a, int aLen, int n, int K ) {
    quicksort(a, 0, aLen-1, K-1); // 对数组进行快速排序,寻找第K大数
    return a[K-1]; // 返回第K大数
}

BM48 数据流中的中位数 

static int array[1000];

static int arr_top=0;//计算的是数据个数

void Insert(int num ) {

    //每次插入 进行插入排序 插入到合适的位置

    //保证插入的顺序是有序的

    int i=0;

    //第一个元素直接插入

    if(arr_top==0){

        array[arr_top]=num;

    }

    else{

        i=arr_top-1;

        while(num<array[i]&&i>=0){

            array[i+1]=array[i];

            i--;

            }

        array[i+1]=num;

    }

    arr_top++;

}

double GetMedian() {

    // write code here

    double ans=0;

    if(arr_top%2)

        ans=array[arr_top/2];

    else

        ans=((double)array[arr_top/2]+(double)array[arr_top/2-1])/2;

    return ans;

}

BM4 合并两个排序的链表

 /**

 * struct ListNode {

 *  int val;

 *  struct ListNode *next;

 * };

 */

/**

 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可

 *

 *

 * @param pHead1 ListNode类

 * @param pHead2 ListNode类

 * @return ListNode类

 */

struct ListNode* Merge(struct ListNode* pHead1, struct ListNode* pHead2 )

{

    struct ListNode* vhead = (struct ListNode*)malloc(sizeof(struct ListNode)); //新建一个头结点

    vhead->val = -1;

    struct ListNode *p = vhead;   //用一个指针指向该头结点

        while (pHead1 && pHead2)    //两个链表都未比较完

       {

            if (pHead1->val <= pHead2->val) //表1的值更小

           {

                p->next = pHead1;    //先将结点连接到新表,再让原表指针后移一位,二者顺序不可换

                pHead1 = pHead1->next;

            }

            else {

                p->next = pHead2;

                pHead2 = pHead2->next;

            }

            p = p->next;  //加入一个新结点后,新表指针也后移一位

        }

        p->next = pHead1 ? pHead1 : pHead2;  //都比较完后,哪个表非空则直接加入到新表中

        return vhead->next;  //返回第一个结点

    }

笔试题1. LED灯控制

1. 先设置灯珠的状态,然后将灯珠的ID和状态封装到结构体中

2. 设置LED灯珠的最大容量,并根据灯珠的操作判断灯珠的状态是OFF、ON、还是BLINKING

3. 编写比较函数,如果灯珠状态不相同按OFF-ON-BLINKING的顺序输出灯珠态,否则,按照ID排序

4. 设置LED灯珠的数量N和操作次数M,初始化LED灯珠,id初始化为i+1,状态初始化为OFF,按照操作次数执行cntrolLED()函数

5. 排序,输出id结果

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

// 定义LED灯珠的状态
typedef enum {
    OFF,          // 灭
    ON,           // 亮
    BLINKING      // 闪烁
} LEDState;
// LED灯珠结构体
typedef struct {
    int id;        // 灯珠的唯一标识
    LEDState state;  // 灯珠的状态
} LEDBead;
// 定义LED灯珠的最大数量
#define MAX_LED_COUNT 1000
// 执行LED灯珠操作
void controlLED(LEDBead leds[], int n, const char* action, int i) {
    if (i < 1 || i > n) {
        return;  // 如果指定的LED灯珠索引超出范围,不执行任何操作,直接返回
    }
    if (strcmp(action, "TURN_OFF") == 0) {
        leds[i - 1].state = OFF;  // 将指定的LED灯珠状态设置为"灭"
    }
    else if (strcmp(action, "TURN_ON") == 0) {
        leds[i - 1].state = ON;  // 将指定的LED灯珠状态设置为"亮"
    }
    else if (strcmp(action, "TURN_BLINK") == 0) {
        leds[i - 1].state = BLINKING;  // 将指定的LED灯珠状态设置为"闪烁"
    }
}
// 比较函数,用于排序LED灯珠
int compare(const void* a, const void* b) {
    LEDBead* beadA = (LEDBead*)a;
    LEDBead* beadB = (LEDBead*)b;
    if (beadA->state != beadB->state) {
        return beadA->state - beadB->state;  // 首先按状态排序(灭 < 亮 < 闪烁)
    }
    else {
        return beadA->id - beadB->id;  // 如果状态相同,按照ID排序
    }
}
int main() {
    int N, M;
    scanf("%d %d", &N, &M);  // 读取LED灯珠数量(N)和操作次数(M)
    LEDBead leds[MAX_LED_COUNT];  // 创建数组以存储LED灯珠
    // 初始化LED灯珠
    for (int i = 0; i < N; i++) {
        leds[i].id = i + 1;  // 设置LED灯珠的ID
        leds[i].state = OFF;  // 初始化LED灯珠的状态为"灭"
    }
    // 执行操作
    for (int i = 0; i < M; i++) {
        char action[20];
        int id;
        scanf("%s %d", action, &id);  // 读取LED操作(action)和LED灯珠的ID
        controlLED(leds, N, action, id);  // 对指定的LED执行指定的操作
    }
    // 排序LED灯珠
    qsort(leds, N, sizeof(LEDBead), compare);
    // 输出结果
    for (int i = 0; i < N; i++) {
        printf("%d ", leds[i].id);  // 按照排序顺序输出LED灯珠的ID
    }
    return 0;
}

笔试题2. 最大优美序列

#include <stdio.h>

int main() {
    int n;
    scanf("%d", &n); // 读取排列的长度

    int arr[100000]; // 假设排列的长度不会超过 100000
    int left = 1;    // 左边的数从1开始
    int right = n;   // 右边的数从 n 开始

    for (int i = 1; i <= n; i++) {
        if (i % 2 == 1) {
            arr[i] = right; // 如果 i 为奇数,则填充右边的数
            right--;
        } else {
            arr[i] = left; // 如果 i 为偶数,则填充左边的数
            left++;
        }
    }

    // 输出优美排列
    for (int i = 1; i <= n; i++) {
        printf("%d", arr[i]);
        if (i < n) {
            printf(" "); // 输出空格分隔,除了最后一个数字
        }
    }

    return 0;
}

笔试题3. 小红走字符串

笔试题4. 回文串 

笔试题5. 完美偶数

小红定义一个正整数  为完美偶数满足以下两个条件:1.x 是偶数2.x不小于l,不大于r,小红拿到了一个长度为n的数组a。她想知道这个数组内有多少个完美偶数?
输入描述
第一行输入三个正整数n,l,r,用空格隔开,第二行输入n个正整数ai,代表小红拿到的数组。1≤n,ai<=100,1<=I<=r <=100.   
输出描述:
该数组中完美偶数的数量。        
输入:
5 3 8
1 2 6 8 7
输出:
2

#include <stdio.h>
int isPerfectEven(int x, int l, int r) {
    return (x % 2 == 0 && x >= l && x <= r);
}
int countPerfectEvens(int* arr, int n, int l, int r) {
    int count = 0;
    for (int i = 0; i < n; i++) {
        if (isPerfectEven(arr[i], l, r)) {
            count++;
        }
    }
    return count;
}
int main() {
    int n, l, r;
    scanf("%d %d %d", &n, &l, &r);
    int arr[100]; // 假设数组长度不超过100
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
    int result = countPerfectEvens(arr, n, l, r);
    printf("%d\n", result);
    return 0;

笔试题6.  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值