高质量代码篇——代码的完整性

这篇博客聚焦于面试中常见的算法问题,包括数值的整数次方、打印最大n位数、删除链表节点、正则表达式匹配以及调整数组顺序等。每个问题都提供了原题链接及解决方案,帮助提升编程技能和解决问题的能力。

面试题16:数值的整数次方:

原题链接

class Solution {
public:
    double myPow(double x, int n) {
    /*
    思路:本题主要考点在于代码的完整性,解题时需要注意尽可能地考虑到边界情况和特例
    */
        long int Ln = (long int)n;  // 注意n的取值范围,为int的最小值时直接乘以-1转为正数会出错
        if(abs(x - 0.0) < 0.0000001)
            return 0;
        if(Ln == 0)
            return 1.0;

        int neg = (n < 0) ? 1 : -1;   // 标识是否是负次幂
        if(Ln < 0)
            Ln *= -1;

        if(neg == 1)
            return 1.0/Pow(x, Ln);
        else
            return Pow(x, Ln);
    }
    double Pow(double x, long int n){
    	// 快速幂
        if(n == 0)
            return 1;
        double ans = 1;
        if(n % 2 == 1)
            ans *= x;
        double temp = Pow(x, n/2);
        return ans*temp*temp;
    }
};

面试题17:打印从1到最大的n位数

原题链接
python3答案:

class Solution:
    def printNumbers(self, n: int) -> List[int]:
        return [i for i in range(1, int(str("9"*n))+1)]

增加难度:n可以任意大,使用递归求解,为了方便输出从0开始

class Solution {
public:
    void PrintOut(string num){
        int i = 0;
        while(i < num.size() && num[i] == '0')
            i++;
        for(;i < num.size(); i++)
            cout << num[i];
        cout << endl;
        // cout << num << endl;
    }

    void helper(string s, int index){
        if(index == s.size()){
            PrintOut(s);
            return ;
        }        
        for(int i = 0;i < 10; i++){
            s[index] = '0' + i;
            helper(s, index+1);
        }

    }

    vector<int> printNumbers(int n) {
    /*思路:从最高位开始,每一位都从0变到9,最后一位设置完成后再输出。
    */
       string num(n, '0');
       vector<int> ans;
       for(int i = 0;i < 10; i++){
           num[0] = '0' + i;
           helper(num, 1);
       }
       return ans;
    }
};

面试题18:删除链表的节点

原题链接

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* deleteNode(ListNode* head, int val) {
    	/*思路:构建一个新head,它的next指向传入的head,不断检查next的val,如果是目标值则直接删除,删除完成后返回新head的next。
    	*/
        ListNode* newHead = new ListNode(0);
        ListNode* newHeadCopy = newHead;
        newHead->next = head;
        while(newHead->next != NULL){
            if(newHead->next->val == val){
                newHead->next = newHead->next->next;
                break;
            }
            newHead = newHead->next;
        }
        ListNode* ans = newHeadCopy->next;
        delete newHeadCopy;
        return ans;
    }
};

面试题19:正则表达式匹配

原题链接

class Solution {
public:
    bool isMatch(string s, string p) {
    /*
    思路:动态规划,考虑p和s最后一个字母的各种情况,根据子问题isMatch(s[:slen-1], p[:plen-1])的答案,得到当前问题的答案。
    时间复杂度 O(n^2)
    空间复杂度 O(n^2)
    */
        int slen = s.size();
        int plen = p.size();

        if(plen == 0)
            return slen == 0;

        vector<vector<bool> > dp(plen+1, vector<bool>(slen+1, false));

        for(int i = 0;i <= plen; i++){
            for(int j = 0;j <= slen; j++){
                if(i == 0 && j == 0)
                    dp[i][j] = true;
                else if(i == 0)
                    dp[i][j] = false;
                else if(j == 0){
                    if(p[i-1] == '*'){
                        dp[i][j] = dp[i][j] || dp[i-2][j];
                    }
                }
                else{
                    if(p[i-1] == s[j-1] || p[i-1] == '.')
                        dp[i][j] = dp[i][j] || dp[i-1][j-1];
                    if(p[i-1] == '*'){
                        dp[i][j] = dp[i][j] || dp[i-2][j];
                        if(s[j-1] == p[i-2] || p[i-2] == '.')
                            dp[i][j] = dp[i][j] || dp[i-1][j-1] || dp[i][j-1];
                    }
                }
            }
        }

        return dp[plen][slen];
    }
};

面试题20:表示数值的字符串

原题链接
略显拙略的版本

class Solution {
public:
    bool checkNumber(string number, bool canBeFloat){
        if(number.size() == 0)
            return false;
        if(!canBeFloat){
            int i = 0;
            if(number[i] == '+' || number[i] == '-')
                i++;
            if(i == number.size())  // 只有正负号
                return false;
            while(i < number.size() && isdigit(number[i]))
                i++;
            return i == number.size();
        }
        else{
            int i = 0;
            while(i < number.size() && isdigit(number[i]))
                i++;
            if(i == number.size())
                return true;
            if(number[i] == '.')
                i++;
            if(i == 1 && number.size() == 1)  // 只有小数点
                return false;
            while(i < number.size() && isdigit(number[i]))
                i++;
            return i == number.size();
        }
    }
    bool isNumber(string s) {
        int slen = s.size();
        if(slen == 0)
            return true;
        // 去除字符串首尾的空格
        int i = 0, j = slen-1;
        while(i < slen && s[i] == ' ')
            i++;
        while(j >= 0 && s[j] == ' ')
            j--;
        s = s.substr(i, j-i+1);

        // 去除符号
        if(s[0] == '-' || s[0] == '+')
            s = s.substr(1, slen-1);
        
        // 找到e的位置
        int e_index = -1;
        for(int i = 0;i < s.size(); i++){
            if(s[i] == 'e'){
                e_index = i;
                break;
            }
        }
        if(e_index != -1){
            string base = s.substr(0, e_index);
            string exp = s.substr(e_index+1, s.size()-e_index-1);
            return checkNumber(base, true) && checkNumber(exp, false);
        }
        else{
            return checkNumber(s, true);    
        }
            
    }
};

面试题21:调整数组顺序使奇数位于偶数前面

原题链接

class Solution {
public:
    vector<int> exchange(vector<int>& nums) {
        int len = nums.size();
        if(len <= 1)
            return nums;
        int i = 0, j = len-1;

        while(1){
            while(i < len && nums[i] % 2 == 1)
                i++;
            while(j >= 0 && nums[j] % 2 == 0)
                j--;
            if(i > j)
                break;
            else
                swap(nums[i], nums[j]);
        }
        return nums;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值