重刷剑指offer

根据leetcode上的顺序:剑指offer

字符串

剑指 Offer 05. 替换空格

剑指 Offer 05. 替换空格

思路

首先记录这个字符串中的空格的数量count,然后对s进行resize,扩充为oldSize+2*count,然后从后往前进行复写。遇到非空格直接复制,遇到空格就按照顺序复写"%20"。

代码

class Solution {
public:
    string replaceSpace(string s) {
        int oldSize = s.size();
        int count = 0;
        for(auto c:s){
            if(c == ' ')
                count++;
        }
        s.resize(count*2 + oldSize);
        int newSize = s.size();
        for(int i = newSize - 1, j = oldSize - 1; i >= 0, j >= 0;i--, j--){
            if(s[j] == ' '){
                s[i] = '0';
                s[i - 1] = '2';
                s[i - 2] = '%';
                i -= 2;
            }
            else{
                s[i] = s[j];
            }
        }
        return s;
    }
};

剑指 Offer 58 - II. 左旋转字符串

剑指 Offer 58 - II. 左旋转字符串

思路

左旋转字符串是把字符串前面的n个字符转移到字符串的尾部。这里可以通过一个小技巧来实现。
abcdefg, n=2把字符串分为abcdefg两部分,然后进行三次反转。

  1. 反转前n个字符,bacdefg
  2. 反转后面的字符,bagfedc
  3. 整体反转,cdefgab

至于反转函数,可以直接用std里的string的reverse,比如

reverse(s.begin(), s.begin() + n)

也可以直接重新写一个函数。

代码

class Solution {
public:
    string replaceSpace(string s) {
        int oldSize = s.size();
        int count = 0;
        for(auto c:s){
            if(c == ' ')
                count++;
        }
        s.resize(count*2 + oldSize);
        int newSize = s.size();
        for(int i = newSize - 1, j = oldSize - 1; i >= 0, j >= 0;i--, j--){
            if(s[j] == ' '){
                s[i] = '0';
                s[i - 1] = '2';
                s[i - 2] = '%';
                i -= 2;
            }
            else{
                s[i] = s[j];
            }
        }
        return s;
    }
};

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

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

思路

没什么好说的,模拟,考虑到所有情况

代码

class Solution {
public:
    bool isNumber(string s) {
        //先去除前后的空格
        int front = 0;
        for(int i = 0; i < s.size(); i++){
            if(s[i] == ' '){
                front++;
            }
            else{
                break;
            }
        }
        s.erase(s.begin(),s.begin() + front);
        int back = s.size();
        for(int i = s.size() - 1; i >= 0; i--){
            if(s[i] == ' '){
                back--;
            }
            else{
                break;
            }
        }
        s.erase(s.begin() + back,s.end());
        //三个flag记录这三个东西是否出现过
        bool numFlag = false;
        bool dotFlag = false;
        bool eFlag = false;
        for(int i = 0; i < s.size(); i++){
            //如果是'+'或者'-',且符号只能出现在第一位或者e后面
            if((s[i] == '+' || s[i] == '-') && (i == 0 || s[i-1] == 'e' || s[i-1] == 'E')){
                continue;
            }
            //如果是数字
            else if(isdigit(s[i])){
                numFlag = true;
            }
            //如果是'.',但是需要没出现过'.'和'e'
            else if(s[i] == '.' && dotFlag == false && eFlag == false){
                dotFlag = true;
            }
            //如果是'e',需要没出现过'e'且出现过数字,满足条件后要把出现过数字的numFlag调为false
            else if((s[i] == 'e' || s[i] == 'E') && eFlag == false && numFlag == true){
                eFlag = true;
                numFlag = false;
            }
            else{
                return false;
            }
        }
        return numFlag;
    }
};

剑指 Offer 67. 把字符串转换成整数

剑指 Offer 67. 把字符串转换成整数

思路

也是一个模拟为主的题目。需要注意的是要用long类型来保存临时的结果,因为可能会溢出,所以先用long来保存。然后用一次(int)来强转ans的结果,如果(int)ans和ans的结果不一样,说明ans对于int类型来说是溢出的。

代码

class Solution {
public:
    int strToInt(string str) {
        int n = str.size();
        long ans = 0;//防止溢出,先把ans设置为long
        //记录空格后的第一位
        int i = 0;
        while(i < n && str[i] == ' '){
            i++;
        }
        if(i == n){
            return 0;
        }
        //记录符号位
        int flag = 1;
        if(str[i] == '+'){
            i++;
        }
        else if(str[i] == '-'){
            flag = -1;
            i++;
        }
        //记录数字
        while(i < n && str[i] >= '0' && str[i] <= '9'){
            ans = ans*10 + str[i] - '0';
            if(ans > INT_MAX){
                break;
            }
            i++;
        }
        //如果有溢出,转化结果
        if(int(ans) != ans){
            return flag == 1 ? INT_MAX:INT_MIN;
        }
        return flag*ans;
    }
};

链表

剑指 Offer 06. 从尾到头打印链表

剑指 Offer 06. 从尾到头打印链表

思路

可以用遍历的方法来做,也可以直接翻转链表来实现。这里采用翻转链表的方法,需要定义几个节点,比如pre、cur、temp,然后使用一个辅助函数来实现翻转。

代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverse(ListNode* head){
        ListNode* pre = nullptr;
        ListNode* cur = head;
        while(cur){
            ListNode* temp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = temp;
        }
        return pre;
    }
    vector<int> reversePrint(ListNode* head) {
        vector<int> ans;
        head = reverse(head);
        while(head){
            ans.push_back(head->val);
            head = head->next;
        }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值