剑指 Offer 20. 表示数值的字符串
十一、
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
数值(按顺序)可以分成以下几个部分:
- 若干空格
- 一个 小数 或者 整数
- (可选)一个
'e'
或'E'
,后面跟着一个 整数- 若干空格
小数(按顺序)可以分成以下几个部分:
- (可选)一个符号字符(
'+'
或'-'
)- 下述格式之一:
- 至少一位数字,后面跟着一个点
'.'
- 至少一位数字,后面跟着一个点
'.'
,后面再跟着至少一位数字- 一个点
'.'
,后面跟着至少一位数字整数(按顺序)可以分成以下几个部分:
- (可选)一个符号字符(
'+'
或'-'
)- 至少一位数字
部分数值列举如下:
["+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;
}
}