嵌入式程序员手撕代码

目录

1、将字符串反转

2、数字翻转和回文判断

3、大小端问题

(1)判断大小端

(2)大小端转换

4、实现函数memcpy(), strcpy(), strcmp(), strcat()

 5、实现最简单的hello world字符设备驱动

6、设计函数 int atoi(char *s),void itoa(int n, char s[])

7、链表操作(单链表的插入、删除节点、遍历、反转)

8、排序算法

9、二分查找

10、 字符串转换数字

 11、求一个数中1的位数

12、判断一个数是否为2的幂

13、实现atoi

滑动窗口

 24. 两两交换链表中的节点

3. 无重复字符的最长子串

86. 分隔链表 

141. 环形链表 ​编辑

19. 删除链表的倒数第 N 个结点

 61. 旋转链表

438. 找到字符串中所有字母异位词(滑动窗口)

5. 最长回文子串

2487. 从链表中移除节点

剑指 Offer 45. 把数组排成最小的数 

1、将字符串反转

// 实现字符串反转的两个函数
// 第一个函数,参数为字符数组
void reserverString(char str[])
{
    char tmp; // 定义一个临时变量
    int i, j; // 定义两个整型变量
    // 循环遍历字符数组,i从0开始,j从字符串长度减1开始,i小于j时循环
    for (i = 0, j = strlen(str) - 1; i < j; i++, j--)
    {
        tmp = str[i]; // 将str[i]的值赋给tmp
        str[i] = str[j]; // 将str[j]的值赋给str[i]
        str[j] = tmp; // 将tmp的值赋给str[j]
    }
}
// 第二个函数,参数为字符指针
char* reserverString1(char* str)
{
    char* start = str; // 定义一个字符指针start,指向字符串的首地址
    char* end = str + strlen(str) - 1; // 定义一个字符指针end,指向字符串的末尾地址
    char tmp; // 定义一个临时变量
    // 如果传入的字符串不为空
    if (NULL != str)
    {
        // do-while循环,先执行一次循环体,再判断条件是否成立
        do
        {
            tmp = *start; // 将start指向的字符赋给tmp
            *start++ = *end; // 将end指向的字符赋给start指向的字符,然后start指针向后移动一位
            *end-- = tmp; // 将tmp的值赋给end指向的字符,然后end指针向前移动一位
        } while (start<end); // 当start指针小于end指针时继续循环
    }
    return str; // 返回反转后的字符串
}

2、数字翻转和回文判断

数字翻转

int reverse(int num) {
    int reversed = 0;
    while (num != 0) {
        reversed = reversed * 10 + num % 10;
        num /= 10;
    }
    return reversed;
}
#include <stdio.h>
int main() {
    int num, reversed_num = 0, remainder, original_num; // 定义整型变量num、reversed_num、remainder和original_num

    printf("Enter an integer: "); // 输出提示信息,要求用户输入一个整数
    scanf("%d", &num); // 读取用户输入的整数,并存储到变量num中

    original_num = num; // 将变量num的值赋给变量original_num

    while (num != 0) { // 当变量num不等于0时,执行循环体内的语句
        remainder = num % 10; // 取变量num除以10的余数,存储到变量remainder中
        reversed_num = reversed_num * 10 + remainder; // 将变量reversed_num乘以10再加上变量remainder的值,存储到变量reversed_num中
        num /= 10; // 将变量num除以10的结果,存储到变量num中
    }

    if (original_num == reversed_num) { // 如果变量original_num等于变量reversed_num,执行if语句块内的语句
        printf("%d is a palindrome.\n", original_num); // 输出变量original_num是回文数的信息
    } else { // 否则,执行else语句块内的语句
        printf("%d is not a palindrome.\n", original_num); // 输出变量original_num不是回文数的信息
    }

    return 0; // 返回0,表示程序正常结束
}

3、大小端问题

(1)判断大小端

方法一:输入一个字符变量,若数据的高位字节存储在内存的低地址处,低位字节存储在内存的高地址处,则是大端存储方式;若数据的低位字节存储在内存的低地址处,高位字节存储在内存的高地址处,则是小端存储方式。

#include <stdio.h>
#include <stdlib.h>
 
int check_sys()
{
    int a = 1;
    return *(char*)&a;//返回1表示小端,返回0表示大端
}
 
int main()
{
    if (check_sys() == 1)
    {
        printf("小端\n");
    }
    else
    {
        printf("大端\n");
    }
    system("pause");
    return 0;
}

方法二:用联合体

(2)大小端转换

//对于16位数据,定义一个宏BIG2LITTLE,用于将大端字节序转换为小端字节序
#define BIG2LITTLE(A)   ((((A)&0xff00)>>8) | (((A)&0x00ff)<<8))  

//对于32位数据,定义一个宏BIG2LITTLE,用于将大端字节序转换为小端字节序
#define BIG2LITTLE(A)  (((A)&0xff000000)>>24) | (((A)&0x000000ff)<<24) | (((A)&0x0000ff00)<<8) | (((A)&0x00ff00)>>8))

//1. 宏定义:#define 宏名(参数) 宏体

//2. & 位运算符:按位与,将两个数的二进制位进行与运算,只有两个数对应位都为1时,结果才为1,否则为0

//3. | 位运算符:按位或,将两个数的二进制位进行或运算,只要两个数对应位有一个为1,结果就为1,否则为0

//4. >> 位运算符:右移运算符,将一个数的二进制位向右移动指定的位数,移动后高位补0

//5. << 位运算符:左移运算符,将一个数的二进制位向左移动指定的位数,移动后低位补0

//6. &0xff00:将A的高8位清零,低8位保留

//7. &0x00ff:将A的低8位清零,高8位保留

//8. ((((A)&0xff00)>>8) | (((A)&0x00ff)<<8)):将A的高8位和低8位交换位置,得到小端字节序

//9. &0xff000000:将A的高8位清零,低24位保留

//10. &0x000000ff:将A的低24位清零,高8位保留

//11. &0x0000ff00:将A的低16位和高8位清零,中间的8位保留

//12. ((((A)&0xff000000)>>24) | (((A)&0x000000ff)<<24) | ((A)&0x0000ff00)<<8) | (((A)&0x00ff00)>>8)):将A的高24位和低8位交换位置,将A的次高8位和次低8位交换位置,得到小端字节序。

4、实现函数memcpy(), strcpy(), strcmp(), strcat()

(1)函数原型 :void *memcpy(void *dest, const void *src, size_t n);

功能:从源src所指的内存地址的起始位置开始,拷贝n个字节到目标dest所指的内存地址的起始位置中,函数返回dest的值。

(2)函数原型 :void strcpy (char *dest,const char*src);

功能:将src拷贝到dest中

char* strcpy(char* dest, const char* src) {
    char* p = dest;
    while (*src != '\0') {
        *p++ = *src++;
    }
    *p = '\0';
    return dest;
}

(3)函数原型 :int strcmp(const char *s,const char * t);
功能:比较字符串s和t,并且根据s按照字典顺序小于,等于或大于t的结果分别返回负整数,0,正整数。

int strcmp(const char *s, const char * t)
{
	for (; *s == *t; s++, t++)//注意for循环,能循环下去的条件的两者元素对应相等,一旦不相等立即退出
		if (*s == '\0')
			return 0;//表示相等
	return *s - *t;
}

(4)函数原型 :char *strcat(char *dest,char *src);
功能:把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0',返回指向dest的指针

char *strcat(char *dst, const char *src) {
    // 找到目标字符串的末尾
    char *p = dst + strlen(dst);
    // 逐个字符追加源字符串,直到遇到 null 字符
    while (*src != '\0') {
        *p++ = *src++;
    }
    // 添加 null 字符
    *p = '\0';
    return dst;
}

(5)函数原型 :void *memmove(void *dest, const void *src, size_t n);
功能:将src指向的内存块中的n个字节拷贝到dest指向的内存块中。与memcpy()函数不同的是,memmove()函数可以处理源内存块和目标内存块重叠的情况,保证拷贝的正确性。因此,memmove()函数更加安全,但是相对于memcpy()函数来说,它的执行效率可能会稍微低一些。

void *my_memmove(void *dest, const void *src, size_t count)
{
    char *tmp;  //定义一个char类型的指针tmp
    const char *s;  //定义一个const char类型的指针s
    if((dest + count < src) || (src+ count) < dest)){  //如果两个内存没有重叠
        tmp = dest;  //将目标内存的地址赋值给tmp
        s = src;  //将源内存的地址赋值给s
        while (count--)  //循环count次
            *tmp++ = *s++;  //将源内存中的数据复制到目标内存中
    } else {  //如果两个内存有重叠
        tmp = dest;  //将目标内存的地址赋值给tmp
        tmp += count;  //将tmp指针移动到目标内存的末尾
        s = src;  //将源内存的地址赋值给s
        s += count;  //将s指针移动到源内存的末尾
        while (count--)  //循环count次
            *--tmp = *--s;  //将源内存中的数据复制到目标内存中
    }
    return dest;  //返回目标内存的地址
}

 5、实现最简单的hello world字符设备驱动

//1、头文件的包含
#include <linux/init.h>
#include <linux/module.h>
 
//许可的声明
MODULE_LICENSE("Dual BSD/GPL");
 
//3、函数注意static、返回值、printk、KERN
static int hello_init(void)
{
	printk(KERN_ALERT "Hello World!\n");
	return 0;
}
static void hello_exit(void)
{
	printk(KERN_ALERT "Goodbye, cruel world\n");
}
//4、注意这两个宏函数的使用
module_init(hello_init);
module_exit(hello_exit);

6、设计函数 int atoi(char *s),void itoa(int n, char s[])

(1)int atoi(char *s)

描述:把字符串转换成整型数的一个函数。int atoi(const char *nptr) 函数会扫描参数 nptr字符串,跳过前面的空白字符(例如空格,tab缩进)等,可以通过isspace( )函数来检测),直到遇上数字或正负符号才开始做转换,而在遇到非数字或字符串结束符('\0')才结束转换,并将结果返回。如果 nptr不能转换成 int 或者 nptr为空字符串,那么将返回0。特别注意,该函数要求被转换的字符串是按十进制数理解的。

int atoi(char s[])
{
	int i, n, sign;
	for (i = 0; isspace(s[i]); i++); /*跳过空白符:空格时会一直循环,直到遇到不是空格*/ 
	sign = (s[i] == '-') ? -1 : 1;//遇到的如果不是-号,比如是数字,则说明不是负数 
	if (s[i] == '+' || s[i] == '-') /* 跳过符号 */
		i++;
	for (n = 0; isdigit(s[i]); i++)
		n = 10 * n + (s[i] - '0');
	return sign * n;
}//注意判断空格、是否是数字的函数,你懂写吗?
int atoi(char *s) {
    int num = 0;
    int sign = 1;
    if (*s == '-') {
        sign = -1;
        s++;
    }
    while (*s != '\0') {
        if (*s >= '0' && *s <= '9') {
            num = num * 10 + (*s - '0');
        } else {
            break;
        }
        s++;
    }
    return num * sign;
}

(2)void itoa(int n, char s[])

功能:将整型数字转换为字符串

void itoa(int n, char s[])
{
	int i, sign;
	if ((sign = n) < 0) //记录符号
	n = -n; //使n成为正数
	i = 0;
	do 
	{ //以反序生成数字          //假设n=987654
		s[i++] = n % 10 + '0'; //n % 10 + '0'表示数字对应的字符,比如第一次的数字是4,变成字符4,是4+'0'	                       
	} while ((n /= 10) > 0);   //此时n变成了98765
	if (sign < 0)
	s[i++] = '-';
	s[i] = '\0';
	reverse(s);
}

7、链表操作(单链表的插入、删除节点、遍历、反转)

8、排序算法

9、二分查找

/* 
参数:数组,数组元素个数,要查找的数
返回:成功找到返回元素下标;失败返回-1
*/
int binary_search(int a[], int len, int num)
{
	// 定义查找范围的下限和上限
	int low = 0, high = len-1;
	// 定义中间位置
	int mid = (low+high) / 2;
	
	// 当下限小于等于上限时,继续查找
	while(low <= high){
		// 如果中间位置的元素等于要查找的数,返回中间位置下标
		if(num == a[mid]){
			return mid;
		}
		// 如果中间位置的元素小于要查找的数,将下限移动到中间位置的右侧,继续查找
		else if(num > a[mid]){
			low = mid + 1;
			mid = (low+high) / 2;
		}
		// 如果中间位置的元素大于要查找的数,将上限移动到中间位置的左侧,继续查找
		else{
			high = mid - 1;
			mid = (low+high) / 2;
		}
	}
	// 如果查找失败,返回-1
	return -1;
}

10、 字符串转换数字

int stoi(char *p)
{
	int i = 0;
	for(i = 0; *p; p++){
		i = (*p - '0') + 10 * i;
	}
	return i;
}

 11、求一个数中1的位数

算法:让一个数的最低位和1位与,位与完数向右移1位,如果与的结果位1,计数+1。返回计数值。

// 统计一个整数二进制表示中1的个数
int NumOne(int i)
{
    int ret = 0; // 初始化计数器为0
    while(i){ // 当i不为0时,继续循环
        if(i & 1) // 如果i的二进制表示的最后一位是1
            ret++; // 计数器加1
        i = i>>1; // 将i的二进制表示向右移动一位,相当于除以2
    }
    return ret; // 返回计数器的值
}

12、判断一个数是否为2的幂

算法:2的次幂的二进制特征是最高位为1,其余全0。可以用它和(它-1)位与,结果为0表示是,反之不是。

/* 
传一个整数,当这个数为2的幂时返回0;不是返回1 
*/
int judge(int i)
{
	if(i <= 0)      // 判断是否为正数
		return 1;   // 不是正数,返回1
	else{
		if(!(i & (i-1)))    // 判断是否为2的幂
			return 0;   // 是2的幂,返回0
		else
			return 1;   // 不是2的幂,返回1
	}
}

13、实现atoi

描述:字符串转换成数字,前面跳过空格,当第一个字符为+、-、数字字符时,函数转换,直到非数字字符,返回转换后的整型数。若非空格后的第一个字符不是上面三者其一,则返回0。

int my_atoi(const char s[])
{
    int i;
    int sign;
    int ret = 0;    
    for(i = 0; isspace(s[i]); i++);  // 从字符串开头开始跳过空格,isspace()函数用于判断字符是否为空格
    sign = (s[i] == '-') ? -1 : 1;  // 判断符号,如果第一个非空格字符是'-',则为负数,否则为正数
    if(s[i] == '+' || s[i] == '-'){  // 如果第一个非空格字符是'+'或'-',则跳过该字符
        i++;
    }
    for(ret = 0; isdigit(s[i]); i++)  // 从第一个非空格字符开始,如果是数字,则将其转换为整数
        ret = (s[i]-'0') + ret*10;  // 将字符转换为数字,累加到ret中
    return ret * sign;  // 返回最终结果
}
int myAtoi(char * s){
  int i=0;
    int sign=1;
    long long ret=0;
    while(isspace(s[i])) i++;
    if(s[i]=='-') {
        sign=-1;
        i++;
    } else if(s[i]=='+') {
        i++;
    }
    while(isdigit(s[i])) {
        ret=ret*10+(s[i]-'0');
        if(ret*sign>INT_MAX) return INT_MAX;
        if(ret*sign<INT_MIN) return INT_MIN;
        i++;
    }
    return ret*sign;
}

14、遍历单链表中确定值最大的点

int GetMax(LinkList L)
{
    // 如果链表为空,返回NULL
    if(L->next == NULL)
        return NULL;
    LNode *pmax,*p;
    // 假定第一个节点中数据最大
    pmax=L->next;
    p=L->next->next;
    while(p)
    {
        // 若p值大于pmax值,则重新赋值
        if(p->data > pmax->data)
            pmax=p;
        // 遍历链表
        p=p->next;
    }
    // 返回最大值
    return pmax->data;
}

应对嵌入式校招面试手撕之——链表_嵌入式手撕算法_iamsohard的博客-CSDN博客

程序员校招准备嵌入式软件面试的手撕代码练习_嵌入式软件会手撕tcp_iamsohard的博客-CSDN博客

各大公司IC面试手撕代码总结(超全面)-

1.分治法基本思想
分治法的基本思想是将一个规模为n的问题分解为k个规模为较小的子问题,这些子问题互相独立且与原问题相同。递归地求解这些子问题,然后利用子问题的解合并(构造)出原问题的解。
(1)分治算法的设计
分治算法的设计过程分为三个阶段:

分解(Divide) 阶段;将整个问题划分为多个子问题;

递归求解(Conquer)阶段: (递归调用正在设计的算法) 求解每个子问题;

合并( Combine)阶段:合并子问题的解,形成原始问题的解。

滑动窗口

滑动窗使用思路(寻找最长)
一核心: 左右双指针(L, R)在起始点,R向右逐位滑动循环
—每次滑动过程中
如果:窗内元素满足条件, R向右扩大窗口,并更新最优结果
如果:窗内元素不满足条件, L向右缩小窗口
—R到达结尾
滑动窗使用思路(寻找最短)
—核心:左右双指针(L, R)在起始点,R向右逐位滑动循环
—每次滑动过程中
如果:窗内元素满足条件, L向右缩小窗口,并更新最优结果

int minSubArrayLen(int target, int* nums, int numsSize){
int left=0,right=0;
int sum=0;
int best=0;
int*result=malloc(sizeof(int)*numsSize);
while(right<numsSize)
{
    sum+=nums[right];
    while(sum>=target)
    {
       if(right-left+1<best||best==0)
       {
           best=right-left+1;
       }
       sum-=nums[left];
       left++;
    }
    right++;
}
return best; 
}

 24. 两两交换链表中的节点

struct ListNode* swapPairs(struct ListNode* head){
    // 如果链表为空或只有一个节点,直接返回
    if (head == NULL || head->next == NULL) {
        return head;
    }
    // 定义两个指针p和q,分别指向相邻的两个节点
    struct ListNode *p = head;
    struct ListNode *q = head->next;
    // 递归调用swapPairs函数,交换后面的节点
    p->next = swapPairs(q->next);//p->next等于2指向的下一个结点交换后的结点,即swapPairs(q->next)
    // 将q节点指向p节点,完成交换
    q->next = p;//2指向1
    // 返回交换后的链表头节点
    return q;
}

3. 无重复字符的最长子串

int lengthOfLongestSubstring(char *s) {
    int n = strlen(s);
    int ans = 0;
    int i = 0, j = 0;
    int freq[128] = {0}; // 用于记录字符出现的频率

    while (i < n && j < n) {
        if (freq[s[j]] == 0) { // 如果当前字符没有出现过
            freq[s[j++]]++; // 将字符加入窗口,并将其出现次数加1
            ans = fmax(ans, j - i); // 更新最长子串长度
        } else { // 如果当前字符已经出现过
            freq[s[i++]]--; // 将窗口左侧的字符移出,并将其出现次数减1
        }
    }

    return ans;
}

86. 分隔链表 

该代码的思路是创建两个新的链表,一个用于存储小于x的节点,一个用于存储大于或等于x的节点。然后遍历原链表,将小于x的节点插入到小链表中,将大于或等于x的节点插入到大链表中。最后将小链表的尾节点指向大链表的头节点,返回小链表的头节点即可。 

// 定义单链表结构体
// 包含一个整数值和指向下一个节点的指针
struct ListNode {
    int val;
    struct ListNode *next;
};

// 分割链表函数,传入链表头指针和分割值x
struct ListNode* partition(struct ListNode* head, int x) {
    // 如果链表为空或只有一个节点,直接返回
    if(head==NULL||head->next==NULL)
        return head;
    // 定义两个新链表头节点,一个存放小于x的节点,一个存放大于等于x的节点
    struct ListNode *smallHead = (struct ListNode*)malloc(sizeof(struct ListNode));
    struct ListNode *bigHead = (struct ListNode*)malloc(sizeof(struct ListNode));
    // 定义两个尾指针,用于添加新节点
    struct ListNode *smallTail = smallHead;
    struct ListNode *bigTail = bigHead;
    // 定义一个指针p,用于遍历原链表
    struct ListNode *p = head;
    // 遍历原链表
    while (p != NULL) {
        // 如果当前节点的值小于x,将其添加到小链表中
        if (p->val < x) {
            smallTail->next = p;
            smallTail = smallTail->next;
        } else { // 否则将其添加到大链表中
            bigTail->next = p;
            bigTail = bigTail->next;
        }
        // 指针p指向下一个节点
        p = p->next;
    }
    // 将小链表的尾节点指向大链表的头节点
    smallTail->next = bigHead->next;
    // 将大链表的尾节点指向NULL
    bigTail->next = NULL;
    // 如果小链表为空,直接返回大链表
    if(smallHead->next == NULL) return bigHead->next;
    // 否则返回小链表
    return smallHead->next;
}

141. 环形链表

bool hasCycle(struct ListNode *head) {
    int count = 10001; // 设置一个计数器,避免链表太长导致死循环
    while (count) { // 循环10001次
        if (head == NULL) { // 如果链表为空,说明没有环
            return false;
        }
        head = head->next; // 指针向后移动
        count--; // 计数器减1
    }
    return true; // 如果循环10001次还没有返回false,说明链表有环
}

19. 删除链表的倒数第 N 个结点

struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
// 定义函数,传入链表头指针和要删除的倒数第n个节点的位置n
if(head==NULL)   return head;
// 如果链表为空,直接返回头指针
struct ListNode*fast=head;
// 定义快指针,指向头指针
struct ListNode*slow=head;
// 定义慢指针,指向头指针
while(n)
{
    fast=fast->next;
    n--;
}
// 快指针先走n步
if(fast==NULL)  return head->next;
// 如果快指针已经走到链表末尾,说明要删除的是头节点,直接返回头指针的下一个节点
while(fast->next!=NULL)
{
    fast=fast->next;
    slow=slow->next;
}
// 快指针和慢指针同时向前走,直到快指针走到链表末尾
slow->next=slow->next->next;
// 慢指针的下一个节点指向下下个节点,即删除了倒数第n个节点
return head;
// 返回头指针
}

 61. 旋转链表

struct ListNode* rotateRight(struct ListNode* head, int k){
if(head==NULL||head->next==NULL||k==0)
return head;
int count=1;
struct ListNode*p=head;
while(p->next!=NULL)
{
    p=p->next;
    count++;//计算链表结点个数
}
p->next=head;//链表尾指向头,形成环形链表
int step=count-k%count;
while(step--)
{
    p=p->next;//寻找新的链表尾
}
struct ListNode*tail=p;//链表尾
struct ListNode*res=p->next;//因为是环形链表,所以这是链表头
tail->next=NULL;//链表尾指向空
return res;
}

438. 找到字符串中所有字母异位词(滑动窗口)

int* findAnagrams(char * s, char * p, int* returnSize){
    int len1=strlen(s);
    int len2=strlen(p);
    int*res=(int*)malloc(sizeof(int)*128);
    if(len2>len1) 
    *returnSize = 0;
    return res;
    int i=0;
    int count[26]={0};
    for(int i=0;i<len1;i++)
    {
        count[p[i]-'a']++;
    }
    for(int left=0,right=0;right<len1;right++)
    {
        count[s[right]-'a']--;
        while(count[s[right]-'a']<0)
        {
            count[s[left]-'a']++;
            
            left++;
        }
        if(right-left+1==len2)
        res[i++]=left;
    }
    * returnSize=i;
    return res;
}

5. 最长回文子串

// 给定一个字符串s,返回s中的最长回文子串
char* longestPalindrome(char* s) {
    int len = strlen(s); // 获取字符串s的长度
    if (len < 2) { // 如果s的长度小于2,直接返回s
        return s;
    }
    int maxLen = 1, start = 0; // 初始化最长回文子串的长度为1,起始位置为0
    for (int i = 0; i < len - 1; i++) { // 遍历字符串s
        int len1 = expandAroundCenter(s, i, i); // 以i为中心,向两边扩展,获取回文子串的长度
        int len2 = expandAroundCenter(s, i, i + 1); // 以i和i+1为中心,向两边扩展,获取回文子串的长度
        int curMaxLen = len1 > len2 ? len1 : len2; // 取两种情况下的最大回文子串长度
        if (curMaxLen > maxLen) { // 如果当前回文子串长度大于最大回文子串长度
            maxLen = curMaxLen; // 更新最大回文子串长度
            start = i - (maxLen - 1) / 2; // 更新最大回文子串的起始位置
        }
    }
    s[start + maxLen] = '\0'; // 将最大回文子串的结束位置设置为'\0',使其成为一个字符串
    return s + start; // 返回最大回文子串的起始位置
}

// 以left和right为中心,向两边扩展,获取回文子串的长度
int expandAroundCenter(char* s, int left, int right) {
    int len = strlen(s); // 获取字符串s的长度
    while (left >= 0 && right < len && s[left] == s[right]) { // 如果left和right指向的字符相同,继续向两边扩展
        left--; // 左指针向左移动
        right++; // 右指针向右移动
    }
    return right - left - 1; // 返回回文子串的长度
}

2487. 从链表中移除节点

int findRepeatNumber(int* nums, int numsSize){
if(numsSize==0||numsSize==1)   return -1;
for(int i=0;i<numsSize;i++)
{
    while(nums[i]!=i)
    {
        if(nums[i]==nums[nums[i]])
        {
            return nums[i];
        }
        int k=nums[nums[i]];
        nums[nums[i]]=nums[i];
        nums[i]=k;
    }
}
return -1;
}

剑指 Offer 45. 把数组排成最小的数 

如果x+y<y+x,就让x排在y的前面。

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值