第二周集训题解

401. 二进制手表

https://leetcode.cn/problems/binary-watch/solutions/837337/er-jin-zhi-shou-biao-by-leetcode-solutio-3559/

思路:枚举时针的所有情况,已经秒针的所有情况。

代码:

#include<stdio.h>

class Solution {
public:
    vector<string> readBinaryWatch(int turnedOn) {
        int line1[] = {8 , 4 , 2 , 1} ;
        int line2[] = {32 , 16 , 8 , 4 , 2 , 1} ;
        vector<vector<int>> V1(100 , vector<int>()) , V2(100 , vector<int>()) ;
        for (int i = 0 ; i < (1 << 4) ; ++i) {
            int cnt = 0 ;
            int now = 0 ;
            for (int j = 0 ; j < 4 ; ++j) {
                if (i & (1 << j)) {
                    ++cnt ;
                    now += line1[j] ;
                }
            }
            if (now <= 11) {
                V1[cnt].push_back(now) ;
            }
        }
        for (int i = 0 ; i < (1 << 6) ; ++i) {
            int cnt = 0 ;
            int now = 0 ;
            for (int j = 0 ; j < 6 ; ++j) {
                if (i & (1 << j)) {
                    ++cnt ;
                    now += line2[j] ;
                }
            }
            if (now <= 59) {
                V2[cnt].push_back(now) ;
            }
        }
        vector<string> res ;
        for (int i = 0 ; i <= turnedOn ; ++i) {
            int j = turnedOn - i ;
            for (int k = 0 ; k < V1[i].size() ; ++k) {
                string now_res ;
                char tmp[100] ;
                sprintf(tmp , "%d" , V1[i][k]) ;
                now_res += tmp ;
                now_res += ":" ;
                for (int u = 0 ; u < V2[j].size() ; ++u) {
                    sprintf(tmp , "%02d" , V2[j][u]) ;
                    
                    res.push_back(now_res+tmp) ;
                }
            }
        }
        return res ;
    }
};

78. 子集

https://leetcode.cn/problems/subsets/description/

思路:直接暴力枚举所有情况即可

代码:

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>> res ;
        int n = nums.size() ;
        for (int i = 0 ; i < (1 << n) ; ++i) {
            vector<int> V ;
            for (int j = 0 ; j < n ; ++j) {
                if (i & (1 << j)) {
                    V.push_back(nums[j]) ;
                }
            }
            res.push_back(V) ;
        }
        return res ;
    }
};

46. 全排列

思路:用搜索的思路去遍历就好。STL有个很方便的东西next_permutation可以直接遍历

代码:

class Solution {
public:
    vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int>> res ;
        sort(nums.begin() , nums.end()) ;
        res.push_back(nums) ;
        while (next_permutation(nums.begin() , nums.end())) {
            res.push_back(nums) ;
        }
        return res ;
    }
};

22. 括号生成

https://leetcode.cn/problems/generate-parentheses/description/

思路:n的最大数量为8,那么字符串长度最长是16,且是8个左括号,8个右括号构成的。只需要全排列,然后判断其中哪些是符合要求的字符串即可。

代码:

bool check(string str) {
    int cnt = 0 ;
    for (int i = 0 ; i < str.size() ; ++i) {
        if (str[i] == '(') {
            ++cnt ;
        }
        else {
            --cnt ;
            if (cnt < 0) {
                return false ;
            }
        }
    }
    return true ;
}


class Solution {
public:
    vector<string> generateParenthesis(int n) {
        string now = "" ;
        for (int i = 0 ; i < n ; ++i) {
            now += '(' ;
        }
        for (int i = 0 ; i < n ; ++i) {
            now += ')' ;
        }
        sort(now.begin() , now.end()) ;
        vector<string> res ;
        while (true) {
            if (check(now)) {
                res.push_back(now) ;
            }
            if (next_permutation(now.begin() , now.end())) {
                continue ;
            }
            else {
                break ;
            }
        }
        return res ;
    }
};

17. 电话号码的字母组合

https://leetcode.cn/problems/letter-combinations-of-a-phone-number/

思路:

有点像全排列,也是去全排列组合

代码:


void solve(vector<string>& s , string& digits , int id , vector<string>& res , string& now) {
    if (id == digits.size()) {
        res.push_back(now) ;
        return ;
    }
    int yoho = (digits[id] - '0') ;
    for (int i = 0 ; i < s[yoho - 2].size() ; i++) {
        now += s[yoho - 2][i] ;
        solve(s , digits , id + 1 , res , now) ;
        now.pop_back() ;
    }
}

class Solution {
public:
    vector<string> letterCombinations(string digits) {

        string str = "" ;
        for (int i = 0 ; i < 26 ; ++i) {
            str += ('a' + i) ;
        }
        vector<int>l (10 , 3) ;
        vector<string> s ;
        l[7] = 4 ;
        l[9] = 4 ;
        int cnt = 0 ;
        vector<string> res ;
        if (digits == "") {
            return res ;
        }
        for (int i = 2 ; i <= 9 ; ++i) {
            s.push_back(str.substr(cnt , l[i])) ;
            cnt += l[i] ;
        }
        string now = "" ;
        solve(s , digits , 0 , res , now) ;
        return res ;
    }
};

89. 格雷编码

https://leetcode.cn/problems/gray-code/description/

思路:用了动态规划的思想。因为上一轮的是有效的,那么下一轮在上一轮的基础上补上一位就ok了,只需要上一轮的正序和上一轮的倒叙加前导1就可以了。

代码:

class Solution {
public:
    vector<int> grayCode(int n) {
        vector<vector<int>> res ;
        vector<int> now ;
        res.push_back(now) ;
        now.push_back(0) ;
        now.push_back(1) ;
        res.push_back(now) ;
        for (int i = 2 ; i <= 16 ; ++i) {
            now.clear() ;
            for (int j = 0 ; j < res[i - 1].size() ; ++j) {
                now.push_back(res[i - 1][j]) ;
            }
            for (int j = res[i - 1].size() - 1 ; j >= 0 ; --j) {
                now.push_back((1 << (i - 1)) + res[i - 1][j]) ;
            }
            res.push_back(now) ;
        }
        return res[n] ;
    }
};

93. 复原 IP 地址

思路:枚举每个点的位置,然后判断是否满足条件

代码:

vector<string> now ;
vector<string> res ;
void dfs(string& s , int id , int cnt) {
    if (cnt == 4) {
        string yoho = "" ;
        for (int i = 0 ; i < now.size() ; ++i) {
            yoho += "." ;
            yoho += now[i] ;
        }
        yoho = yoho.substr(1) ;
        res.push_back(yoho) ;
        return ;
    }
    if (cnt == 3) {
        string nowstr = s.substr(id) ;
        int nowint = atoi(nowstr.c_str()) ;
        if (nowint > 255) {
            return ;
        }
        string newstr = to_string(nowint) ;
        if (nowstr != newstr) {
            return ;
        }
        now.push_back(nowstr) ;
        dfs(s , id , cnt + 1) ;
        now.pop_back() ;
    }
    else 
    for (int i = 1 ; i + id < s.size() ; ++i) {
        string nowstr = s.substr(id , i) ;
        int nowint = atoi(nowstr.c_str()) ;
        if (nowint > 255) {
            continue ;
        }
        string newstr = to_string(nowint) ;
        if (nowstr != newstr) {
            continue ;
        }
        now.push_back(nowstr) ;
        dfs(s , id + i , cnt + 1) ;
        now.pop_back() ;
    }
}


class Solution {
public:
    vector<string> restoreIpAddresses(string s) {
        int n = s.size() ;
        now.clear() ;
        res.clear() ;
        dfs(s , 0 , 0) ;
        return res ;
    }
};

357. 统计各位数字都不同的数字个数

思路:对于长度为4的数字,第一位可以选9种,1~9。第二位可以选择9种,0以及1~9排除第一位,第三位可以选择8种,依次类推。

代码:

class Solution {
public:
    int countNumbersWithUniqueDigits(int n) {
        if (n == 0) return 1 ;
        int res = 0 ;
        for (int i = n ; i >= 1 ; --i) {
            if (i == 1) {
                res += 10 ;
                continue ;
            }
            int a = 9 ;
            int b = 9 ;
            for (int j = 0 ; j < i - 1 ; ++j) {
                a *= b ;
                b-- ;
            }
            res += a ;
        }
        return res ;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值