《高级数据结构》-leetcode刷题课

刷题建议

《高级数据结构》课程结束了,leetcode才是算法人员的第二春(坚持刷题,坚持数据结构与算法思维》,至少坚持每天一个题目

  1. leetcode的简单题一般锻炼代码能力
  2. leetcode的难题目一般锻炼数据结构与算法思维

8:字符串转整型

// 代码核心:越界处理,pre_max和d
class Solution {
public:
    int myAtoi(string s) {
        int ind = 0, num = 0, flag = 1;
        int pre_max = INT_MAX / 10; // 整型能表示的最大值前面部分 -> 越界判断
        int d = INT_MAX % 10;
        // 去除前置空格
        while (ind < s.size() && s[ind] == ' ') ++ ind;
        // 正负数判断
        if (s[ind] == '+') flag = 1, ++ind;
        else if (s[ind] == '-') flag = -1, ++ind;
        while (ind < s.size()) {
            // 数字是否合理
            if (s[ind] < '0' || s[ind] > '9') break;
            // num需要判断是否越界
            if (num > pre_max || (num == pre_max && s[ind] - '0' > d)) {
                if (flag == -1) return INT_MIN;
                return INT_MAX;
            }
            num = num * 10 + (s[ind] - '0');
            ++ind;
        }
        return num * flag;
    }
};

13:罗马数字转整数

class Solution {
public:
    int getValue(char ch) {
        switch(ch) {
            case 'I' : return 1;
            case 'V' : return 5;
            case 'X' : return 10;
            case 'L' : return 50;
            case 'C' : return 100;
            case 'D' : return 500;
            case 'M' : return 1000;
        }
        return 0;
    }

    int romanToInt(string s) {
        int num = 0;
        for (int i = 0; s[i]; i++) {
            // 位权
            num += getValue(s[i]);
            // ? 位权判断
            if (i && getValue(s[i]) > getValue(s[i -1])) {
                num -= 2 * getValue(s[i - 1]); // 2倍
            }
        }
        return num;
    }
};

14:最长公共前缀

class Solution {
public:
    string Compare(string &a, string &b) {
        string ret = "";
        for (int i = 0; a[i]; i++) {
            if (i == b.size()) return ret;
            if (a[i] != b[i]) return ret;
            ret += a[i];
        }
        return ret;
    }

    string longestCommonPrefix(vector<string>& strs) {
        string ret = strs[0];
        for (int i = 1; i < strs.size(); i++) {
            ret = Compare(ret, strs[i]);
        }
        return ret;
    }
};

28:strSTR()

利用sunday算法实现单模匹配

// 单模匹配问题:kmp,sunday,kmp,shift-and,暴力,怎么进行算法选择
// 用sunday实现
class Solution {
public:
    // needle 模式串
    int strStr(string haystack, string needle) {
        int ind[128]; // 每种字符出现在倒数多少位
        for (int i = 0; i < 128; i++)  ind[i] = needle.size();
        // 扫描模式串的每一位   
        for (int i = 0; needle[i]; i++) ind[needle[i]] = needle.size() - i; 
        // 设置匹配变量 i
        int i = 0;
        // 匹配操作
        while (i + needle.size() <= haystack.size()) {
            int flag = 1; // 匹配成功
            // j
            for (int j = 0; needle[j]; j++) {
                if (haystack[i + j] == needle[j]) continue;
                flag = 0; // 匹配不成功
                break;
            }
            // 结果判断
            if (flag) return i; // 完美匹配
            i += ind[haystack[i +needle.size()]]; // 向后调整i指针位置;黄金对齐点位置
        }
        return -1; // 在文本串中找不到模式串
    }
};
  • 尝试用shift-and解决该问题
    – 问题:超INT怎么办? -> 模拟一个数据类型;bitset;高精度思想;二进制位标记

36:有效的数独

// 核心1:二进制标记法
class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        int x[9] = {0}, y[9] = {0}, z[9] = {0}; //
        for (int i = 0; i < board.size(); i++) {
            for (int j = 0; j < 9; j++) {
                if (board[i][j] == '.') continue;
                int d = board[i][j] - '0';
                // 出现过则直接 return flase;
                if (x[i] & (1 << d)) return false;
                if (y[j] & (1 << d)) return false;
                // 核心2: 宫格编号 0-8
                if (z[i / 3 * 3 + j / 3] & (1 << d)) return false; //
                x[i] |= (1 << d);
                y[j] |= (1 << d);
                z[i / 3 * 3 + j / 3] |= (1 << d);
            }
        }
        return true;
    }
};

58:最后一个单词的长度

class Solution {
public:
    int lengthOfLastWord(string s) {
        // 从后往前找
        int p1 = s.size() - 1, p2; 
        while (p1 >= 0 && s[p1] == ' ') --p1; // p1:最后一个字母
        p2 = p1; // p2最后一个单词的首字母前一位
        while (p2 >= 0 && s[p2] != ' ') --p2;
        return p1 - p2;
    }
};

125:验证回文串

class Solution {
public:
    bool is_alpha(char ch) {
        return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
    }
    bool is_digit(char ch) {
        return ch <= '9' && ch >= '0';
    }

    bool isPalindrome(string s) {
        int l = 0, r = s.size() - 1;
        while (l < r) {
            while (l < r && !(is_alpha(s[l]) || is_digit(s[l]))) ++l;
            while (l < r && !(is_alpha(s[r]) || is_digit(s[r]))) --r;
            // 技巧:大写变成小写
            if (s[l] <= 'Z' && s[l] >= 'A') s[l] += 32;  
            if (s[r]<= 'Z' && s[r] >= 'A') s[r] += 32;    
            if (s[l] - s[r]) return false;
            ++l, --r;
        }
        return true;
    }
};

165:比较版本号

// 简单的题目锻炼的是 编码能力,难的题一般都是算法能力
// 技巧点:1.01 vs 1.0 -> 101 vs 100
class Solution {
public:
    void getValue(string &s, int &i, int &val) {
        val = 0;
        while (s[i] && s[i] != '.') val = val * 10 + (s[i++] - '0');
        if (s[i]) ++i;
        return ;

    }

    int compareVersion(string version1, string version2) {
        int i = 0, j = 0; // 位数
        int val1, val2; // 作为传出参数:除去 '.'
        while (version1[i] || version2[j]) {
            getValue(version1, i, val1);
            getValue(version2, j, val2);
            if (val1 - val2) return (val1 < val2 ? - 1 : 1);
        }
        return 0;
    }
};

205:同构字符串

// 记录两种映射:s->t t->s, 保证一一对应
class Solution {
public:
    bool isIsomorphic(string s, string t) {
        if (s.size() - t.size()) return false;
        int st[128] = {0}, ts[128] = {0}; // 映射数组
        for (int i = 0; s[i]; i++) {
            //s->t 的映射建立
            if (st[s[i]] == 0) st[s[i]] = t[i]; //建立映射
            else if (t[i] - st[s[i]]) return false; //出现冲突
            // t->s 的映射建立
            if (ts[t[i]] == 0) ts[t[i]] = s[i];
            else if (s[i] - ts[t[i]]) return false;
        }
        return true;
    }
};

242:有效的字母异构词

// 字母组成一样,但是组成一样 -> 计数排序(字母出现的次数)
class Solution {
public:
    bool isAnagram(string s, string t) {
        if (s.size() - t.size()) return false;
        int cnt[128] = {0};
        for (int i = 0; s[i]; i++) cnt[s[i]] += 1;
        for (int i = 0; t[i]; i++) {
            cnt[t[i]] -= 1;
            if (cnt[t[i]] == -1) return false;
        }
        return true;
    }
};

290:单词规律

// 与单词同构词是一样的,都是映射关系的处理 ?
class Solution {
public:
    void getNextWord(string &s, int &j, string &t) {
        t = ""; // 清空t串
        while (s[j] && s[j] == ' ') ++j; // 吞掉空格
        while (s[j] && s[j] != ' ') t += s[j++]; // 提取下一个单词 
        return ;
    }

    bool wordPattern(string p, string s) {
 
        string ps[128]; // 存储p->s的映射
        unordered_map<string, char> sp;//hash:存储p->s的映射
        string t;
        int j = 0;
        // 扫描pattern的每一位
        for (int i = 0; p[i]; i++) {
            getNextWord(s, j, t); // t获得s的下一个单词
            if (t == "" ) return false; // s和p串长度不同
            // 之前没有映射,创建映射
            if (ps[p[i]] == "") ps[p[i]] = t; 
            else if (ps[p[i]] != t) return false; // 之前映射与现在不是一对 
            // 同上
            if (sp.find(t) == sp.end()) sp[t] = p[i];
            else if (sp[t] != p[i]) return false;       
        }
        if (j != s.size()) return false; 
        // s串应该要处理到最后一位
        return true;
    }
};

344:反转字符串

class Solution {
public:
    void reverseString(vector<char>& s) {
        // 设置头尾两个指针,一起往中间走(翻转字符串,翻转数组)
        for (int i = 0, j = s.size() - 1; i < j; i++, j--) {
            swap(s[i], s[j]);
        }
        return ;
    }
};

345:反转字符串的元音字母

class Solution {
public:
    bool is_valid(char ch) {
        if (ch < 97) ch += 32;
        switch (ch) {
            case 'a' :
            case 'e' :
            case 'i' :
            case 'u' :
            case 'o' : return true;
        }
        return false;
    }
    string reverseVowels(string s) {
        for (int i = 0, j = s.size() - 1; i < j; i++, j--) {
            // ?
            while (i < j && !is_valid(s[i])) ++i;
            while (i < j && !is_valid(s[j])) --j;
            swap(s[i], s[j]);
        }
        return s;
    }
};

383:赎金信

//  异位字符串
class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        int cnt[128] = {0};
        for (int i = 0; magazine[i]; i++)  cnt[magazine[i]] += 1;
        for (int i = 0; ransomNote[i]; i++) {
            cnt[ransomNote[i]] -= 1;
            if (cnt[ransomNote[i]] == -1) return false;
        }
        return true;
    }
};
  • 练习题:leetcode387
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值