练习题 11-15(这三道题,还是没想出来)

剑指 Offer 20. 表示数值的字符串

十一、

请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。

数值(按顺序)可以分成以下几个部分:

  1. 若干空格
  2. 一个 小数 或者 整数
  3. (可选)一个 'e' 或 'E' ,后面跟着一个 整数
  4. 若干空格

小数(按顺序)可以分成以下几个部分:

  1. (可选)一个符号字符('+' 或 '-'
  2. 下述格式之一:
    1. 至少一位数字,后面跟着一个点 '.'
    2. 至少一位数字,后面跟着一个点 '.' ,后面再跟着至少一位数字
    3. 一个点 '.' ,后面跟着至少一位数字

整数(按顺序)可以分成以下几个部分:

  1. (可选)一个符号字符('+' 或 '-'
  2. 至少一位数字

部分数值列举如下:

  • ["+100", "5e2", "-123", "3.1416", "-1E-16", "0123"]

部分非数值列举如下:

  • ["12e", "1a3.14", "1.2.3", "+-5", "12e+5.4"]

bool isNumber(char* s)
{
    int flag = 0;
    if (s == NULL) // 使用双等号来判断是否为NULL
    {
        return false;
    }
    while (*s == ' ') // 去除开头的空格
    {
        s++;
    }
    if (*s == '+' || *s == '-') // 判断正负号
    {
        s++;
        while (*s != '\0' && *s >= '0' && *s <= '9') // 修改条件判断的顺序,先判断是否为数字
        {
            s++;
            flag = 1;
        }
    }
    while (*s != '\0' && *s >= '0' && *s <= '9') // 判断整数部分
    {
        s++;
        flag = 1;
    }
    if (*s == '.') // 判断小数点
    {
        s++;
        while (*s != '\0' && *s >= '0' && *s <= '9') // 判断小数部分
        {
            s++;
            flag = 1;
        }
        if (flag == 0)
        {
            return false;
        }
    }
    if (flag == 0)
    {
        return false;
    }
    flag = 0;
    if (*s == 'e' || *s == 'E') // 判断科学计数法
    {
        s++;
        if (*s == '+' || *s == '-') // 判断指数部分的正负号
        {
            s++;
        }
        while (*s != '\0' && *s >= '0' && *s <= '9') // 判断指数部分的数字
        {
            s++;
            flag = 1;
        }
        if (flag == 0)
        {
            return false;
        }
    }
    while (*s == ' ') // 去除结尾的空格
    {
        s++;
    }
    return *s == '\0'; // 判断是否遍历到字符串的结尾
}

十二、

剑指 Offer 24. 反转链表

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* reverseList(struct ListNode* head){
    struct ListNode* prev = NULL;
    struct ListNode* current = head;
    struct ListNode* temp = NULL;

    while (current != NULL) {
        temp = current->next;
        current->next = prev;
        prev = current;
        current = temp;
    }

    return prev;
}

十三、

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。

示例 1:

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]

示例 2:

输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]
int* spiralOrder(int** matrix, int matrixSize, int* matrixColSize, int* returnSize){
    if (matrixSize == 0 || *matrixColSize == 0)
    {
        *returnSize = 0;
        return NULL;
    }
    int row = matrixSize;
    int col = *matrixColSize;
    int size = row*col;
    *returnSize = size;
    int* arr = (int*)malloc(sizeof(int) * size);
    int cnt = 0;//已经遍历的元素个数
    int left = 0, right = col - 1, up = 0, down = row - 1;//左右上下边界
    int i = 0;
    while (1)                           //cnt < size
    {
        for (i = left; cnt < size && i <= right; i++)
        {
            arr[cnt++] =  matrix[up][i];//打印上边界元素
        }
        //up++;
        if (++up > down)
            break;
        for (i = up; cnt < size && i <= down; i++)
        {
            arr[cnt++] = matrix[i][right];//打印右边界元素
        }
        //right--;
        if (--right < left)
            break;
        for (i = right; cnt < size && i >= left; i--)
        {
            arr[cnt++] = matrix[down][i];//打印下边界元素
        }
        //down--;
        if (--down < up)
            break;
        for (i = down; cnt < size && i >= up; i--)
        {
            arr[cnt++] = matrix[i][left];//打印左边界元素
        }
        //left++;
        if (++left > right)
            break;
    }
    return arr;
}

十四、宝石与石头

给你一个字符串 jewels 代表石头中宝石的类型,另有一个字符串 stones 代表你拥有的石头。 stones 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石。

字母区分大小写,因此 "a" 和 "A" 是不同类型的石头。

示例 1:

输入:jewels = "aA", stones = "aAAbbbb"
输出:3

示例 2:

输入:jewels = "z", stones = "ZZ"
输出:0

 解法1:

int numJewelsInStones(char * jewels, char * stones){
   int count=0;
   int jLen=strlen(jewels);
   int sLen=strlen(stones);
   for(int i=0;i

解法2:哈希算法(不会)

int numJewelsInStones(char* J, char* S)
{
    char hash[52]; // 创建一个大小为 52 的字符数组,用于存储 J 中的字符
    int ret = 0; // 初始化计数器为 0

    // 遍历字符串 J,将 J 中的字符存储到 hash 数组中
    for (int i = 0; i < 50; i++)
    {
        if (J[i] == '\0')
        {
            break; // 当遍历到 J 的结尾时,跳出循环
        }
        hash[J[i] - 'A'] = J[i]; // 将 J 中的字符存储到对应的 hash 数组位置上
    }

    // 遍历字符串 S,统计出现在 J 中的字符的数量
    for (int i = 0; i < 50; i++)
    {
        if (S[i] == '\0')
        {
            break; // 当遍历到 S 的结尾时,跳出循环
        }
        if (hash[S[i] - 'A'] == S[i]) // 如果 S 中的字符在 hash 数组中存在,即为 J 中的字符
        {
            ret++; // 计数器加一
        }
    }

    return ret; // 返回统计的数量
}

十五、合并两个有序数组

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。

请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

示例 1:

输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:需要合并 [1,2,3] 和 [2,5,6] 。
合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。

示例 2:

输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]
解释:需要合并 [1] 和 [] 。
合并结果是 [1] 。

 解法1:

#include 
#include 

int cmp(const void* a, const void* b) {
    return *(int*)a - *(int*)b;
}

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
    for (int i = 0; i != n; ++i) {
        nums1[m + i] = nums2[i];
    }
    qsort(nums1, nums1Size, sizeof(int), cmp);
}

int main() {
    int nums1[10] = {1, 2, 3, 0, 0, 0};
    int m = 3;
    int nums2[3] = {2, 5, 6};
    int n = 3;

    merge(nums1, 10, m, nums2, n);

    printf("Merged Array: ");
    for (int i = 0; i < m + n; i++) {
        printf("%d ", nums1[i]);
    }
    printf("\n");

    return 0;
}

 解法2:

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
int p1 = m - 1, p2 = n - 1;
int tail = m + n - 1;
int cur;
while (p1 >= 0 || p2 >= 0)
{
	if (p1 == -1)//p1遍历完
	{
		cur=nums2[p2--];//nums2放到nums1当中
	}
	else if (p2 == -1)//p2遍历完
	{
		cur = nums1[p1--];//nums1放到nums1当中
	}
	else if (nums1[p1] > nums2[p2])
	{//nums1大于nums2
		cur = nums1[p1--];//nums1放入nums1
	}
	else
	{
		cur = nums2[p2--];
	}
	nums1[tail--] = cur;
}

}

你可能感兴趣的:(数据结构,算法)