ACM模式完整代码训练

最近开始参加笔试发现自己极其高分低能,由于长期使用python导致c++代码遗忘严重再加上常年刷LeetCode,甚至输入输出都写不出来,要加强自我训练。

8.30.LeetCode21合并两个有序链表

完整代码如下:

#include <iostream>
#include <vector>
using namespace std;
struct ListNode
{
	int val;
	ListNode* next;
	ListNode():val(0),next(nullptr){}
	ListNode(int x):val(x),next(nullptr){}
	ListNode(int x,ListNode *next):val(x),next(next){}
};
ListNode* constructList(vector<int> nodes)
{
    ListNode* dummyHead = new ListNode();
    ListNode* cur = dummyHead;
    for (auto i : nodes)
    {
        cur->next = new ListNode(i);
        cur = cur->next;
    }
    cur = dummyHead->next;
    delete dummyHead;
    return cur;
}
void printList(ListNode* head)
{
    ListNode* cur = head;
    if (cur == NULL)
    {
        cout << "[]" << endl;
    }
    while (cur != NULL)
    {
        cout << cur->val << ' ';
        cur = cur->next;
    }
}
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2){
    if (l1 == nullptr) {
        return l2;
    } else if (l2 == nullptr) {
        return l1;
    } else if (l1->val < l2->val) {
        l1->next = mergeTwoLists(l1->next, l2);
        return l1;
    } else {
        l2->next = mergeTwoLists(l1, l2->next);
        return l2;
    }
}
int main(){
	vector<int>a1;
	int num1,num2;
	while(cin >> num1){
		a1.push_back(num1);
		if(cin.get() == '\n')
			break;
	}
	vector<int>a2;
	while(cin >> num2){
		a2.push_back(num2);
		if(cin.get() == '\n')
			break;
	}
	ListNode* l1 = constructList(a1);
	ListNode* l2 = constructList(a2);
	ListNode* result = mergeTwoLists(l1,l2);
	printList(result);
}	

8.31.LeetCode144二叉树的前序遍历

完整代码如下(还有些问题后续会解决):

#include<iostream>
#include<vector>
#include<stack>
#include<stdlib.h>
#include<algorithm>
using namespace std;
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) {}
};
TreeNode* construct_binary_tree(const vector<int>& vec){
    vector<TreeNode*>vecTree(vec.size(),NULL);
    TreeNode* root = NULL;
    for(int i = 0;i < vec.size();i++){
        TreeNode* node = NULL;
        if(vec[i] != -1) node = new TreeNode(vec[i]);
        vecTree[i] = node;
        if(i == 0)root = node;
    }
    for(int i = 0;i * 2 + 2 < vec.size();i++){
        if(vecTree[i] != NULL){
            vecTree[i] -> left = vecTree[i * 2 + 1];
            vecTree[i] -> right = vecTree[i * 2 + 2];
        }
    }
    return root;
}
void traversal(TreeNode* node, vector <int> &vec){
    if(node != nullptr){
        printf("%d\n",node -> val);
        vec.push_back(node -> val);
        traversal(node -> left,vec);
        traversal(node -> right,vec);
    }
}
vector<int> preorderTraversal(TreeNode* root) {
    vector<int> res;
    traversal(root,res);
    return res;
}
int main(){
  vector<int>vec;
  int num;
  while(cin >> num){
    vec.push_back(num);
    if(cin.get() == '\n')
    break;
    }   
    TreeNode* root = construct_binary_tree(vec);
    preorderTraversal(root);
    system("pause");
}

9.1.LeetCode1475.商品折扣后的最终价格&&LeetCode59.螺旋矩阵Ⅱ

代码如下:

#include<iostream>
#include<vector>
#include<stdlib.h>
using namespace std;
vector<int>finalprices(vector<int>&prices){
        for(int i = 0;i < prices.size();i++){
        for(int j = i + 1;j < prices.size();j++){
            if(prices[j] <= prices[i]){
                prices[i] -= prices[j];
                break;
            }
        }
    }
    return prices;
}
int main(){
    vector<int>prices;
    int num;
    while(cin >> num){
        prices.push_back(num);
        if(cin.get() == '\n')
            break;
    }
    vector<int>newprices = finalprices(prices);
    for(int i = 0;i < newprices.size();i++){
        cout << newprices[i] << ",";
    }
    cout << endl;
    system("pause");
}

LeetCode59.螺旋矩阵Ⅱ(参考代码随想录,carl哥yyds)
完整代码如下:

#include<iostream>
#include<vector>
#include<stdlib.h>
using namespace std;
vector<vector<int>>generateMatrix(int n){
    vector<vector<int>> res(n,vector<int>(n,0));
    int startx = 0,starty = 0;
    int loop = n / 2;
    int mid = n/ 2;
    int count = 1;
    int offset = 1;
    int i,j;
    while(loop--){
        i = startx;
        j = starty;
    
    for(j = starty;j < starty + n - offset;j++){
        res[startx][j] = count++;
    }
    for(i = startx;i < startx + n - offset;i++){
        res[i][j] = count++;
    }
    for(;j > starty;j--){
        res[i][j] = count++;
    }
    for(;i > startx;i--){
        res[i][j] = count++;
    }
    startx++;
    starty++;
    offset += 2;
    }
    if(n % 2){
        res[mid][mid] = count;
    }
    return res;
}
int main(){
    int n;
    cin >> n;
    vector<vector<int>>res = generateMatrix(n);
    cout << "[";
    for(int i = 0;i < res.size();i++){
        cout << "[";
        for(int j = 0;j < res[0].size();j++){
            cout << res[i][j];
            if(j != res[0].size() - 1)
                cout << ",";
        }
        cout << "]" << ",";
    }
    cout << "]" << endl;
    system("pause");
}

9.2.LeetCode687.最长同值路径&&LeetCode226翻转二叉树

代码如下:

#include <iostream>
#include<vector>
#include<stdlib.h>
using namespace std;
int res;
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){}
};
TreeNode* construct_binary_tree(const vector<int>&vec){
    vector<TreeNode*>vecTree(vec.size(),NULL);
    TreeNode* root = NULL;
    for(int i = 0;i < vec.size();i++){
        TreeNode* node = NULL;
        if(vec[i] != -1)node = new TreeNode(vec[i]);
        vecTree[i] = node;
        if(i == 0)root = node;
    }
    for(int i = 0;i * 2 + 2 < vec.size();i++){
        if(vecTree[i] != NULL){
            vecTree[i] -> left = vecTree[i * 2 + 1];
            vecTree[i] -> right = vecTree[i * 2 + 2];
        }
    }
    return root;
}
int dfs(TreeNode *root){
    if(root == nullptr){
        return 0;
    }
    int left = dfs(root -> left),right = dfs(root -> right);
    int left1 = 0,right1 = 0;
    if(root -> left && root -> left -> val == root -> val){
        left1 = left + 1;
    }
    if(root -> right && root -> right -> val == root -> val){
        right1 = right + 1;
    }
    res = max(res,left1 + right1);
    return max(left1,right1);
}
int longestUnivaluePath(TreeNode* root) {
        res = 0;
        dfs(root);
        return res;
}
int main(){
    vector<int>vec;
    int num;
    while(cin >> num){
	vec.push_back(num);
	if(cin.get() == '\n')
	    break;
    }   
    TreeNode* root = construct_binary_tree(vec);
    longestUnivaluePath(root);
    cout << res << endl;
    system("pause");
}

LeetCode226翻转二叉树
代码如下:

#include<iostream>
#include<vector>
#include<stack>
#include<queue>
#include<stdlib.h>
using namespace std;
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){}
};
TreeNode* construct_binary_tree(const vector<int>& vec){
    vector<TreeNode*>vecTree(vec.size(),NULL);
    TreeNode* root = NULL;
    for(int i = 0;i < vec.size();i++){
        TreeNode* node = NULL;
        if(vec[i] != -1)node = new TreeNode(vec[i]);
        vecTree[i] = node;
        if(i == 0) root = node;
    }
    for(int i = 0;i * 2 + 2 < vec.size();i++){
        if(vecTree[i] != NULL){
            vecTree[i] -> left = vecTree[i * 2 + 1];
            vecTree[i] -> right = vecTree[i * 2 + 2];
        }
    }
    return root;
}
void print_binary_tree(TreeNode* root){
    queue<TreeNode*>que;
    if(root != NULL)que.push(root);
    vector<int>result;
    while(!que.empty()){
        int size = que.size();
        // vector<int>vec;
        for(int i = 0;i < size;i++){
            TreeNode* node = que.front();
            que.pop();
            if(node != NULL){
                result.push_back(node -> val);
                que.push(node -> left);
                que.push(node ->right);
            }
        }
    }
    cout << "[";
    for(int i = 0;i < result.size();i++){
        cout << result[i];
        if(i != result.size() - 1){
            cout << ",";
        }
    }
    cout << "]" << endl;
}
TreeNode* invertTree(TreeNode* root){
    if(root == NULL)return root;
    stack<TreeNode*>st;
    st.push(root);
    while(!st.empty()){
        TreeNode* node = st.top();
        st.pop();
        swap(node -> left,node -> right);
        if(node -> right)st.push(node -> right);
        if(node -> left)st.push(node -> left);
    }
    return root;
}
int main(){
    vector<int>vec;
	int num;
	while(cin >> num){
		vec.push_back(num);
		if(cin.get() == '\n')
			break;
	}   
    TreeNode* root = construct_binary_tree(vec);
    invertTree(root);
    print_binary_tree(root);
    system("pause");
}

9.3.LeetCode646.最长数对链

代码如下,两个函数分别代表动态规划和贪心算法

#include<iostream>
#include<vector>
#include<algorithm>
#include<stdlib.h>
using namespace std;
int findLongestChain(vector<vector<int>>& pairs) {
    int n = pairs.size();
    sort(pairs.begin(),pairs.end());
    vector<int>dp(n,1);
    for(int i = 0;i < n;i++){
        for(int j = 0;j < i;j++){
            if(pairs[j][1] < pairs[i][0]){
                dp[i] = max(dp[i],dp[j] + 1);
            }
        }
    }
    return dp[n - 1];
}
int findLongestChain(vector<vector<int>>& pairs) {
    int curr = INT_MIN,res = 0;
    sort(pairs.begin(),pairs.end(),[](const vector<int>&a,const vector<int>&b){
        return a[1] < b[1];
    });
    for(auto &p:pairs){
        if(curr < p[0]){
            curr = p[1];
            res++;
        }
    }
    return res;
}
int main(){
    vector<vector<int>>vec;
    vector<int>i1 = {1,2};
    vector<int>i2 = {2,3};
    vector<int>i3 = {3,4};
    vec.push_back(i1);
    vec.push_back(i2);
    vec.push_back(i3);
    int res = findLongestChain(vec);
    cout << res << endl;
    system("pause");
}

9.5.LeetCode156.上下翻转二叉树

代码如下:

#include<iostream>
#include<vector>
#include<stack>
#include<stdlib.h>
#include<queue>
#include<algorithm>
using namespace std;
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) {}
};
TreeNode* construct_binary_tree(const vector<int>& vec){
    vector<TreeNode*>vecTree(vec.size(),NULL);
    TreeNode* root = NULL;
    for(int i = 0;i < vec.size();i++){
        TreeNode* node = NULL;
        if(vec[i] != -1) node = new TreeNode(vec[i]);
        vecTree[i] = node;
        if(i == 0)root = node;
    }
    for(int i = 0;i * 2 + 2 < vec.size();i++){
        if(vecTree[i] != NULL){
            vecTree[i] -> left = vecTree[i * 2 + 1];
            vecTree[i] -> right = vecTree[i * 2 + 2];
        }
    }
    return root;
}
void print_binary_tree(TreeNode* root){
    queue<TreeNode*>que;
    if(root != NULL)que.push(root);
    vector<int>result;
    while(!que.empty()){
        int size = que.size();
        for(int i = 0;i < size;i++){
            TreeNode* node = que.front();
            que.pop();
            if(node != NULL){
                result.push_back(node -> val);
                que.push(node -> left);
                que.push(node ->right);
            }
        }
    }
    cout << "[";
    for(int i = 0;i < result.size();i++){
        cout << result[i];
        if(i != result.size() - 1){
            cout << ",";
        }
    }
    cout << "]" << endl;
}
TreeNode* upsideDownBinaryTree(TreeNode* root){
    if(!root || !root -> left)
        return root;
    TreeNode* l = root -> left;
    TreeNode* r = root -> right;
    root -> left = NULL;
    root -> right = NULL;
    TreeNode* p = upsideDownBinaryTree(l);
    l -> left = r;
    l -> right = root;
    return p;
}
int main(){
	vector<int>vec;
	int num;
	while(cin >> num){
		vec.push_back(num);
		if(cin.get() == '\n')
			break;
	}   
    TreeNode* root = construct_binary_tree(vec);
    print_binary_tree(upsideDownBinaryTree(root));
    system("pause");
}

9.6.LeetCode254.因子的组合

完整代码如下:

#include<iostream>
#include<vector>
#include<stdlib.h>
using namespace std;
void helper(int n,int start,vector<int>out,vector<vector<int>>&res){
    if(n == 1){
        if(out.size() > 1)res.push_back(out);
        return;
    }
    for(int i = start;i <= n;i++){
        if(n % i != 0)
            continue;
        out.push_back(i);
        helper(n / i,i,out,res);
        out.pop_back();
    }
}
vector<vector<int>>getFactors(int n){
    vector<vector<int>>res;
    helper(n,2,{},res);
    return res;
}
int main(){
    int a;
    cin >> a;
    vector<vector<int>>res = getFactors(a);
    cout << "[" << endl;
    for(int i = 0;i < res.size();i++){
        cout << "[";
        for(int j = 0;j < res[i].size();j++){
            cout << res[i][j];
            if(j != res[i].size() - 1)
                cout << ",";
        }
        cout << "]";
        if(i != res.size() - 1)
            cout << ",";
        cout << endl;
    }
    cout << "]" << endl;
    system("pause");
}

9.8 LeetCode163.缺失的区间

完整代码如下:

#include<iostream>
#include<vector>
#include<string>
#include<stdlib.h>
using namespace std;
vector<string>ans;
string miss(int low,int up){
    string left = to_string(low);
    string right;
    if(up > low){
        right = "->" + to_string(up);
    }
    return left + right;
}
vector<string>findmissingranges(vector<int>& nums,int lower,int upper){
    for(int curr:nums){
        if(curr > lower){
            ans.push_back(miss(lower,curr - 1));
            lower = curr + 1;
        }else if(curr == lower){
            lower = curr + 1;
        }
        if(curr == upper){
            return ans;
        }
    }
    if(lower <= upper){
        ans.push_back(miss(lower,upper));
    }
    return ans;
}
int main(){
    vector<int> vec;
    int num;
    while(cin >> num){
        vec.push_back(num);
        if(cin.get() == '\n')
			break;
    }
    int l,u;
    cin >> l;
    cin >> u;
    findmissingranges(vec,l,u);
    cout << "[";
    for(int i = 0;i < ans.size();i++){
        cout << '"' << ans[i] << '"';
        if(i != ans.size() - 1)
            cout << ",";
    }
    cout << "]" << endl;
    system("pause");
}

9.9 LeetCode348.判定井字棋胜负

完整代码如下

#include<iostream>
#include<vector>
#include<stdlib.h>
using namespace std;
class TicTacToe{
    vector<vector<int>>R;
    vector<vector<int>>C;
    vector<int>X45;
    vector<int>X135;
    int N;

public:
    TicTacToe(int n){
        N = n;
        R = vector<vector<int>>(2,vector<int>(n,0));
        C = vector<vector<int>>(2,vector<int>(n,0));
        X45 = vector<int>(2,0);
        X135 = vector<int>(2,0);
    }
    int move(int row,int col,int player){
        if(row == col)
            X45[player - 1]++;
        if(row + col == N - 1)
            X135[player - 1]++;
        R[player - 1][row]++;
        C[player - 1][col]++;
        if(R[player - 1][row] == N || C[player - 1][col] == N
            || X45[player - 1] == N || X135[player - 1] == N)
            cout << player << endl;
            return player;
        return 0;
    }
};


int main(){
    TicTacToe toe(3);
    toe.move(0,0,1);
    toe.move(0,2,2);
    toe.move(2,2,1);
    toe.move(1,1,2);
    toe.move(2,0,1);
    toe.move(1,0,2);
    toe.move(2,1,1);
}

9.10Redbook编程题练习

给大臣排序
在遥远的国度有一位国王,他每天的工作都十分繁忙,因为每天都有许多大臣来向他汇报各种信息等。这天有n位大臣来汇报信息,其中第i位的序号为i,为了更有效的完成每天的工作,国王决定给每位大臣汇报的事情按里要性进行一个排序,让各位大臣按排序依次汇报。首先对每人的汇报在m个方面名评估一个重要性,然后每个汇报的重要性就是m个方面的重要性之和,重要性越高的汇报会排在越前面,对于重要性相同的,则按大臣的序号排序,越小的在越前面。这时,序号为id的大臣找到了你,他想请你帮他计算一下他排在第几个。
输入描述:
第一行三个正整数n、m和id,表示大臣数量、重要性方面数量和来找你帮忙的大臣序号。接下来n行每行m个正整数,第i行为ai1,ai2……aim,其中aij表示序号为i的大臣的汇报在第j个方面的重要性。
输出描述:
输出一行一个正整数ans,表示序号为i的大臣排在第ans位。
样例输入:
3 3 2
90 90 90
80 100 90
80 85 85
样例输出:
2
完整代码如下:

#include<iostream>
#include<vector>
#include<stdlib.h>
#include<algorithm>
#include<unordered_map>
using namespace std;
bool cmp(pair<int, int>a, pair<int, int> b) {
    return a.second >= b.second;//对于second的降序
}
int ministersort(int m,int n,int a,vector<vector<int>>&nums){
    unordered_map<int,int>minister;
    int ans;
    for(int i = 0;i < n;i++){
        int sum = 0;
        for(int j = 0;j < m;j++){
            sum += nums[i][j];
        }
        minister[i] = sum;
    }
    vector<pair<int, int>> vecs;
    for (auto it = minister.begin();it!= minister.end();it++) {
        vecs.push_back(make_pair(it->first, it->second));
   }
    sort(vecs.begin(),vecs.end(),cmp);
    int i = 0;
    for (auto it = vecs.begin(); it != vecs.end(); it++){
        if(it -> first != a){
            i++;
            ans = i;
        }else{
            break;
        }
    }
    return ans;
}
int main(){
    int m,n,a;
    cin >> m >> n >> a;
    int x;
    vector<vector<int>> vec;
    vector<int> v;
    while(cin >> x){
        v.push_back(x);
        if(cin.get() == '\n'){
            vec.push_back(v);
            v.clear();
        }
        if(cin.peek() == '\n'){
            vec.push_back(v);
            break;
        }
    }
    int ans = ministersort(m,n,a,vec);
    cout << ans << endl;
    system("pause");
}

9.11Redbook编程题练习

小明是一名魔法师,他会n种法术,其中第i种法术的威力为a;他经常通过双手各自释放一种法术来提升威力,能得到的威力值为双手各自释放的法术的威力的乘积,但是他还不够强大,双手释放的两种法术必须是不同的,即不能双手释放同一种法术。这天他接到了一个任务,需要释放威力值至少为K才能完成,他想请你帮他算一算,在两只手都释放法术的情况下,共有多少方案能达到威力值K。每种方案可记作(u, v),u*v,其威力值为au * av, (u, v)和(v,u)会被视为不同的方案。
输入描述
第—行两个正整数n和K,表示法术数量和威力值需求。
第二行为n个正整数a1 a2……an,其中ai表示第i个法术的威力为ai。
输出描述
输出威力值至少为K的方案数。
样例输入
3 3
3 2 1
样例输出
4

#include<iostream>
#include<vector>
#include<stdlib.h>
using namespace std;
int ans = 0;
int magepower(vector<int>&nums,int n,int k){
    int temp = nums[0];
    int sum = 0;
    for(int i = 1;i < n;i++){
        // for(int j = i + 1;j < n;j++){
        //     if(nums[i] * nums[j] >= k){
        //         ans++;
        //     }
        // }
        sum += temp * nums[i];
        if(sum >= k)
            ans++;
        temp += nums[i];
    }
    ans *= 2;
    return ans;
}
int main(){
    int n,k,num;
    cin >> n >> k;
    vector<int>vec;
    while(cin >> num){
        vec.push_back(num);
        if(cin.get() == '\n'){
            break;
        }
    }
    int ans = magepower(vec,n,k);
    cout << ans << endl;
    system("pause");
}

9.12.LeetCode257.二叉树的所有路径&&LeetCode1608.特殊数组的特殊值

LeetCode257.二叉树的所有路径
完整代码如下:

#include<iostream>
#include<vector>
#include<algorithm>
#include<stdlib.h>
using namespace std;
struct TreeNode{
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x):val(x),left(nullptr),right(nullptr){}
};
TreeNode* construct_binary_tree(const vector<int>& vec){
    vector<TreeNode*>vecTree(vec.size(),NULL);
    TreeNode* root = NULL;
    for(int i = 0;i < vec.size();i++){
        TreeNode* node = NULL;
        if(vec[i] != -1) node = new TreeNode(vec[i]);
        vecTree[i] = node;
        if(i == 0)root = node;
    }
    for(int i = 0;i * 2 + 2 < vec.size();i++){
        if(vecTree[i] != NULL){
            vecTree[i] -> left = vecTree[i * 2 + 1];
            vecTree[i] -> right = vecTree[i * 2 + 2];
        }
    }
    return root;
}
void travesal(TreeNode* cur,string path,vector<string>&result){
    path += to_string(cur -> val);//中
    if(cur -> left == NULL && cur -> right == NULL){
        result.push_back(path);
        return;
    }
    if(cur -> left) travesal(cur -> left,path + "->",result);//左
    if(cur -> right) travesal(cur -> right,path + "->",result);//右
}
vector<string>binaryTreePaths(TreeNode *root){
    vector<string>result;
    string path;
    if(root == NULL)return result;
    travesal(root,path,result);
    return result;
}
int main(){
    vector<int>vec;
	int num;
	while(cin >> num){
		vec.push_back(num);
		if(cin.get() == '\n')
			break;
	}   
    TreeNode* root = construct_binary_tree(vec);
    vector<string>ans = binaryTreePaths(root);
    cout << "[";
    for(int i = 0;i < ans.size();i++){
        cout << '"'<< ans[i] << '"';
        if(i != ans.size() - 1)
            cout << ',';
    }
    cout << "]";
    system("pause");
}

LeetCode1608.特殊数组的特殊值
完整代码如下:

#include<iostream>
#include<vector>
#include<algorithm>
#include<stdlib.h>
using namespace std;
int specialArray(vector<int>&nums){
    sort(nums.begin(),nums.end(),greater<int>());
    int n = nums.size();
    for(int i = 1;i <= n;i++){
        if(nums[i - 1] >= i && (i == n || nums[i] < i))
            return i;
    }
    return -1;
}
int main(){
    vector<int>vec;
    int num;
    while(cin >> num){
        vec.push_back(num);
        if(cin.get() == '\n')
            break;
    }
    int ans = specialArray(vec);
    cout << ans << endl;
    system("pause");
}

9.15XiaoMi编程题练习

将一个链表m位置到n位置之间的区间反转,要求时间复杂度为O(n),空间复杂度为O(1)。
例如:
给出的链表为1->2->3->4->5->NULL,m=2,n=4.
返回1->4->3->2->5->NULL
注意:
给出的m,n满足一下条件:
1<=m<=n<=链表长度
完整代码如下:

#include<iostream>
#include<vector>
using namespace std;
struct  ListNode{
    int val;
    ListNode* next;
    ListNode():val(0),next(nullptr){}
    ListNode(int x):val(x),next(nullptr){}
    ListNode(int x,ListNode* next):val(x),next(next){}
};
ListNode* constructList(vector<int>nodes){
    ListNode* dummyHead = new ListNode();
    ListNode* cur = dummyHead;
    for(auto i:nodes){
        cur -> next = new ListNode(i);
        cur = cur -> next;
    }
    cur = dummyHead -> next;
    delete dummyHead;
    return cur;
}
void printList(ListNode* head){
    ListNode* cur = head;
    if(cur == NULL){
        cout << '[]' << endl;
    }
    while(cur != NULL){
        cout << cur -> val << ' ';
        cur = cur -> next;
    }
}
ListNode* reverseBetween(ListNode* head,int m,int n){
    if(head == nullptr || head -> next == nullptr)
        return head;
    ListNode* newhead = new ListNode(-1);
    newhead -> next = head;
    ListNode* start = head;
    ListNode* prestart = newhead;
    for(int i = 1;i < m;i++){
        prestart = start;
        start = start -> next;
    }
    for(int j = 0;j < n - m;j++){
        ListNode* temp = start -> next;
        start -> next = temp -> next;
        temp -> next = prestart -> next;
        prestart -> next = temp;
    }
    return newhead -> next;
}
int main(){
    int m,n;
    vector<int>vec;
    int num;
    while(cin >> num){
        vec.push_back(num);
        if(cin.get() == '\n')
            break;
    }
    cin >> m >> n;
    ListNode* node = constructList(vec);
    printList(reverseBetween(node,m,n));
}

11.21LeetCode808.分汤

请了个假,时间清闲了很多,佛系找工作,刷题变爱好

有 A 和 B 两种类型 的汤。一开始每种类型的汤有 n 毫升。有四种分配操作:
1.提供 100ml 的 汤A 和 0ml 的 汤B 。
2.提供 75ml 的 汤A 和 25ml 的 汤B 。
3.提供 50ml 的 汤A 和 50ml 的 汤B 。
4.提供 25ml 的 汤A 和 75ml 的 汤B 。
当我们把汤分配给某人之后,汤就没有了。每个回合,我们将从四种概率同为 0.25 的操作中进行分配选择。如果汤的剩余量不足以完成某次操作,我们将尽可能分配。当两种类型的汤都分配完时,停止操作。
注意 不存在先分配 100 ml 汤B 的操作。
需要返回的值: 汤A 先分配完的概率 +  汤A和汤B 同时分配完的概率 / 2。返回值在正确答案 10-5 的范围内将被认为是正确的。
示例 1:
输入: n = 50
输出: 0.62500
解释:如果我们选择前两个操作,A 首先将变为空。
对于第三个操作,A 和 B 会同时变为空。
对于第四个操作,B 首先将变为空。
所以 A 变为空的总概率加上 A 和 B 同时变为空的概率的一半是 0.25 *(1 + 1 + 0.5 + 0)= 0.625。
示例 2:
输入: n = 100
输出: 0.71875
完整代码如下:

#include <iostream>
#include <vector>
#include<stdlib.h>
#include<math.h>
using namespace std;
double soupservings(int n){
    n = ceil((double)n / 25);
    if(n >= 179){
        return 1.0;
    }
    vector<vector<double>>dp(n + 1,vector<double>(n + 1));
    dp[0][0] = 0.5;
    for(int i = 1;i <= n;i++){
        dp[0][i] = 1.0;
    }
    for(int i = 1;i <= n;i++){
        for(int j = 1;j <= n;j++){
            dp[i][j] = (dp[max(0,i - 4)][j] + dp[max(0,i - 3)][max(0,j - 1)]+
            dp[max(0,i - 2)][max(0,j - 2)]+ dp[max(0,i - 1)][max(0,j - 3)]) / 4.0;
        }
    }
    return dp[n][n];
}
int main(){
    int n;
    cin >> n;
    double res = soupservings(n);
    cout << res << endl;
    system("pause");
}

11.22LeetCode878.第N个神奇数字

偷偷吐槽一下,反正工作不好找,摆烂找工作刷题是真的开心,哈哈哈哈哈哈哈哈哈哈哈哈哈
今天的题很有意思运用了很多数学知识,我也第一次了解了欧几里得算法(辗转相除法),这是个求最大公约数的算法。
相关知识链接如下:欧几里得算法
一个正整数如果能被 a 或 b 整除,那么它是神奇的。
给定三个整数 n , a , b ,返回第 n 个神奇的数字。因为答案可能很大,所以返回答案 对 1e9 + 7 取模 后的值。
示例 1:
输入:n = 1, a = 2, b = 3
输出:2
示例 2:
输入:n = 4, a = 2, b = 3
输出:6
提示:
1 <= n <= 109
2 <= a, b <= 4 * 104
完整代码如下:

#include<iostream>
#include<vector>
#include<stdlib.h>
using namespace std;
int gcd(int a, int b)
{
	if (a % b == 0) return b;
	else return gcd(b, a % b);
}
int lcm(int a, int b)
{
	int temp = a * b;
	temp = temp / gcd(a, b);
	return temp;
}
const int MOD = 1e9 + 7;
int nthMagicalNumber(int n,int a,int b){
    long long l = min(a,b);
    long long r = (long long)n * min(a,b);
    int c = lcm(a,b);
    while(l <= r){
        long long mid = (l + r) / 2;
        long long cnt = mid / a + mid / b - mid / c;
        if(cnt >= n){
            r = mid - 1;
        }else{
            l = mid + 1;
        }
    }
    return (r + 1) % MOD;
}
int main(){
    int n,a,b;
    cin >> n >> a >> b;
    int res = nthMagicalNumber(n,a,b);
    cout << res << endl;
    system("pause");
}

11.23LeetCode1742.盒子中小球的最大数量

你在一家生产小球的玩具厂工作,有 n 个小球,编号从 lowLimit 开始,到 highLimit 结束(包括 lowLimit 和 highLimit ,即 n == highLimit - lowLimit + 1)。另有无限数量的盒子,编号从 1 到 infinity 。
你的工作是将每个小球放入盒子中,其中盒子的编号应当等于小球编号上每位数字的和。例如,编号 321 的小球应当放入编号 3 + 2 + 1 = 6 的盒子,而编号 10 的小球应当放入编号 1 + 0 = 1 的盒子。
给你两个整数 lowLimit 和 highLimit ,返回放有最多小球的盒子中的小球数量。如果有多个盒子都满足放有最多小球,只需返回其中任一盒子的小球数量。
示例 1:
输入:lowLimit = 1, highLimit = 10
输出:2
解释:
盒子编号:1 2 3 4 5 6 7 8 9 10 11 ...
小球数量:2 1 1 1 1 1 1 1 1 0 0 ...
编号 1 的盒子放有最多小球,小球数量为 2 。
示例 2:
输入:lowLimit = 5, highLimit = 15
输出:2
解释:
盒子编号:1 2 3 4 5 6 7 8 9 10 11 ...
小球数量:1 1 1 1 2 2 1 1 1 0 0 ...
编号 5 和 6 的盒子放有最多小球,每个盒子中的小球数量都是 2 。
示例 3:
输入:lowLimit = 19, highLimit = 28
输出:2
解释:
盒子编号:1 2 3 4 5 6 7 8 9 10 11 12 ...
小球数量:0 1 1 1 1 1 1 1 1 2 0 0 ...
编号 10 的盒子放有最多小球,小球数量为 2 。
提示:
1 <= lowLimit <= highLimit <= 1e5
完整代码如下:

#include<iostream>
#include<vector>
#include<stdlib.h>
#include<math.h>
#include<unordered_map>
using namespace std;
int countBalls(int lowLimit, int highLimit){
    unordered_map<int,int>count;
    int res = 0;
    int box,x;
    for(int i = lowLimit;i < highLimit + 1;i++){
        box = 0,x = i;
        while(x){
            box += x % 10;
            x /= 10;
        }
        count[box]++;
        res = max(res,count[box]);
    }
    return res;
}
int main(){
    int low,high;
    cin >> low >> high;
    int res = countBalls(low,high);
    cout << res << endl;
    system("pause");
}

11.24LeetCode795.区间子数组个数

给你一个整数数组 nums 和两个整数:left 及 right 。找出 nums 中连续、非空且其中最大元素在范围 [left, right] 内的子数组,并返回满足条件的子数组的个数。
生成的测试用例保证结果符合 32-bit 整数范围。
示例 1:
输入:nums = [2,1,4,3], left = 2, right = 3
输出:3
解释:满足条件的三个子数组:[2], [2, 1], [3]
示例 2:
输入:nums = [2,9,2,5,6], left = 2, right = 8
输出:7
提示:
1 <= nums.length <= 105
0 <= nums[i] <= 109
0 <= left <= right <= 109
完整代码如下:

#include<iostream>
#include<vector>
#include<stdlib.h>
using namespace std;
int count(vector<int>&nums,int lower){
    int res = 0,cur = 0;
    for(auto x:nums){
        cur = x < lower?cur + 1:0;
        res += cur;
    }
    return res;
}
int numSubarrayBoundedMax(vector<int>& nums, int left, int right) {
    return count(nums,right) - count(nums,left - 1);
}
int main(){
    int left,right,num;
    vector<int>vec;
	while(cin >> num){
		vec.push_back(num);
		if(cin.get() == '\n')
			break;
	}   
    cin >> left >> right;
    int res = numSubarrayBoundedMax(vec,left,right);
    cout << res << endl;
    system("pause");
}

11.27LeetCode1752. 检查数组是否经排序和轮转得到

给你一个数组 nums 。nums 的源数组中,所有元素与 nums 相同,但按非递减顺序排列。
如果 nums 能够由源数组轮转若干位置(包括 0 个位置)得到,则返回 true ;否则,返回 false 。
源数组中可能存在 重复项 。
注意:我们称数组 A 在轮转 x 个位置后得到长度相同的数组 B ,当它们满足 A[i] == B[(i+x) % A.length] ,其中 % 为取余运算。
示例 1:
输入:nums = [3,4,5,1,2]
输出:true
解释:[1,2,3,4,5] 为有序的源数组。
可以轮转 x = 3 个位置,使新数组从值为 3 的元素开始:[3,4,5,1,2] 。
示例 2:
输入:nums = [2,1,3,4]
输出:false
解释:源数组无法经轮转得到 nums 。
示例 3:
输入:nums = [1,2,3]
输出:true
解释:[1,2,3] 为有序的源数组。
可以轮转 x = 0 个位置(即不轮转)得到 nums 。
提示:
1 <= nums.length <= 100
1 <= nums[i] <= 100
完整代码如下:

#include<iostream>
#include<vector>
#include<stdlib.h>
using namespace std;
bool check(vector<int> &nums){
    int n = nums.size(),x = 0;
    for(int i = 1;i < n;i++){
        if(nums[i] < nums[i - 1]){
            x = i;
            break;
        }
    }
    if(x == 0)
        return true;
    for(int i = x + 1;i < n;i++){
        if(nums[i] < nums[i - 1]){
            return false;
        }
    }
    return nums[0] >= nums[n - 1];
}
int main(){
    int num;
    vector<int>vec;
    while(cin >> num){
        vec.push_back(num);
        if(cin.get() == '\n')
            break;
    }
    if(check(vec)){
        cout << "true" << endl;
    }else{
        cout << "false" << endl;
    } 
    system("pause");
}

11.28LeetCode813. 最大平均值和的分组

今天的题有点难度,使用了动态规划,我这里确实不太好,还需要继续学习。
给定数组 nums 和一个整数 k 。我们将给定的数组 nums 分成 最多 k 个相邻的非空子数组 。 分数 由每个子数组内的平均值的总和构成。
注意我们必须使用 nums 数组中的每一个数进行分组,并且分数不一定需要是整数。
返回我们所能得到的最大 分数 是多少。答案误差在 10-6 内被视为是正确的。

示例 1:
输入: nums = [9,1,2,3,9], k = 3
输出: 20.00000
解释:
nums 的最优分组是[9], [1, 2, 3], [9]. 得到的分数是 9 + (1 + 2 + 3) / 3 + 9 = 20.
我们也可以把 nums 分成[9, 1], [2], [3, 9].
这样的分组得到的分数为 5 + 2 + 6 = 13, 但不是最大值.
示例 2:
输入: nums = [1,2,3,4,5,6,7], k = 4
输出: 20.50000
完整代码如下:

#include<iostream>
#include<vector>
#include<stdlib.h>
using namespace std;
double largestSumOfAverages(vector<int>&A,int K){
    int i,j,k,n = A.size();
    vector<vector<double>>dp(n,vector<double>(K + 1,0.0));
    //dp[i][k]表示,以i结束的时候,切分成k段,所有平均值的最大值
    vector<int>presum(A);
    for(i = 1;i < n;i++)
        presum[i] += presum[i - 1];
    for(i = 0;i <= n - K;i++){
        dp[i][1] = presum[i]/double(i + 1);//初始化,切1段出来的平均值
    }
    for(k = 2;k <= K;k++){
        //第k段
        for(j = k - 1;j < n - (K - k);j++){
            //j在第k段可能的范围
            for(i = j - 1;i >= 0;i--){
                //遍历小于j的所有i
                dp[j][k] = max(dp[j][k],dp[i][k - 1] + (presum[j] - presum[i])/double(j - i));
            }
        }
    }
    return dp[n - 1][K];
}
int main(){
    int num,k;
    vector<int>vec;
    while(cin >> num){
        vec.push_back(num);
        if(cin.get() == '\n')
            break;
    }
    cin >> k;
    double res = largestSumOfAverages(vec,k);
    cout << res << endl;
    system("pause");
}

11.29LeetCode1758. 生成交替二进制字符串的最少操作数

给你一个仅由字符 '0' 和 '1' 组成的字符串 s 。一步操作中,你可以将任一 '0' 变成 '1' ,或者将 '1' 变成 '0' 。
交替字符串 定义为:如果字符串中不存在相邻两个字符相等的情况,那么该字符串就是交替字符串。例如,字符串 "010" 是交替字符串,而字符串 "0100" 不是。
返回使 s 变成 交替字符串 所需的 最少 操作数。
示例 1:
输入:s = "0100"
输出:1
解释:如果将最后一个字符变为 '1' ,s 就变成 "0101" ,即符合交替字符串定义。
示例 2:
输入:s = "10"
输出:0
解释:s 已经是交替字符串。
示例 3:
输入:s = "1111"
输出:2
解释:需要 2 步操作得到 "0101" 或 "1010" 。
提示:
1 <= s.length <= 104
s[i] 是 '0' 或 '1'

#include<iostream>
#include<vector>
#include<stdlib.h>
using namespace std;
int minOperations(string s) {
    int n = s.size(),res = 0;;
    for(int i = 1;i < n;i++){
        if(s[i] == s[i - 1]){
            res++;
            if(s[i] =='0'){
                s[i] = '1';
            }else{
                s[i] ='0';
            }
        }
    }
    return min(res,n - res);
}
int main(){
    string s;
    cin >> s;
    int res = minOperations(s);
    cout << res << endl;
    system("pause");
}

12.2LeetCode1769. 移动所有球到每个盒子所需的最小操作数

有 n 个盒子。给你一个长度为 n 的二进制字符串 boxes ,其中 boxes[i] 的值为 '0' 表示第 i 个盒子是 空 的,而 boxes[i] 的值为 '1' 表示盒子里有 一个 小球。
在一步操作中,你可以将 一个 小球从某个盒子移动到一个与之相邻的盒子中。第 i 个盒子和第 j 个盒子相邻需满足 abs(i - j) == 1 。注意,操作执行后,某些盒子中可能会存在不止一个小球。
返回一个长度为 n 的数组 answer ,其中 answer[i] 是将所有小球移动到第 i 个盒子所需的 最小 操作数。
每个 answer[i] 都需要根据盒子的 初始状态 进行计算。
示例 1:
输入:boxes = "110"
输出:[1,1,3]
解释:每个盒子对应的最小操作数如下:

  1. 第 1 个盒子:将一个小球从第 2 个盒子移动到第 1 个盒子,需要 1 步操作。
  2. 第 2 个盒子:将一个小球从第 1 个盒子移动到第 2 个盒子,需要 1 步操作。
  3. 第 3 个盒子:将一个小球从第 1 个盒子移动到第 3 个盒子,需要 2 步操作。将一个小球从第 2 个盒子移动到第 3 个盒子,需要 1 步操作。共计 3 步操作。
    示例 2:
    输入:boxes = "001011"
    输出:[11,8,5,4,3,4]
    本题有两个解法,第一个是模拟法,第二个是根据前一个盒子的操作数得到下一个盒子的操作数
    完整代码如下:
#include<iostream>
#include<vector>
#include<stdlib.h>
using namespace std;
/*
vector<int> minOperations(string boxes) {
    int n = boxes.size();
    vector<int>res(n,0);
    for(int i = 0;i < n;i++){
        for(int j = 0;j < n;j++){
            if(boxes[j] == '1'){
                res[i] += abs(j - i);
            }
        }
    }
    return res;
}
*/
vector<int> minOperations(string boxes) {
    int left = boxes[0] - '0',right = 0,operations = 0;
    int n = boxes.size();
    for(int i = 1;i < n;i++){
        if(boxes[i] == '1'){
            right++;
            operations += i;
        }
    }
    vector<int>res(n);
    res[0] = operations;
    for(int i = 1;i < n;i++){
        operations += left - right;
        if(boxes[i] == '1'){
            left++;
            right--;
        }
        res[i] = operations;
    }
    return res;
}
int main(){
    string t;
    cin >> t;
    vector<int>res = minOperations(t);
    cout << "[";
    for(int i = 0;i < res.size();i++){
        cout << res[i];
        if(i != res.size() - 1)
            cout << ",";
    }
    cout << "]" << endl;
    system("pause");
}

12.3LeetCode1796. 字符串中第二大的数字

给你一个混合字符串 s ,请你返回 s 中 第二大 的数字,如果不存在第二大的数字,请你返回 -1 。
混合字符串 由小写英文字母和数字组成。
示例 1:
输入:s = "dfa12321afd"
输出:2
解释:出现在 s 中的数字包括 [1, 2, 3] 。第二大的数字是 2 。
示例 2:
输入:s = "abc1111"
输出:-1
解释:出现在 s 中的数字只包含 [1] 。没有第二大的数字。

#include<iostream>
#include<vector>
#include<stdlib.h>
using namespace std;
int secondHighest(string s) {
    int first = -1,second = -1;
    for(auto c:s){
        if(isdigit(c)){
            int num = c - '0';
            if(num > first){
                second = first;
                first = num;
            }else if(num < first && num > second){
                second = num;
            }
        }
    }
    return second;
}
int main(){
    string s;
    cin >> s;
    int res = secondHighest(s);
    cout << res << endl;
    system("pause");
}

12.6LeetCode1805. 字符串中不同整数的数目

给你一个字符串 word ,该字符串由数字和小写英文字母组成。
请你用空格替换每个不是数字的字符。例如,"a123bc34d8ef34" 将会变成 " 123  34 8  34" 。注意,剩下的这些整数为(相邻彼此至少有一个空格隔开):"123"、"34"、"8" 和 "34" 。
返回对 word 完成替换后形成的 不同 整数的数目。
只有当两个整数的 不含前导零 的十进制表示不同, 才认为这两个整数也不同。
示例 1:
输入:word = "a123bc34d8ef34"
输出:3
解释:不同的整数有 "123"、"34" 和 "8" 。注意,"34" 只计数一次。
示例 2:
输入:word = "leet1234code234"
输出:2
示例 3:
输入:word = "a1b01c001"
输出:1
解释:"1"、"01" 和 "001" 视为同一个整数的十进制表示,因为在比较十进制值时会忽略前导零的存在。
提示:
1 <= word.length <= 1000
word 由数字和小写英文字母组成

#include<iostream>
#include<vector>
#include<stdlib.h>
#include<unordered_set>
using namespace std;
int numDifferentIntegers(string word){
    unordered_set<string>s;
    int n = word.size(),p1 = 0,p2;
    while(true){
        while (p1 < n && !isdigit(word[p1])){
            p1++;
        }
        if(p1 == n){
            break;
        }
        p2 = p1;
        while(p2 < n && isdigit(word[p2])){
            p2++;
        }
        while(p2 - p1 > 1 && word[p1] == '0'){
            p1++;
        }
        s.insert(word.substr(p1,p2 - p1));
        p1 = p2;
    }
    return s.size();
}
int main(){
    string s;
    cin >> s;
    int res = numDifferentIntegers(s);
    cout << res << endl;
    system("pause");
}

12.7LeetCode1775. 通过最少操作次数使数组的和相等

给你两个长度可能不等的整数数组 nums1 和 nums2 。两个数组中的所有值都在 1 到 6 之间(包含 1 和 6)。
每次操作中,你可以选择 任意 数组中的任意一个整数,将它变成 1 到 6 之间 任意 的值(包含 1 和 6)。
请你返回使 nums1 中所有数的和与 nums2 中所有数的和相等的最少操作次数。如果无法使两个数组的和相等,请返回 -1 。
示例 1:
输入:nums1 = [1,2,3,4,5,6], nums2 = [1,1,2,2,2,2]
输出:3
解释:你可以通过 3 次操作使 nums1 中所有数的和与 nums2 中所有数的和相等。以下数组下标都从 0 开始。

  • 将 nums2[0] 变为 6 。 nums1 = [1,2,3,4,5,6], nums2 = [6,1,2,2,2,2] 。
  • 将 nums1[5] 变为 1 。 nums1 = [1,2,3,4,5,1], nums2 = [6,1,2,2,2,2] 。
  • 将 nums1[2] 变为 2 。 nums1 = [1,2,2,4,5,1], nums2 = [6,1,2,2,2,2] 。
    示例 2:
    输入:nums1 = [1,1,1,1,1,1,1], nums2 = [6]
    输出:-1
    解释:没有办法减少 nums1 的和或者增加 nums2 的和使二者相等。
    示例 3:
    输入:nums1 = [6,6], nums2 = [1]
    输出:3
    解释:你可以通过 3 次操作使 nums1 中所有数的和与 nums2 中所有数的和相等。以下数组下标都从 0 开始。
  • 将 nums1[0] 变为 2 。 nums1 = [2,6], nums2 = [1] 。
  • 将 nums1[1] 变为 2 。 nums1 = [2,2], nums2 = [1] 。
  • 将 nums2[0] 变为 4 。 nums1 = [2,2], nums2 = [4] 。

提示:
1 <= nums1.length, nums2.length <= 105
1 <= nums1[i], nums2[i] <= 6

#include<iostream>
#include<vector>
#include<stdlib.h>
#include<numeric>
#include<algorithm>
using namespace std;
int minOperations(vector<int>&nums1,vector<int>&nums2){
    int sum1 = accumulate(nums1.begin(),nums1.end(),0);
    int sum2 = accumulate(nums2.begin(),nums2.end(),0);
    if(sum1 < sum2){
        swap(nums1,nums2);
        swap(sum1,sum2);
    }
    int n1 = nums1.size(),n2 = nums2.size();
    int d = sum1 - sum2;
    if(d == 0)return 0;
    sort(nums1.begin(),nums1.end());
    sort(nums2.begin(),nums2.end());
    int i = n1 - 1,j = 0;
    int ans = 0;
    while(i >= 0 || j < n2){
        int d1 = 0,d2 = 0;
        if(i >= 0) d1 = nums1[i] - 1;
        if(j < n2) d2 = 6 - nums2[j];
        int maxd = max(d1,d2);
        if(maxd == 0) return -1;
        if(maxd >= d) return ans + 1;
        if(d1 == maxd){
            i--;
        }else{
            j++;
        }
        d -= maxd;
        ans++;
    }
    return -1;
}
int main(){
    int num1,num2;
    vector<int>vec1;
    vector<int>vec2;
    while(cin >> num1){
        vec1.push_back(num1);
        if(cin.get() == '\n')
            break;
    }
    while(cin >> num2){
        vec2.push_back(num2);
        if(cin.get() == '\n')
            break;
    }
    int res = minOperations(vec1,vec2);
    cout << res << endl;
    system("pause");
}

12.8LeetCode1812. 判断国际象棋棋盘中一个格子的颜色

今天的题有点过于简单了,泪目!

给你一个坐标 coordinates ,它是一个字符串,表示国际象棋棋盘中一个格子的坐标。下图是国际象棋棋盘示意图。
如果所给格子的颜色是白色,请你返回 true,如果是黑色,请返回 false 。
给定坐标一定代表国际象棋棋盘上一个存在的格子。坐标第一个字符是字母,第二个字符是数字。
示例 1:
输入:coordinates = "a1"
输出:false
解释:如上图棋盘所示,"a1" 坐标的格子是黑色的,所以返回 false 。
示例 2:
输入:coordinates = "h3"
输出:true
解释:如上图棋盘所示,"h3" 坐标的格子是白色的,所以返回 true 。
示例 3:
输入:coordinates = "c7"
输出:false
提示:
coordinates.length == 2
'a' <= coordinates[0] <= 'h'
'1' <= coordinates[1] <= '8'

#include<iostream>
#include<vector>
#include<stdlib.h>
using namespace std;
bool squareIsWhite(string coordinates){
    int res = coordinates[0] - 96 + coordinates[1];
    if(res % 2 == 0)
        return false;
    return true;
}
int main(){
    string s;
    cin >> s;
    cout << squareIsWhite(s) << endl;
    system("pause");
}

12.9LeetCode1780. 判断一个数字是否可以表示成三的幂的和

给你一个整数 n ,如果你可以将 n 表示成若干个不同的三的幂之和,请你返回 true ,否则请返回 false 。
对于一个整数 y ,如果存在整数 x 满足 y == 3x ,我们称这个整数 y 是三的幂。
示例 1:
输入:n = 12
输出:true
解释:12 = 31 + 32
示例 2:
输入:n = 91
输出:true
解释:91 = 30 + 32 + 34
示例 3:
输入:n = 21
输出:false
提示:
1 <= n <= 107

#include<iostream>
#include<vector>
#include<stdlib.h>
using namespace std;
bool checkPowersOfThree(int n){
    while(n){
        if(n % 3 == 2)
            return false;
        n /= 3;
    }
    return true;
}
int main(){
    int num;
    cin >> num;
    cout << checkPowersOfThree(num) << endl;
    system("pause");
}

12.11LeetCode1827. 最少操作使数组递增

给你一个整数数组 nums (下标从 0 开始)。每一次操作中,你可以选择数组中一个元素,并将它增加 1 。
比方说,如果 nums = [1,2,3] ,你可以选择增加 nums[1] 得到 nums = [1,3,3] 。
请你返回使 nums 严格递增 的 最少 操作次数。
我们称数组 nums 是 严格递增的 ,当它满足对于所有的 0 <= i < nums.length - 1 都有 nums[i] < nums[i+1] 。一个长度为 1 的数组是严格递增的一种特殊情况。
示例 1:
输入:nums = [1,1,1]
输出:3
解释:你可以进行如下操作:

  1. 增加 nums[2] ,数组变为 [1,1,2] 。
  2. 增加 nums[1] ,数组变为 [1,2,2] 。
  3. 增加 nums[2] ,数组变为 [1,2,3] 。
    示例 2:
    输入:nums = [1,5,2,4,1]
    输出:14
    示例 3:
    输入:nums = [8]
    输出:0
    提示:
    1 <= nums.length <= 5000
    1 <= nums[i] <= 104
#include<iostream>
#include<vector>
#include<stdlib.h>
using namespace std;
int minOperations(vector<int>&nums){
    int n = nums.size();
    int res = 0;
    for(int i = 0;i < n - 1;i++){
        if(nums[i + 1] <= nums[i]){
            res += nums[i] + 1 - nums[i + 1];
            nums[i + 1] = nums[i] + 1;
        }
    }
    return res;
}
int main(){
    int num;
    vector<int>vec;
    while(cin >> num){
        vec.push_back(num);
        if(cin.get() == '\n')
            break;
    }
    int res = minOperations(vec);
    cout << res << endl;
    system("pause");
}

12.13LeetCode1832. 判断句子是否为全字母句

全字母句 指包含英语字母表中每个字母至少一次的句子。
给你一个仅由小写英文字母组成的字符串 sentence ,请你判断 sentence 是否为 全字母句 。
如果是,返回 true ;否则,返回 false 。 
示例 1:
输入:sentence = "thequickbrownfoxjumpsoverthelazydog"
输出:true
解释:sentence 包含英语字母表中每个字母至少一次。
示例 2:
输入:sentence = "leetcode"
输出:false

提示:
1 <= sentence.length <= 1000
sentence 由小写英语字母组成

#include<iostream>
#include<vector>
#include<stdlib.h>
#include<unordered_set>
using namespace std;
bool checkIfPangram(string sentence){
    unordered_set<char>p;
    for(auto s:sentence){
        p.insert(s);
    }
    if(p.size() == 26){
        return true;
    }
    return false;
}
int main(){
    string s;
    cin >> s;
    cout << checkIfPangram(s) << endl;
    system("pause");
}

12.15LeetCode1945. 字符串转化后的各位数字之和

给你一个由小写字母组成的字符串 s ,以及一个整数 k 。
首先,用字母在字母表中的位置替换该字母,将 s 转化 为一个整数(也就是,'a' 用 1 替换,'b' 用 2 替换,... 'z' 用 26 替换)。接着,将整数 转换 为其 各位数字之和 。共重复 转换 操作 k 次 。
例如,如果 s = "zbax" 且 k = 2 ,那么执行下述步骤后得到的结果是整数 8 :
转化:"zbax" ➝ "(26)(2)(1)(24)" ➝ "262124" ➝ 262124
转换 #1:262124 ➝ 2 + 6 + 2 + 1 + 2 + 4 ➝ 17
转换 #2:17 ➝ 1 + 7 ➝ 8
返回执行上述操作后得到的结果整数。
示例 1:
输入:s = "iiii", k = 1
输出:36
解释:操作如下:

  • 转化:"iiii" ➝ "(9)(9)(9)(9)" ➝ "9999" ➝ 9999
  • 转换 #1:9999 ➝ 9 + 9 + 9 + 9 ➝ 36
    因此,结果整数为 36 。
    示例 2:
    输入:s = "leetcode", k = 2
    输出:6
    解释:操作如下:
  • 转化:"leetcode" ➝ "(12)(5)(5)(20)(3)(15)(4)(5)" ➝ "12552031545" ➝ 12552031545
  • 转换 #1:12552031545 ➝ 1 + 2 + 5 + 5 + 2 + 0 + 3 + 1 + 5 + 4 + 5 ➝ 33
  • 转换 #2:33 ➝ 3 + 3 ➝ 6
    因此,结果整数为 6 。
    提示:
    1 <= s.length <= 100
    1 <= k <= 10
    s 由小写英文字母组成
#include<iostream>
#include<vector>
#include<stdlib.h>
using namespace std;
int getLucky(string s,int k) {
    string n;
    for(char ch:s){
        n += to_string(ch - 96);
    }
    while(k > 0 && n.size() > 1){
        int sum = 0;
        for(char ch:n){
            sum += ch - '0';
        }
        n = to_string(sum);
        k--;
    }
    return stoi(n);
}
int main(){
    string s;
    cin >> s;
    int k;
    cin >> k;
    int res = getLucky(s,k);
    cout << res << endl;
    system("pause");
}

12.26LeetCode1759. 统计同构子字符串的数目

成了小羊人太久没状态了,今天继续
给你一个字符串 s ,返回 s 中 同构子字符串 的数目。由于答案可能很大,只需返回对 109 + 7 取余 后的结果。
同构字符串 的定义为:如果一个字符串中的所有字符都相同,那么该字符串就是同构字符串。
子字符串 是字符串中的一个连续字符序列。
示例 1:
输入:s = "abbcccaa"
输出:13
解释:同构子字符串如下所列:
"a" 出现 3 次。
"aa" 出现 1 次。
"b" 出现 2 次。
"bb" 出现 1 次。
"c" 出现 3 次。
"cc" 出现 2 次。
"ccc" 出现 1 次。
3 + 1 + 2 + 1 + 3 + 2 + 1 = 13
示例 2:
输入:s = "xy"
输出:2
解释:同构子字符串是 "x" 和 "y" 。
示例 3:
输入:s = "zzzzz"
输出:15
提示:
1 <= s.length <= 105
s 由小写字符串组成
完整代码如下:

#include<iostream>
#include<stdlib.h>
#include<vector>
using namespace std;
int countHomogenous(string s){
    long long res = 0;
    long long mod = 1e9 + 7;
    int prev = s[0];
    int cnt = 0;
    for(auto c:s){
        if(c == prev){
            cnt++;
        }else{
            res += (long long)(cnt + 1) * cnt / 2;
            cnt = 1;
            prev = c;
        }
    }
    res += (long long)(cnt + 1) * cnt / 2;
    return res % mod;
}
int main(){
    string s;
    cin >> s;
    long long res = countHomogenous(s);
    cout << res << endl;
    system("pause");
}

posted @ 2022-08-30 19:18  程序员中最好的渔民  阅读(253)  评论(0)    收藏  举报