【Leecode 随笔】C语言版看了不后悔系列持续更新中。。。

news2024/11/6 3:12:36

在这里插入图片描述

文章目录

    • 题目一:最长回文子串
      • 题目描述:
      • 示例输入与输出:
      • 题目分析:
      • 解题思路:
      • 示例代码:
      • 深入剖析:
    • 题目二:合并K个有序链表
      • 题目描述:
      • 示例输入与输出:
      • 题目分析:
      • 解题思路:
      • 示例代码:
      • 深入剖析:
    • 题目三:全排列
      • 题目描述:
      • 示例输入与输出:
      • 题目分析:
      • 解题思路:
      • 示例代码:
      • 深入剖析:

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

题目一:最长回文子串

题目描述:

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例输入与输出:

输入:s = “babad”
输出:“bab” 或 “aba”
输入:s = “cbbd”
输出:“bb”

题目分析:

回文串是指正读和反读都相同的字符串。解决这个问题的关键在于如何高效地找到最长的回文子串。暴力解法的时间复杂度为O(n^3),显然不可取。我们可以考虑使用动态规划或中心扩展法来优化。

解题思路:

动态规划:定义一个二维数组dp,其中dp[i][j]表示字符串s从索引i到j的子串是否为回文。通过填充这个数组,我们可以找到最长的回文子串。
中心扩展法:遍历字符串中的每个字符和每对相邻字符作为回文中心,然后向外扩展以找到最长的回文子串。
这里我们选择中心扩展法,因为它的实现更简洁且时间复杂度为O(n^2),适合本题的要求。

示例代码:

#include <stdio.h>  
#include <string.h>  
#include <stdlib.h>  
  
char* longestPalindrome(char* s) {  
    int len = strlen(s);  
    if (len < 2) return s;  
  
    int start = 0, maxLen = 1;  
  
    for (int i = 0; i < len; i++) {  
        int len1 = expandAroundCenter(s, i, i); // 奇数长度回文中心  
        int len2 = expandAroundCenter(s, i, i + 1); // 偶数长度回文中心  
        int len = len1 > len2 ? len1 : len2;  
  
        if (len > maxLen) {  
            start = i - (len - 1) / 2;  
            maxLen = len;  
        }  
    }  
  
    char* result = (char*)malloc((maxLen + 1) * sizeof(char));  
    strncpy(result, s + start, maxLen);  
    result[maxLen] = '\0';  
  
    return result;  
}  
  
int expandAroundCenter(char* s, int left, int right) {  
    while (left >= 0 && right < strlen(s) && s[left] == s[right]) {  
        left--;  
        right++;  
    }  
    return right - left - 1;  
}  
  
int main() {  
    char s1[] = "babad";  
    char* result1 = longestPalindrome(s1);  
    printf("Longest palindrome in \"%s\" is \"%s\"\n", s1, result1);  
    free(result1);  
  
    char s2[] = "cbbd";  
    char* result2 = longestPalindrome(s2);  
    printf("Longest palindrome in \"%s\" is \"%s\"\n", s2, result2);  
    free(result2);  
  
    return 0;  
}

深入剖析:

中心扩展法的核心思想是以每个字符或每对相邻字符为中心,向外扩展以找到最长的回文子串。这种方法避免了不必要的比较,从而提高了效率。

题目二:合并K个有序链表

题目描述:

给定一个链表数组,每个链表都已经按升序排列。合并所有链表,并返回合并后的有序链表。

示例输入与输出:

输入:[[1,4,5],[1,3,4],[2,6]]
输出:1 -> 1 -> 2 -> 3 -> 4 -> 4 -> 5 -> 6
输入:[]
输出:[]

题目分析:

这个问题可以通过逐个合并链表来解决,但效率较低。更优的方法是使用最小堆(优先队列)来维护当前所有链表中的最小元素,从而依次取出最小元素构建合并后的链表。

解题思路:

创建一个最小堆,并将所有链表的头节点加入堆中。
重复以下步骤,直到堆为空:
从堆中取出最小元素作为当前节点。
如果当前节点的下一个节点存在,则将其加入堆中。
将当前节点添加到合并后的链表中。

示例代码:

#include <stdio.h>  
#include <stdlib.h>  
  
typedef struct ListNode {  
    int val;  
    struct ListNode* next;  
} ListNode;  
  
// 最小堆节点结构定义  
typedef struct MinHeapNode {  
    ListNode* node;  
    struct MinHeapNode* left;  
    struct MinHeapNode* right;  
    struct MinHeapNode* parent;  
} MinHeapNode;  
  
// 最小堆结构定义  
typedef struct MinHeap {  
    MinHeapNode** array;  
    int size;  
    int capacity;  
} MinHeap;  
  
// 辅助函数:比较两个节点值的大小  
int compare(ListNode* a, ListNode* b) {  
    return (a->val > b->val) - (a->val < b->val);  
}  
  
// 创建最小堆  
MinHeap* createMinHeap(int size) {  
    MinHeap* minHeap = (MinHeap*)malloc(sizeof(MinHeap));  
    minHeap->capacity = size;  
    minHeap->size = 0;  
    minHeap->array = (MinHeapNode**)malloc(size * sizeof(MinHeapNode*));  
    return minHeap;  
}  
  
// 释放最小堆内存  
void freeMinHeap(MinHeap* minHeap) {  
    for (int i = 0; i < minHeap->size; i++) {  
        free(minHeap->array[i]);  
    }  
    free(minHeap->array);  
    free(minHeap);  
}  
  
// 插入节点到最小堆  
void insertMinHeap(MinHeap* minHeap, ListNode* node) {  
    if (minHeap->size == minHeap->capacity) {  
        printf("Heap is full, cannot insert new node.\n");  
        return;  
    }  
  
    MinHeapNode* newNode = (MinHeapNode*)malloc(sizeof(MinHeapNode));  
    newNode->node = node;  
    newNode->left = NULL;  
    newNode->right = NULL;  
    newNode->parent = NULL;  
  
    int i = minHeap->size;  
    minHeap->array[i] = newNode;  
    minHeap->size++;  
  
    // 上浮调整  
    while (i && compare(minHeap->array[(i - 1) / 2]->node, node) > 0) {  
        MinHeapNode* temp = minHeap->array[i];  
        minHeap->array[i] = minHeap->array[(i - 1) / 2];  
        minHeap->array[(i - 1) / 2] = temp;  
  
        if (minHeap->array[i]->left) {  
            minHeap->array[i]->left->parent = minHeap->array[(i - 1) / 2];  
        }  
        if (minHeap->array[i]->right) {  
            minHeap->array[i]->right->parent = minHeap->array[(i - 1) / 2];  
        }  
        minHeap->array[(i - 1) / 2]->parent = minHeap->array[i];  
  
        i = (i - 1) / 2;  
    }  
}  
  
// 提取最小节点  
ListNode* extractMin(MinHeap* minHeap) {  
    if (minHeap->size == 0) {  
        printf("Heap is empty, cannot extract minimum node.\n");  
        return NULL;  
    }  
  
    ListNode* minNode = minHeap->array[0]->node;  
    MinHeapNode* lastNode = minHeap->array[minHeap->size - 1];  
    minHeap->array[0] = lastNode;  
    minHeap->size--;  
  
    // 下沉调整  
    int i = 0;  
    while (2 * i + 1 < minHeap->size) {  
        int leftChild = 2 * i + 1;  
        int rightChild = 2 * i + 2;  
        int smallest = i;  
  
        if (compare(minHeap->array[leftChild]->node, minHeap->array[smallest]->node) < 0) {  
            smallest = leftChild;  
        }  
        if (rightChild < minHeap->size && compare(minHeap->array[rightChild]->node, minHeap->array[smallest]->node) < 0) {  
            smallest = rightChild;  
        }  
  
        if (smallest != i) {  
            MinHeapNode* temp = minHeap->array[i];  
            minHeap->array[i] = minHeap->array[smallest];  
            minHeap->array[smallest] = temp;  
  
            if (minHeap->array[i]->left) {  
                minHeap->array[i]->left->parent = minHeap->array[i];  
            }  
            if (minHeap->array[i]->right) {  
                minHeap->array[i]->right->parent = minHeap->array[i];  
            }  
            if (minHeap->array[smallest]->left) {  
                minHeap->array[smallest]->left->parent = minHeap->array[smallest];  
            }  
            if (minHeap->array[smallest]->right) {  
                minHeap->array[smallest]->right->parent = minHeap->array[smallest];  
            }  
            i = smallest;  
        } else {  
            break;  
        }  
    }  
  
    free(lastNode);  
    return minNode;  
}  
  
// 检查堆是否为空  
int isEmpty(MinHeap* minHeap) {  
    return minHeap->size == 0;  
}  
  
// 获取堆的大小  
int getSize(MinHeap* minHeap) {  
    return minHeap->size;  
}  
  
// 辅助函数:创建新链表节点  
ListNode* createNode(int val) {  
    ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));  
    newNode->val = val;  
    newNode->next = NULL;  
    return newNode;  
}  
  
// 辅助函数:打印链表  
void printList(ListNode* head) {  
    ListNode* current = head;  
    while (current != NULL) {  
        printf("%d -> ", current->val);  
        current = current->next;  
    }  
    printf("NULL\n");  
}  
  
// 主函数:合并K个有序链表  
ListNode* mergeKLists(ListNode** lists, int listsSize) {  
    if (listsSize == 0) return NULL;  
  
    MinHeap* minHeap = createMinHeap(listsSize);  
    for (int i = 0; i < listsSize; i++) {  
        if (lists[i] != NULL) {  
            insertMinHeap(minHeap, lists[i]);  
        }  
    }  
  
    ListNode dummy = {0, NULL};  
    ListNode* tail = &dummy;  
    while (!isEmpty(minHeap)) {  
        ListNode* minNode = extractMin(minHeap);  
        tail->next = minNode;  
        tail = tail->next;  
        if (minNode->next != NULL) {  
            insertMinHeap(minHeap, minNode->next);  
        }  
    }  
  
    freeMinHeap(minHeap);  
    return dummy.next;  
}  
  
int main() {  
    ListNode* l1 = createNode(1);  
    l1->next = createNode(4);  
    l1->next->next = createNode(5);  
  
    ListNode* l2 = createNode(1);  
    l2->next = createNode(3);  
    l2->next->next = createNode(4);  
  
    ListNode* l3 = createNode(2);  
    l3->next = createNode(6);  
  
    ListNode* lists[] = {l1, l2, l3};  
    int listsSize = 3;  
  
    ListNode* mergedList = mergeKLists(lists, listsSize);  
    printList(mergedList);  
  
    return 0;  
}

深入剖析:

使用最小堆可以有效地合并K个有序链表,因为堆能够始终提供当前所有链表中的最小元素。这种方法的时间复杂度为O(N log K),其中N是所有链表中节点的总数,K是链表的数量。

题目三:全排列

题目描述:

给定一个没有重复数字的序列,返回其所有可能的全排列。

示例输入与输出:

输入:[1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
输入:[0,1]
输出:[[0,1],[1,0]]

题目分析:

全排列问题是一个经典的回溯算法问题。回溯算法通过递归和剪枝来搜索所有可能的解。

解题思路:

定义一个递归函数,该函数接收当前排列和剩余可选数字作为参数。
在每次递归调用中,选择一个数字加入当前排列,并从剩余可选数字中移除该数字。
当剩余可选数字为空时,将当前排列加入结果集中。
递归调用该函数,直到所有可能的排列都被找到。

示例代码:

#include <stdio.h>  
#include <stdlib.h>  
  
// 动态数组结构定义  
typedef struct {  
    int* data;  
    int size;  
    int capacity;  
} IntArray;  
  
// 辅助函数:创建动态数组  
IntArray* createIntArray(int capacity) {  
    IntArray* array = (IntArray*)malloc(sizeof(IntArray));  
    array->data = (int*)malloc(capacity * sizeof(int));  
    array->size = 0;  
    array->capacity = capacity;  
    return array;  
}  
  
// 辅助函数:向动态数组添加元素  
void append(IntArray* array, int val) {  
    if (array->size >= array->capacity) {  
        array->capacity *= 2;  
        array->data = (int*)realloc(array->data, array->capacity * sizeof(int));  
    }  
    array->data[array->size++] = val;  
}  
  
// 辅助函数:释放动态数组内存  
void freeIntArray(IntArray* array) {  
    free(array->data);  
    free(array);  
}  
  
// 主函数:生成全排列  
int** permute(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) {  
    *returnSize = 0;  
    IntArray* numsArray = createIntArray(numsSize);  
    for (int i = 0; i < numsSize; i++) {  
        append(numsArray, nums[i]);  
    }  
  
    IntArray* path = createIntArray(numsSize);  
    IntArray* used = createIntArray(numsSize);  
    for (int i = 0; i < numsSize; i++) {  
        used->data[i] = 0;  
    }  
  
    int* returnColumnSizesArray = (int*)malloc(numsSize * sizeof(int));  
    int** result = (int**)malloc(numsSize * numsSize * sizeof(int*));  
  
    // 回溯函数  
    void permuteHelper(IntArray* nums, IntArray* path, IntArray* used, IntArray** result, int* returnSize) {  
        if (path->size == nums->size) {  
            IntArray* temp = createIntArray(path->size);  
            for (int i = 0; i < path->size; i++) {  
                append(temp, path->data[i]);  
            }  
            result[*returnSize] = temp->data;  
            (*returnSize)++;  
            freeIntArray(temp);  
            return;  
        }  
  
        for (int i = 0; i < nums->size; i++) {  
            if (used->data[i]) continue;  
            used->data[i] = 1;  
            append(path, nums->data[i]);  
            permuteHelper(nums, path, used, result, returnSize);  
            used->data[i] = 0;  
            path->size--;  
        }  
    }  
  
    permuteHelper(numsArray, path, used, result, returnSize);  
  
    for (int i = 0; i < *returnSize; i++) {  
        returnColumnSizesArray[i] = path->size;  
    }  
  
    *returnColumnSizes = returnColumnSizesArray;  
    freeIntArray(numsArray);  
    freeIntArray(path);  
    freeIntArray(used);  
    
    return result;  
}  
  
// 辅助函数:打印二维数组  
void printPermutations(int** permutations, int permutationsSize, int* returnColumnSizes) {  
    for (int i = 0; i < permutationsSize; i++) {  
        for (int j = 0; j < returnColumnSizes[i]; j++) {  
            printf("%d ", permutations[i][j]);  
        }  
        printf("\n");  
    }  
}  
  
int main() {  
    int nums1[] = {1, 2, 3};  
    int numsSize1 = sizeof(nums1) / sizeof(nums1[0]);  
    int* returnColumnSizes1;  
    int returnSize1;  
    int** permutations1 = permute(nums1, numsSize1, &returnSize1, &returnColumnSizes1);  
    printPermutations(permutations1, returnSize1, returnColumnSizes1);  
    int nums2[] = {0, 1};  
    int numsSize2 = sizeof(nums2) / sizeof(nums2[0]);  
    int* returnColumnSizes2;  
    int returnSize2;  
    int** permutations2 = permute(nums2, numsSize2, &returnSize2, &returnColumnSizes2);  
    printPermutations(permutations2, returnSize2, returnColumnSizes2);  
    
    return 0;  
}

深入剖析:

回溯算法通过递归和剪枝来搜索所有可能的解空间。在全排列问题中,我们使用三个动态数组来分别存储原始数字、当前排列和已使用数字的状态。通过递归地选择数字并更新状态,我们可以找到所有可能的全排列。


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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2180018.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GaussDB关键技术原理:高弹性(六)

书接上文GaussDB关键技术原理&#xff1a;高弹性&#xff08;五&#xff09;从日志多流和事务相关方面对hashbucket扩容技术进行了解读&#xff0c;本篇将从扩容实践方面继续介绍GaussDB高弹性技术。 5 扩容实践 5.1 工具介绍 5.1.1 TPC-C TPC-C(全称Transaction Proces…

【使用resnet18训练自己的数据集】

1.背景及准备 书接上文【以图搜图代码实现】–犬类以图搜图示例 总结了一下可以优化的点&#xff0c;其中提到使用自己的数据集训练网络&#xff0c;而不是单纯使用预训练的模型&#xff0c;这不就来了&#xff01;&#xff01; 使用11类犬类微调resnet18网络模型&#xff1a…

如何实现一个优秀的散列表!

文章内容收录到个人网站&#xff0c;方便阅读&#xff1a;http://hardyfish.top/ 文章内容收录到个人网站&#xff0c;方便阅读&#xff1a;http://hardyfish.top/ 文章内容收录到个人网站&#xff0c;方便阅读&#xff1a;http://hardyfish.top/ 前言 假设现在有一篇很长的…

python-pptx 中 placeholder 和 shape 有什么区别?

在 python-pptx 库中&#xff0c;placeholder 和 shape 是两个核心概念。虽然它们看起来相似&#xff0c;但在功能和作用上存在显著的区别。为了更好地理解这两个概念&#xff0c;我们可以通过它们的定义、使用场景以及实际代码示例来剖析其差异。 Python-pptx 的官网链接&…

08_OpenCV文字图片绘制

import cv2 import numpy as npimg cv2.imread(image0.jpg,1) font cv2.FONT_HERSHEY_SIMPLEXcv2.rectangle(img,(500,400),(200,100),(0,255,0),20) # 1 dst 2 文字内容 3 坐标 4 5 字体大小 6 color 7 粗细 8 line type cv2.putText(img,flower,(200,50),font,1,(0,0,250)…

Kubernetes从零到精通(17-扩展-Operator模式)

目录 一、简介 二、核心概念 三、工作原理 四、Operator Framework SDK示例 1.准备工作 2. 定义MySQLCluster CRD 3. 自定义资源实例 4. 编写控制器逻辑 5. 部署Operator 6. 验证 一、简介 Kubernetes中的Operator模式是一种用于简化和自动化管理复杂应用程序(尤其是…

【最新华为OD机试E卷-支持在线评测】简单的自动曝光(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 💻 ACM金牌🏅️团队 | 大厂实习经历 | 多年算法竞赛经历 ✨ 本系列打算持续跟新华为OD-E/D卷的多语言AC题解 🧩 大部分包含 Python / C / Javascript / Java / Cpp 多语言代码 👏 感谢大家的订阅➕ 和 喜欢�…

数字电路与逻辑设计-移位寄存器逻辑功能测试和应用

一、实验目的 l&#xff0e;验证移位寄存器的逻辑功能&#xff1b; 2&#xff0e;掌握集成电路4位双向移位寄存器的使用方法&#xff1b; 3&#xff0e;学会应用移位寄存器实现数据的串行、并行转换和构成环形计数器。 二、实验原理 l&#xff0e;移位寄存器的特点 寄存器…

深入掌握 Protobuf 与 RPC 的高效结合:实现C++工程中的高效通信

目录 一、Protobuf与RPC框架的通信流程概述二、Protobuf与RPC在C中的实际应用2.1 定义 .proto 文件2.2 编译 .proto 文件生成C代码2.3 实现服务器端逻辑2.4 实现客户端逻辑2.5 使用CMake构建工程2.6 编译与运行2.7 关键组件解析2.8 序列化与反序列化的实现 三、关键实现与解析四…

想不到!手机壁纸变现项目,有人 3 个月怒赚 180000+(附教程)

同学们&#xff01;今天无意间发现了一个超级有潜力的变现数据账号。这个账号专注于制作 3D 立体膨胀壁纸&#xff0c;我实在是忍不住要和大家分享。 这个账号的笔记内容非常简洁&#xff0c;主要就是展示壁纸作品。然而&#xff0c;就是这样简单的内容&#xff0c;却在短短 8…

介绍我经常使用的两款轻便易用的 JSON 工具

第一款是 Chrome Extension&#xff0c;名叫 JSON Viewer Pro&#xff0c;可以在 Chrome 应用商店下载&#xff1a; 点击右上角的 JSON Input&#xff0c;然后可以直接把 JSON 字符串内容粘贴进去&#xff0c;也直接直接加载本地 JSON 文件。 可以在树形显示和图形显示两种模式…

淘宝自动下单退货RPA自动化脚本(已运行两个月)

使用AdsPower Browser写的两个自动化脚本&#xff0c;一个下单一个退货&#xff0c;我也不知道他为什么要做这个自动化脚本&#xff0c;运行2个月时间&#xff0c;还蛮稳定&#xff0c;可以多窗口并发运行! 下单指定淘宝商品连接&#xff0c;执行下单RPA脚本实现自动操作。 退…

模糊测试SFuzz亮相第32届中国国际信息通信展览会

9月25日&#xff0c;被誉为“中国ICT市场的创新基地和风向标”的第32届中国国际信息通信展在北京盛大开幕&#xff0c;本次展会将在为期三天的时间内&#xff0c;为信息通信领域创新成果、尖端技术和产品提供国家级交流平台。开源网安携模糊测试产品及相关解决方案精彩亮相&…

Flux最新ControlNet 高清修复模型测评,效果好速度快!

上一篇介绍了Jasper AI 发布了三个模型中的法线贴图&#xff0c;没看过的可以看一下哈&#xff1a; Flux目前最快ControlNet模型现身&#xff01;法线贴图详细测评 (chinaz.com) 这次再介绍一下另一个模型&#xff1a;升频器&#xff0c;可以有比较好的模糊修复效果&#xff…

一条命令Docker安装常用桌面linux系统含一些系统和应用

分类 一. opens use 15.5 desktop https://hub.docker.com/r/kasmweb/opensuse-15-desktop 这是我最近用的一个,稳定性和性能好过ubuntu,兼容性稍微差,部分依赖无法安装,部分软件运行不起来,界面比ubuntu的要好看.风格是win10的.提供一个开源的webVNC, 可选,但是桌面必定要用…

AIGC专栏16——CogVideoX-Fun V1.1版本详解 支持图文生视频与更大的动态性 为文生视频添加控制

AIGC专栏16——CogVideoX-Fun V1.1版本详解 支持图&文生视频与更大的动态性 为文生视频添加控制 学习前言相关地址汇总源码下载地址HF测试链接 CogVideoX-Fun V1.1详解技术储备Diffusion Transformer (DiT)Stable Diffusion 3EasyAnimate-I2V 算法细节V1.1特点参考图片添加…

20.1 分析pull模型在k8s中的应用,对比push模型

本节重点介绍 : push模型和pull模型监控系统对比为什么在k8s中只能用pull模型的k8s中主要组件的暴露地址说明 push模型和pull模型监控系统 对比下两种系统采用的不同采集模型&#xff0c;即push型采集和pull型采集。不同的模型在性能的考虑上是截然不同的。下面表格简单的说…

二、Spring Boot集成Spring Security之实现原理

Spring Boot集成Spring Security之实现原理 一、Spring Security实现原理概要介绍二、使用WebSecurityConfiguration向Spring容器中注册FilterChainProxy类型的对象springSecurityFilterChain1、未配置securityFilterChain过滤器链时使用默认配置用于生成默认securityFilterCha…

Java SE 总结

Java SE&#xff08;Standard Edition&#xff09;是Java编程语言的标准版本&#xff0c;提供了基础的编程环境和API&#xff0c;适用于开发和运行Java应用程序。下面是Java SE的几个重要方面的知识回顾与总结。 1. Java环境基础 具体可参考这里对三者的介绍 传送门 1.1 JVM…

后端-对表格数据进行添加、删除和修改

一、添加 要求&#xff1a; 按下添加按钮出现一个板块输入添加的数据信息&#xff0c;点击板块的添加按钮&#xff0c;添加&#xff1b;点击取消&#xff0c;板块消失。 实现&#xff1a; 1.首先&#xff0c;设计页面输入框格式&#xff0c;表格首行 2.从数据库里调数据 3.添加…