五月集训(第05天)——双指针

双指针

1. 917. 仅仅反转字母

    思路:
        left往右找字母,right往左找字母,两个都找到后交换位置,继续移动指针

class Solution {
public:
    string reverseOnlyLetters(string s) {
        int len = s.length();
        int left = 0, right = len - 1;
        char temp;
        while (left < right) {
            while (!((s[left] >= 'a' && s[left] <= 'z') || (s[left] >= 'A' && s[left] <= 'Z'))) {
                left++;
                if (left >= right) break;
            }
            while (!((s[right] >= 'a' && s[right] <= 'z') || (s[right] >= 'A' && s[right] <= 'Z'))) {
                right--;
                if (left >= right) break;
            }
            if (left >= right) break;
            temp = s[left];
            s[left] = s[right];
            s[right] = temp;
            left ++;
            right --;
        }
        return s;
    }
};

2. 167. 两数之和 II - 输入有序数组

    思路:
        利用leftright两个指针从数组的首尾向中间移动,和大于目标值,right左移,和小于目标值left右移。

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int left = 0, right = numbers.size() - 1;
        vector<int> ans;
        while (left < right) {
            if (numbers[left] + numbers[right] == target) break;
            else if (numbers[left] + numbers[right] < target) left ++;
            else if (numbers[left] + numbers[right] > target) right --;
        }
        ans.push_back(left + 1);
        ans.push_back(right + 1);
        return ans;
    }
};

3. 165. 比较版本号

    思路:
        没用上双指针,直接字符串处理了,思路在代码注释里

class Solution {
public:
    void GetVersion(vector<string> &ver, string version, int len) {
        string temp;
        int flag = 0;
        for (int i = 0; i < len; i++) {
            if (version[i] == '.') {
                if (temp != "") ver.push_back(temp);
                else ver.push_back("0");
                flag = 0;
                temp = "";
            }
            else {
                while (flag == 0) {
                    if (version[i] != '0') flag = 1;
                    else i ++;
                }
                if (version[i] != '.') temp.push_back(version[i]);
                else i--;
            }
        }
    }

    int Cmp_Ver(vector<string> &ver1, vector<string> &ver2) {
        int size1 = ver1.size(), size2 = ver2.size();
        int minn = fmin(size1, size2);
        int len1, len2;
        // 首先将相同部分的修订号比大小
        for (int i = 0; i < minn; i++) {
            len1 = ver1[i].length();
            len2 = ver2[i].length();
            // 长度长的修订号更大(最高位更高)
            if (len1 != len2) return len1 > len2 ? 1 : -1;
            else {  // 长度相等话逐位比较
                for (int j = 0; j < len1; j++) {
                    if (ver1[i][j] != ver2[i][j]) return ver1[i][j] > ver2[i][j] ? 1 : -1;
                }
            }
        }
        // 如果修订号的数量相同,且大小相等
        if (size1 == size2) return 0;
        else {  // 如果前面部分修订号的都相同,就比较修订号更多的一个版本号多出来的修订号是否为0,有一个不为0,则更大
            if (size1 < size2) {
                for (int i = minn; i < size2; i++) {
                    if (ver2[i] != "0") return -1;
                }
            } else  {
                for (int i = minn; i < size1; i++) {
                    if (ver1[i] != "0") return 1;
                }
            }
        }
        return 0;
    }

    int compareVersion(string version1, string version2) {
        vector<string> ver1;
        vector<string> ver2;
        version1 += '.';
        version2 += '.';
        int len_ver1 = version1.length();
        int len_ver2 = version2.length();

        // 将version1的每个修订号(去掉前导零、如果全为0,则该修订号记为0)放入数组ver1
        GetVersion(ver1, version1, len_ver1);

        // 将version2的每个修订号(去掉前导零、如果全为0,则该修订号记为0)放入数组ver2
        GetVersion(ver2, version2, len_ver2);
        
        // 返回比较结果
        return Cmp_Ver(ver1, ver2);
    }
};

4. 443. 压缩字符串

    思路:
        一边统计字母个数,一边在另一个vector存储答案。本来这应该是双指针问题,但是今天状态不好,直接大模拟了,收工,要去复习了,还有两门考试在等我,呜呜呜。

class Solution {
public:
    int compress(vector<char>& chars) {
        int n = chars.size();
        int cnt = 1;
        vector<char> ans;
        ans.push_back(chars[0]);
        for (int i = 1; i < n; i++) {
            if (chars[i] == ans[ans.size() - 1]) {
                cnt ++;
            } 
            if (i == n - 1 || chars[i] != ans[ans.size() - 1]) {
                if (cnt < 10 && cnt > 1) ans.push_back(cnt + '0');
                else if (cnt >= 10) {
                    int temp = 0;
                    int len = 0;
                    while (cnt) {
                        len ++;
                        temp = temp * 10 + cnt % 10;
                        cnt /= 10;
                    }
                    while (temp) {
                        len --;
                        ans.push_back(temp % 10 + '0');
                        temp /= 10;
                    }
                    while (len --) {
                        ans.push_back('0');
                    }
                }
                if (chars[i] != chars[i - 1]) ans.push_back(chars[i]);
                cnt = 1;
            }
        }
        chars.clear();
        for (int i = 0; i < ans.size(); i++) chars.push_back(ans[i]);
        return ans.size();
    }
};
posted @ 2022-05-05 21:12  番茄元  阅读(9)  评论(0)    收藏  举报