力扣vip

156.上下翻转二叉树
要求:如图所示看箭头
在这里插入图片描述
思路:迭代递归都行

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution1 {
public:
    TreeNode* upsideDownBinaryTree(TreeNode* root) {
        if (!root || !root->left) {
            return root;
        }

        TreeNode* left = root->left;
        TreeNode* right = root->right;
        TreeNode* flippedLeft = upsideDownBinaryTree(left);
        left->left = right; // turn original right into left
        left->right = root; // turn original root into right
        root->left = nullptr;
        root->right = nullptr;

        return flippedLeft;
    }
};

class Solution {
public:
    TreeNode* upsideDownBinaryTree(TreeNode* root) {
        TreeNode* cur = root;
        TreeNode* pre = nullptr;
        TreeNode* tmp = nullptr;
        while (cur) {
            auto next = cur->left;
            cur->left = tmp; // copy original right to left
            tmp = cur->right; // save next level original right
            cur->right = pre; // copy original root to right
            pre = cur; // save cur root, i.e: next level left
            cur = next;
        }

        return pre;
    }
};

157.用 Read4 读取 N 个字符
要求:read4能读最多4个字符到buf并返回读了几个。实现read调用read4读n个字符,返回实际读了几个,buf够长

/**
 * The read4 API is defined in the parent class Reader4.
 *     int read4(char *buf4);
 */

class Solution {
public:
    /**
     * @param buf Destination buffer
     * @param n   Number of characters to read
     * @return    The number of actual characters read
     */
    int read(char *buf, int n) {
        int res = 0;
        for (int i = 0; i < n; i += 4)
        {
            res += read4(buf);      //指针后移
            buf += 4;
        }

        return min(res, n);
    }
};

158.用 Read4 读取 N 个字符 II
跟上题区别是要多次读取,要把buf存下来

/**
 * The read4 API is defined in the parent class Reader4.
 *     int read4(char *buf4);
 */

class Solution {
public:
    char *buf4 = new char[4];
    int buf4Index = 0;
    int buf4Size = 0;
    int read(char *buf, int n) {
        int index = 0;
        while(index<n){
            while(buf4Index<buf4Size && index<n){
                buf[index++] = buf4[buf4Index++];
            }
            if(index<n){
                buf4Size = read4(buf4);
                buf4Index = 0;
                if(buf4Size==0) break;
            }
        }
        return index;
    }
};

159.至多包含两个不同字符的最长子串
rt,滑动窗口

class Solution {
public:
    int lengthOfLongestSubstringTwoDistinct(string s) {
        if(s.size()<=2)
        return s.size();
        int l=0,r=0,preIndex=-1,maxLength=0;
        while(r<s.size()-1){
            r++;
            if(s[r]==s[r-1])
            maxLength=max(maxLength,r-l+1);
            else if(preIndex==-1 || s[r]==s[preIndex]){
                preIndex=r-1;
                maxLength=max(maxLength,r-l+1);
            }else{
                l=preIndex+1;
                preIndex=r-1;
            }
        }
        return maxLength;
    }
};

161.相隔为 1 的编辑距离
一个字符串由另一个插/换/删1个字符得到,注意这里除了那个字符外两串顺序一样

class Solution {
public:
    bool isOneEditDistance(string s, string t) {
        int ns=s.length(),nt=t.length();
        if(ns>nt)
            return isOneEditDistance(t,s);
        if(nt-ns>1)return 0;
        int replace=0;
        for(int i=0;i<ns;i++){
            if(s[i]!=t[i]){
                if(nt!=ns)
                    return (s.substr(i)==t.substr(i+1));
                else return (i==ns-1)||(s.substr(i+1)==t.substr(i+1));
            }
        }
        return nt!=ns; 
    }
};

163.缺失的区间
输入: nums = [0, 1, 3, 50, 75], lower = 0 和 upper = 99,
输出: [“2”, “4->49”, “51->74”, “76->99”]

class Solution {
public:
    vector<string> findMissingRanges(vector<int>& nums, int lower, int upper) {
        long l = lower;
    	vector<string> ans;
    	for(int i = 0; i < nums.size(); ++i)
    	{
    		if(l == nums[i])
    			l++;//相等,我跳过你
    		else if(l < nums[i])
    		{	//有空缺
    			if(l < nums[i]-1)//大于1
    				ans.push_back(to_string(l)+"->"+to_string(nums[i]-1));
    			else if(l == nums[i]-1)//等于1
    				ans.push_back(to_string(l));
    			l = long(nums[i])+1;//更新l到nums[i]下一个数
                // [2147483647]
                // 0
                // 2147483647
    		}
    	}
    	if(l < upper)
    		ans.push_back(to_string(l)+"->"+to_string(upper));
    	else if(l==upper)
    		ans.push_back(to_string(l));
    	return ans;
    }
};

170.两数之和 III - 数据结构设计
存数并判断是否有两数之和为target,要用哈希存频数

class TwoSum 
{
public:
    unordered_map<long long,int> dic;

    /** Initialize your data structure here. */
    TwoSum() 
    {

    }
    
    /** Add the number to an internal data structure.. */
    void add(int number) 
    {
        if (dic.count(number) != 0)
            dic[number] ++;
        else
            dic[number] = 1;
    }
    
    /** Find if there exists any pair of numbers which sum is equal to the value. */
    bool find(int value) 
    {
        for (auto [x, freq]: dic)
        {
            long long y = (long long)value - x;
            if (x == y)
            {
                if (dic[x] >= 2)
                    return true;
            }
            else
            {
                if (dic.count(y) != 0)
                {
                    return true;
                }
            }
        }
        return false;
    }
};

/**
 * Your TwoSum object will be instantiated and called as such:
 * TwoSum* obj = new TwoSum();
 * obj->add(number);
 * bool param_2 = obj->find(value);
 */

186.翻转字符串里的单词 II
输入: [“t”,“h”,“e”," “,“s”,“k”,“y”,” “,“i”,“s”,” “,“b”,“l”,“u”,“e”]
输出: [“b”,“l”,“u”,“e”,” “,“i”,“s”,” “,“s”,“k”,“y”,” ",“t”,“h”,“e”]

class Solution {
public:
    void reverseWords(vector<char>& s) {
        int left = 0;
        int right = 0;
        int len = s.size();
        while (right < len) {
            if (s[right] == ' ') {
                Swap(s, left, right - 1);
                right++;
                left = right;
            } else {
                right++;
            }
        }
        Swap(s, left, len - 1);
        Swap(s, 0, len - 1);
    }
    void Swap(vector<char>& s, int left, int right) {
        char temp;
        while (left < right) {
            temp = s[left];
            s[left] = s[right];
            s[right] = temp;
            left++;
            right--;
        }
    }
};

253.会议室 II
给你一个会议时间安排的数组 intervals ,每个会议时间都会包括开始和结束的时间 intervals[i] = [starti, endi] ,返回 所需会议室的最小数量 。就是最多的重叠的区间个数。优先队列最大size,或者模拟开会时间加1结束减1取最大值

class Solution{
public:
    int minMeetingRooms(vector<vector<int>>& intervals){
        int N=intervals.size();
        sort(intervals.begin(),intervals.end());
        priority_queue<int,vector<int>,greater<int>>que;
        que.push(intervals[0][1]);
        int res=1;
        for(int i=1;i<N;i++){
            if(intervals[i][0]>=que.top()){
                que.pop();
                que.push(intervals[i][1]);
            }
            else{
                que.push(intervals[i][1]);
            }
            int T=que.size();
            res=max(res,T);
        }
        return res;
    }
};
class Solution {    // 排序+遍历
public:
    struct cmp {    // 排序优先级:会议时间升序 > 相等时间先结束后开始
        bool operator()( const pair<int, int> & p1, const pair<int, int> & p2 ) {
            if (p1.first == p2.first)   return p1.second < p2.second;   // 会议时间相同,先结束后开始
            return p1.first < p2.first;     // 按会议时间升序排序
        }
    };
    int minMeetingRooms(vector<vector<int>>& intervals) {
        int n = intervals.size();
        if (n < 2) return n;
        vector<pair<int, int>>  times;
        for (auto & inter : intervals) {
            times.emplace_back( make_pair(inter[0], 1) );   // 会议开始,会议室+1
            times.emplace_back( make_pair(inter[1], -1) );  // 会议结束,会议室-1
        }
        sort(times.begin(), times.end(), cmp());            // 排序
        int works = 0, ans = 1;                             
        for (auto & t : times) {
            works += t.second;                              // 此时开会的会议室数量
            ans = max(ans, works);                          // 记录最多数量
        }
        return ans;
    }
};

251.展开二维向量
二维vector一个个值输出。y是记录某个一维vector里访问到第几个了

// In the following x is a pointer to pointer, *x is an pointer to array v[i] above
class Vector2D {
public:
    Vector2D(vector<vector<int>>& vec) {
        x = vec.begin();
        end = vec.end();
    }
    
    void moveToNext() {
        while (x != end && y == (*x).size()) {
            x++;
            y = 0;
        }
    }

    int next() {
        moveToNext();
        return (*x)[y++];
    }
    
    bool hasNext() {
       moveToNext();
       return x != end && y < (*x).size();
    }

private:
    int y = 0;
    vector<vector<int>>::iterator x;
    vector<vector<int>>::iterator end;
};

/**
 * Your Vector2D object will be instantiated and called as such:
 * Vector2D* obj = new Vector2D(vec);
 * int param_1 = obj->next();
 * bool param_2 = obj->hasNext();
 */

269.火星词典
字符串数组按新的字符大小规则排序了,如果合理的话输出字符大小顺序
可以根据单词按字符建图拓扑排序看是否有环

class Solution {
public:
    const int VISITING = 1, VISITED = 2;
    unordered_map<char, vector<char>> edges;
    unordered_map<char, int> states;
    bool valid = true;
    string order;
    int index;
    string alienOrder(vector<string>& words) {
        int length = words.size();
        for (string & word : words) {
            int wordLength = word.size();
            for (int j = 0; j < wordLength; j++) {
                char c = word[j];
                if (!edges.count(c)) {
                    edges[c] = vector<char>();
                }
            }
        }
        for (int i = 1; i < length && valid; i++) {
            addEdge(words[i - 1], words[i]);
        }
        order = string(edges.size(), ' ');
        index = edges.size() - 1;
        for (auto [u, _] : edges) {
            if (!states.count(u)) {
                dfs(u);
            }
        }
        if (!valid) {
            return "";
        }
        return order;
    }
    void addEdge(string before, string after) {
        int length1 = before.size(), length2 = after.size();
        int length = min(length1, length2);
        int index = 0;
        while (index < length) {
            char c1 = before[index], c2 = after[index];
            if (c1 != c2) {
                edges[c1].emplace_back(c2);
                break;
            }
            index++;
        }
        if (index == length && length1 > length2) {
            valid = false;
        }
    }
    void dfs(char u) {
        states[u] = VISITING;
        for (char v : edges[u]) {
            if (!states.count(v)) {
                dfs(v);
                if (!valid) {
                    return;
                }
            } else if (states[v] == VISITING) {
                valid = false;
                return;
            }
        }
        states[u] = VISITED;
        order[index] = u;
        index--;
    }
};
class Solution {
public:
    unordered_map<char, vector<char>> edges;
    unordered_map<char, int> indegrees;
    bool valid = true;
    string alienOrder(vector<string>& words) {
        int length = words.size();
        for (auto word : words) {
            int wordLength = word.size();
            for (int j = 0; j < wordLength; j++) {
                char c = word[j];
                if (!edges.count(c)) {
                    edges[c] = vector<char>();
                }
            }
        }
        for (int i = 1; i < length && valid; i++) {
            addEdge(words[i - 1], words[i]);
        }
        if (!valid) {
            return "";
        }
        queue<char> qu;
        for (auto [u, _] : edges) {
            if (!indegrees.count(u)) {
                qu.emplace(u);
            }
        }
        string order;
        while (!qu.empty()) {
            char u = qu.front();
            qu.pop();
            order.push_back(u);
            for (char v : edges[u]) {
                indegrees[v]--;
                if (indegrees[v] == 0) {
                    qu.emplace(v);
                }
            }
        }
        return order.size() == edges.size() ? order : "";
    }
    void addEdge(string before, string after) {
        int length1 = before.size(), length2 = after.size();
        int length = min(length1, length2);
        int index = 0;
        while (index < length) {
            char c1 = before[index], c2 = after[index];
            if (c1 != c2) {
                edges[c1].emplace_back(c2);
                indegrees[c2] += 1;
                break;
            }
            index++;
        }
        if (index == length && length1 > length2) {
            valid = false;
        }
    }
};

277.搜寻名人
名人定义是其他人都认识他但他不认识其他人,编号是0-n-1,可以调用knows函数获取a是否认识b。如果 knows(i,j) 为ture,说明i不可能是名人。如果 knows(i,j) 为false, 说明j不可能是名人。也就说说任意两人相互比较总能淘汰一个人。

/* The knows API is defined for you.
      bool knows(int a, int b); */

// Forward declaration of the knows API.

class Solution {
public:
    int findCelebrity(int n) {
        int result = 0;
        for (int i = 1; i < n; ++i) {
            if (knows(result, i)) {
                result = i;
            }
        }
        for (int i = 0; i < n; ++i) {//检查是否符合名人条件
            if (result == i) continue;
            if (knows(result, i) || !knows(i, result)) return -1;
        }
        return result;
    }
};

285.二叉搜索树中的中序后继

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
        TreeNode* ans=nullptr;
        // 若p有右子树,右子树最左的叶子结点为p的后续结点
        if(p->right){
            ans=p->right;
            while(ans->left)
                ans=ans->left;
        }
        // 若p没有右子树,考虑二叉搜索树的性质
        else{
            // @@ 从根结点到p结点的路径中,比p大的、最靠近p的结点即为p的后序结点 @@
            TreeNode *cur=root;
            while(cur!=p){
                if(cur->val>p->val){
                    ans=cur; // 不断记录最新的比p大的结点
                    cur=cur->left;
                }
                else
                    cur=cur->right;
            }
        }
        return ans;
    }
};

308.二维区域和检索 - 可变
矩阵求一块的和,用每一行的前缀和做

class NumMatrix
{
public:
    int b[404][404];
    vector<vector<int>> a;
    int n, m;
    NumMatrix(vector<vector<int>> &a) : a(a)
    {
        n = a.size(), m = a[0].size();
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= m; ++j)
            {
                b[i][j] = b[i][j - 1] + a[i - 1][j - 1];
            }
    }

    void update(int l, int r, int v)
    {
        a[l][r] = v;
        for (int j = r + 1; j <= m; ++j)
            b[l + 1][j] = b[l + 1][j - 1] + a[l][j - 1];
    }

    int sumRegion(int x, int y, int l, int r)
    {
        int sum = 0;
        for (int i = x + 1; i <= l + 1; ++i)
        {
            sum += b[i][r + 1] - b[i][y];
        }
        return sum;
    }
};

/**
 * Your NumMatrix object will be instantiated and called as such:
 * NumMatrix* obj = new NumMatrix(matrix);
 * obj->update(row,col,val);
 * int param_2 = obj->sumRegion(row1,col1,row2,col2);
 */

340.至多包含 K 个不同字符的最长子串
哈希表,滑动窗口

class Solution {
public:
    int lengthOfLongestSubstringKDistinct(string s, int k) {
        unordered_map<char,int> map;
        if(k==0){return 0;}
        int n = s.size();
        int ans =0;
        for(int l=0,r=0;r<n;r++){
            map[s[r]]++;
            while(map.size()>k){
                map[s[l]]--;
                if(map[s[l]]==0){map.erase(s[l]);}
                l++;
            }
            ans = max(ans,r-l+1);
        }
        return ans;
    }
};

348.设计井字棋

class TicTacToe {
    vector<int> r, c, q;
    int n;
public: 
    TicTacToe(int n) : r(n), c(n), q(2), n(n){}

    int move(int row, int col, int player) {
        if(player == 1 && (++r[row] == n || ++c[col] == n || row == col && ++q[0] == n || row + col == n - 1 && ++q[1] == n) ||
        player == 2 && (--r[row] == -n || --c[col] == -n || row == col && --q[0] == -n || row + col == n - 1 && --q[1] == -n)) return player;
        return 0;
    }
};

/**
 * Your TicTacToe object will be instantiated and called as such:
 * TicTacToe* obj = new TicTacToe(n);
 * int param_1 = obj->move(row,col,player);
 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值