简单记录一下剑指offer的编程题(C语言实现)——替换空格&&反转链表

1. 替换空格 (剑指 Offer 05)

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

示例:

输入:s = "We are happy."
输出:"We%20are%20happy."

简单分析:
新建一个数组,长度为替换空格后的长度+1,遍历原始数组,往新数组中按顺序添加字符

char* replaceSpace(char* s){
  int count = 0;                    //记录原始数组中有几个空格
  int flag = 0;                     //新数组的索引
  int len = strlen(s);              //计算原始数组长度
  for(int i = 0; i < len; i++){     //计算有几个空格
      if(s[i] == ' '){
          count++;
      }
  }
   char* s1 = (char*)malloc(sizeof(char) * (1 + len + count * 2 ));  //申请动态数组
   for(int i = 0; i < len; i++){     //遍历原始数组,新数组依次进行添加字符
       if(s[i] == ' '){
           s1[flag] = '%';
           s1[flag + 1] = '2';
           s1[flag + 2] = '0';
           flag = flag + 3;
       }else{
           s1[flag] = s[i];
           flag++;
       }
   }
   s1[flag] = '\0';        //这里是flag,因为已经加1了,就是最后一个值了; 不加这个,会报堆栈溢出;字符串以'\0'结尾,一定要加上
   return s1;
}

2. 反转链表

链表是带指针的结构体;

//链表的定义
  struct ListNode {
      int val;
     struct ListNode *next;
  };

在这里插入图片描述`

struct ListNode* reverseList(struct ListNode* head){
    
    //双指针迭代
    struct ListNode* pre = NULL;          //记录前一个结点
    struct ListNode* cur = head;          //记录当前一个结点
    struct ListNode* next = NULL;         //记录下一个结点

    while(cur != NULL){
      next = cur->next;                   //next指向头结点的下一个结点
      cur->next = pre;                    //使当前结点指向前一个结点
      pre = cur;                          //移动pre指针位置,pre指向现在的当前结点
      cur = next;                         //移动cur指针位置, cur指向下一个结点
    }
    return pre;                           //返回pre为新的头节点
}

这里的while中的内容不能改成:

 while(cur != NULL){
      cur->next = pre;                    //使当前结点指向前一个结点
      pre = cur;                          //移动pre指针位置,pre指向现在的当前结点
      cur = cur->next;                    //移动cur指针位置, cur指向下一个结点
    }

因为已经对cur->next进行操作了,即cur指向前一个结点,现在再移动cur的指针位置,已经和头结点的下一个结点断开了,找不到下一个节点的位置了,所以还是要引入新的结点变量,来记录头节点的下一结点来完成遍历链表。

整体思想是:
记录头节点下一节点位置;(记录)
改变当前结点指向,使其指向前一结点;(重指向)
移动当前和前一结点指针位置,使当前节点指针指向下一结点位置,前一结点指向当前节点位置。(移动双指针)

//使用头插法
 struct ListNode *L = (struct ListNode*)malloc(sizeof(struct ListNode));   //创建一个头结点
  
  L->next = NULL;                       //使头结点的下一个结点是NULL
  
  struct ListNode *cur = head;         //记录当前一个结点
  struct ListNode *next = NULL;        //记录下一个结点

  while(cur != NULL){                  //判断当前结点是否为null
     next = cur->next;                 //记录下一个结点,next指向头结点的下一个结点
     cur->next = L->next;              //新插入的当前结点指向(开始)头结点的下一个结点
     L->next = cur;                    //头结点的下一个节点指向新插入的当前结点
     cur = next;                       //移动cur指针位置, cur指向下一个结点
  }
return L->next;                        //返回头结点的下一个结点为新的头节点

整体思想是:
创建一个新的头结点,指向为空;(创建)
记录开始头节点head的下一节点位置;(记录)
新插入的当前结点指向新的头结点的下一个结点;(重指向)
头结点的下一个节点指向新插入的当前结点;(重指向)
移动当前指针位置, 使当前的指针指向下一个结点。(移动)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值