2. leetcode(哈系表+字符串)

1. leetcode 242 有效的字母异位词

class Solution {
public:
    bool isAnagram(string s, string t) {
        int record[26] = {0};
        for (int i = 0; i < s.size(); i++) {
            record[s[i] - 'a']++; 
        }
        for (int i = 0; i < t.size(); i++) {
            record[t[i] - 'a']--;
        }
        for (int i = 0; i < 26; i++) {
            if (record[i] != 0)
                return false;
        }
        return true;
    }
};

#endif


#if 0

//leetcode 349  两个数组的交集
//unorder_set 中无序不重复

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result;
        unordered_set<int> a_set(nums1.begin(), nums1.end());

        for (int i : nums2) {
            //find返回i的迭代器,如果找不到该元素,则迭代器指向集合最后一个元素之后的位置
            //所以如果i 不在a_set, 返回的就是a_set.end();
            if (a_set.find(i) != a_set.end()) {
                result.insert(i);
            }
        } 
        return vector<int>(result.begin(), result.end());
    }
};


//使用map

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_map<int, int> map;
        vector<int> res;
        for (int i = 0; i < nums1.size(); i++) {
            map[nums1[i]] = 1;
        }

        for (int i = 0; i < nums2.size(); i++) {
            if (map[nums2[i]] == 1) {
                map[nums2[i]] = 0;
                res.push_back(nums2[i]);
            }
        }
        return res;
    }
};

2. leetcode 202 快乐数

class Solution {
public:
    //取数值的各个位上的单数平方之和
    int getSum(int n) {
        int sum = 0;
        while (n) {
            sum += (n % 10) * (n % 10);
            n /= 10;
        }
        return sum;
    }
    bool isHappy(int n) {
        unordered_set<int> res;
        while (1) {
            int sum = getSum(n);
            if (sum == 1) {
                return true;
            }
            // 如果这个sum曾经出现过,说明陷入了无限循环中
            if (res.find(sum) != res.end()) {
                return false;
            } else {
                res.insert(sum);
            }
            n = sum;
        }
        
    }
};

3. leetcode 1 两数之和

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> res;
        for (int i = 0; i < nums.size(); i++) {
            auto iter = res.find(target - nums[i]);
            if (iter != res.end()) {
                return {iter->second, i};
            }
            res.insert(pair<int, int>(nums[i], i));
        }
        return {};
    }
};

4. leetcode 383 赎金信

//字符统计
class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        int record[26] = {0};
        for (int i = 0; i < magazine.length(); i++) {
            record[magazine[i] - 'a']++;
        }
        for (int i = 0; i < ransomNote.length(); i++) {
            record[ransomNote[i] - 'a']--;
            if (record[ransomNote[i] - 'a'] < 0) {
                return false;
            }
        }
        return true;
    }
};

5. leetcode 15 三数之和


class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        if (nums.size() < 3) return {};
        vector<vector<int>> res; // 保存所有不重复的三元组
        sort(nums.begin(), nums.end());

        for (int i = 0; i < nums.size(); i++) {
            if (nums[i] > 0) return res;  // 第一个数大于0,后面递增,则可能为0
            //去重
            if (i > 0 && nums[i] == nums[i - 1] ) {
                continue;
            }

            int left = i + 1, right = nums.size() - 1;
            while (right > left) {
                if (nums[i] + nums[left] + nums[right] > 0) {
                    right--;
                } else if (nums[i] + nums[left] + nums[right] < 0) {
                    left++;
                } else {
                    res.push_back(vector<int> {nums[i], nums[left], nums[right]});

                    // 去重逻辑应该在找到第一个三元组之后
                    while (right > left && nums[right] == nums[right - 1]) right--;
                    while (right > left && nums[left] == nums[left + 1]) left--;
                    //找到答案,双指针收缩
                    left++;
                    right--;
                }

            }
        }
        return res;
    }
};


// 
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) 
    {
        int size = nums.size();
        if (size < 3)   return {};          // 特判
        vector<vector<int> >res;            // 保存结果(所有不重复的三元组)
        std::sort(nums.begin(), nums.end());// 排序(默认递增)
        for (int i = 0; i < size; i++)      // 固定第一个数,转化为求两数之和
        {
            if (nums[i] > 0)    return res; // 第一个数大于 0,后面都是递增正数,不可能相加为零了
            // 去重:如果此数已经选取过,跳过
            if (i > 0 && nums[i] == nums[i-1])  continue;
            // 双指针在nums[i]后面的区间中寻找和为0-nums[i]的另外两个数
            int left = i + 1;
            int right = size - 1;
            while (left < right)
            {
                if (nums[left] + nums[right] > -nums[i])
                    right--;    // 两数之和太大,右指针左移
                else if (nums[left] + nums[right] < -nums[i])
                    left++;     // 两数之和太小,左指针右移
                else
                {
                    // 找到一个和为零的三元组,添加到结果中,左右指针内缩,继续寻找
                    res.push_back(vector<int>{nums[i], nums[left], nums[right]});
                    left++;
                    right--;
                    // 去重:第二个数和第三个数也不重复选取
                    // 例如:[-4,1,1,1,2,3,3,3], i=0, left=1, right=5
                    while (left < right && nums[left] == nums[left-1])  left++;
                    while (left < right && nums[right] == nums[right+1])    right--;
                }
            }
        }
        return res;
    }
};

6. leetcode 18 四数之和

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> res;
        sort(nums.begin(), nums.end());

        for (int i = 0; i < nums.size(); i++) {
            if (i > 0 && nums[i] == nums[i - 1]) {  //去重
                continue;
            }

            for (int j = i + 1; j < nums.size(); j++) {
                if (j > i + 1 && nums[j] == nums[j - 1]) {  //去重
                    continue;
                }

                int left = j + 1, right = nums.size() - 1;
                while (left < right) {
                    if (nums[i] + nums[j] + nums[left] + nums[right] >target) {
                        right--;
                    } else if (nums[i] + nums[j] + nums[left] + nums[right] < target) {
                        left++;
                    } else {
                        res.push_back(vector<int> {nums[i], nums[j], nums[left], nums[right]});
                        left++;
                        right--;
                        while (right > left && nums[right] == nums[right + 1]) right--;
                        while (right > left && nums[left] == nums[left - 1]) left++;


                    }
                }
            }
        }
        return res;
    }
};

字符串

7. leetcode 344 反转字符串

class Solution {
public:
    void reverseString(vector<char>& s) {
        int n = s.size();
        for (int left = 0, right = n - 1; left <= right; ++left, --right) {
            swap(s[left],s[right]);
        }

    }
};

8. leetcode 541 反转字符串II

class Solution {
public:
    void reverse(string& s, int start, int end) {
        for (int i = start, j = end; i < j; i++, j--) {
            swap(s[i], s[j]);
        }
    }
    string reverseStr(string s, int k) {
        for (int i = 0; i < s.size(); i += 2 * k) {
            //每隔2k个字符的前k个字符进行反转
            //剩余字符小于2k但大于等于k个,则反转前k个字符
            if (i + k < s.size()) {
                reverse(s, i, i + k - 1);
                continue;
            }
            //直到剩余字符小于k个,则反转余下全部
            reverse(s, i, s.size() - 1);
        }
        return s;
    }
};


//模拟

class Solution {
public:
    string reverseStr(string s, int k) {
        int n = s.length();
        for (int i = 0; i < n; i += 2 * k) {
            reverse(s.begin() + i, s.begin() + min(i + k, n));
        }
        return s;
    }
};

9. 剑指Offer 05 替换空格

class Solution {
public:
    string replaceSpace(string s) {
        int length = s.size();
        for (int i = 0; i <= length - 1; i++) {
            if (s[i] == ' ') {
                s += "  ";
            }
        }

        int i = s.size() - 1;
        for (int j = length - 1; j >= 0; j--) {
            if (s[j] == ' ') {
                s[i--] = '0';
                s[i--] = '2';
                s[i--] = '%';
            } else {
                s[i--] = s[j];
            }
        }

        return s;

    }
};

//
class Solution {
public:
    string replaceSpace(string s) {
        string res;
        for (auto &c : s) {  //遍历原字符串
            if (c == ' ') {
                res.push_back('%');
                res.push_back('2');
                res.push_back('0');
            } else {
                res.push_back(c);
            }
        }
        return res;
    }
};

10. leetcode 151 翻转字符串里的单词

class Solution {
public:
    //字符串反转
    void reverse(string& s, int start, int end) {
        for (int i = start, j =  end; i < j; i++, j--) {
            swap(s[i], s[j]);
        }
    }
    //移除冗余空格 双指针法
    void removeExtraSpace(string& s) {
        int slow = 0, fast = 0;
        while (s.size() > 0 && fast < s.size() && s[fast] == ' ') {
            fast++;
        }
        for (; fast < s.size(); fast++) {
            //去除字符串内的多余空格
            if (fast > 1 && s[fast] == ' ' && s[fast - 1] == s[fast]) {
                continue;
            } else {
                s[slow++] = s[fast];
            }
        }
        if (slow > 1 && s[slow - 1] == ' ') {
            s.resize(slow - 1);
        } else {
            s.resize(slow);
        }
    }
    string reverseWords(string s) {
        removeExtraSpace(s);
        reverse(s, 0, s.size() - 1);

        for (int i = 0; i < s.size(); i++) {
            int j = i;
            while (j < s.size() && s[j] != ' ') j++;
            reverse(s, i, j - 1);
            i = j;
        } 
        return s;
    }
};


//自行编写对应的函数
class Solution {
public:
    string reverseWords(string s) {
        // 反转整个字符串
        reverse(s.begin(), s.end());

        int n = s.size();
        int idx = 0;
        for (int start = 0; start < n; ++start) {
            if (s[start] != ' ') {
                // 填一个空白字符然后将idx移动到下一个单词的开头位置
                if (idx != 0) s[idx++] = ' ';

                // 循环遍历至单词的末尾
                int end = start;
                while (end < n && s[end] != ' ') s[idx++] = s[end++];

                // 反转整个单词
                reverse(s.begin() + idx - (end - start), s.begin() + idx);

                // 更新start,去找下一个单词
                start = end;
            }
        }
        s.erase(s.begin() + idx, s.end());
        return s;
    }
};

//双端队列
class Solution {
public:
    string reverseWords(string s) {
        int left = 0, right = s.size() - 1;
        // 去掉字符串开头的空白字符
        while (left <= right && s[left] == ' ') ++left;

        // 去掉字符串末尾的空白字符
        while (left <= right && s[right] == ' ') --right;

        deque<string> d;
        string word;

        while (left <= right) {
            char c = s[left];
            if (word.size() && c == ' ') {
                // 将单词 push 到队列的头部
                d.push_front(move(word));
                word = "";
            }
            else if (c != ' ') {
                word += c;
            }
            ++left;
        }
        d.push_front(move(word));
        
        string ans;
        while (!d.empty()) {
            ans += d.front();
            d.pop_front();
            if (!d.empty()) ans += ' ';
        }
        return ans;
    }
};


//stringstream + 栈
class Solution {
public:
    string reverseWords(string s) 
    {
        stack<string> stk;
        string res, temp;
        istringstream ss(s); // ss与数输入的字符串s绑定
        while (ss >> temp)   // 以空格为分隔符将其分割
        {
            stk.push(temp);
            stk.push(" ");
        }
        if(!stk.empty()) 
            stk.pop();       // 弹出最后压入的那个多余空格
        while (! stk.empty())// 单词翻转后的新串
        {
            res += stk.top();
            stk.pop();
        }
        return res;
    }
};

11. 剑指Offer58-II 左旋转字符串

class Solution {
public:
    string reverseLeftWords(string s, int n) {
        reverse(s.begin(), s.begin() + n);
        reverse(s.begin() + n, s.end());
        reverse(s.begin(), s.end());
        return s;
    }
};


class Solution {
public:
    int reverse_string(string& s, int start, int end) {
        for (int i = start; i <= (start + end) / 2; i++) {
            char temp = s[i];
            s[i] = s[start+end-i];
            s[start+end-i] = temp;
        }
        return 0;
    }

    string reverseLeftWords(string s, int n) {
        int length = s.length();

        reverse_string(s, 0, length-1);
        reverse_string(s, 0, length-n-1);
        reverse_string(s, length-n, length-1);
        
        return s;
    }
};

12. leetcode 28 实现strStr()

//暴力破解
class Solution {
public:
    int strStr(string haystack, string needle) {
        int n = haystack.size(), m = needle.size();
        for (int i = 0; i + m <= n; i++) {
            bool flag = true;
            for (int j = 0; j < m; j++) {
                if (haystack[ i + j] != needle[j]) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                return i;
            }
        }
        return -1;
    }
};

class Solution {
public:
    int strStr(string s, string p) {
        int n = s.size(), m = p.size();
        for(int i = 0; i <= n - m; i++){
            int j = i, k = 0; 
            while(k < m and s[j] == p[k]){
                j++;
                k++;
            }
            if(k == m) return i;
        }
        return -1;
    }
};



//KMP算法
class Solution {
public:
    int strStr(string haystack, string needle) {
        int n = haystack.size(), m = needle.size();
        if(m == 0) return 0;
        //设置哨兵
        haystack.insert(haystack.begin(),' ');
        needle.insert(needle.begin(),' ');
        vector<int> next(m + 1);
        //预处理next数组
        for(int i = 2, j = 0; i <= m; i++){
            while(j and needle[i] != needle[j + 1]) j = next[j];
            if(needle[i] == needle[j + 1]) j++;
            next[i] = j;
        }
        //匹配过程
        for(int i = 1, j = 0; i <= n; i++){
            while(j and haystack[i] != needle[j + 1]) j = next[j];
            if(haystack[i] == needle[j + 1]) j++;
            if(j == m) return i - m;
        }
        return -1;
    }
};

你可能感兴趣的:(leetcode,leetcode,c++)