#每日一题合集#牛客JZ13-JZ22

为了督促自己每天练一练编程
时间:2022年8月11日-2022年8月20日
网站:https://www.nowcoder.com/exam/oj/ta?tpId=13

8.11-JZ13.机器人的运动范围

在这里插入图片描述

        递归需要考虑的:
        1.边界:首先,由于坐标是从[0,0]到[rows-1,cols-1]的,因此最基础的就是不合法的数据(x < 0 || y < 0 || x >= rows || y >= cols);然后,就是题目的条件,“不能进入行坐标和列坐标的数位之和大于 threshold 的格子”,所以需要分解行列的位数再相加,这个就比较基础(getsum(x) + getsum(y) > threshold);最后,由于我们是统计格子数,因此需要判断,这个格子走没走过,没走过的才进入下一轮判断
        2.递归条件:这个就比较简单,就是这个格子,加上往上下左右四个方向的格子数,然后不断递归就可以啦。

class Solution {
public:
    bool visit[101][101];
    // 求和函数
    int getsum(int n){
        int sum = 0;
        while(n != 0){
            sum += n % 10;
            n = n / 10;
        }
        return sum;
    }
    //递归判断走路函数
    int Judge(int threshold, int rows, int cols, int x, int y){
        if(x < 0 || y < 0 || x >= rows || y >= cols || getsum(x) + getsum(y) > threshold || visit[x][y])
            return 0;
        visit[x][y] = 1;
        return Judge(threshold, rows, cols, x, y+1) +
            Judge(threshold, rows, cols, x, y-1) +
            Judge(threshold, rows, cols, x-1, y) +
            Judge(threshold, rows, cols, x+1, y) +1;
    }
    
    int movingCount(int threshold, int rows, int cols) {
        if(rows <= 0 || cols <= 0 || threshold < 0)
            return 0;
        int cnt = Judge(threshold, rows, cols, 0, 0);
        return cnt;
    }
};

8.12-JZ14.剪绳子

在这里插入图片描述
动态规划思路:一根绳子其中一段不可分的为j,那么如果另一段为n−j最大乘积已知,我们可以遍历所有j找到这个最大乘积。因此用dp[i]表示长度为i的绳子可以被剪出来的最大乘积,那么后续遍历每个j的时候,我们取dp[i]和j∗dp[i−j]的最大值就好了。

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param n int整型 
     * @return int整型
     */
    int cutRope(int n) {
        // write code here
        if(n <= 3)
            return n - 1;
        vector<int> dp(n + 1, 0);
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 3;
        dp[4] = 4;
        for(int i = 5; i <= n; i++){
            for(int j = 1; j < i; j++){
                dp[i] = max(dp[i], j * dp[i-j]);
            }
        }
        return dp[n];
    }
};

8.13-JZ15.二进制中1的个数

在这里插入图片描述

基础位与操作

class Solution {
public:
     int  NumberOf1(int n) {
         int res = 0;
         for(int i = 0; i < 32; i++){
             if(n & 1 != 0){
                 res++;
             }
             n = n >> 1;
         } 
         return res;
     }
};

8.14-JZ16.数值的整数次方


基础计算,就是多了负数的,转换一下即可

class Solution {
public:
    double Power(double base, int exponent) {
        double res = 1.0;
        if(exponent < 0){
            base = 1 / base;
            exponent = -exponent;
        }
        for(int i = 0; i < exponent; i++)
            res *= base;
        return res;
    }
};

8.15-JZ17.打印从1到最大的n位数

在这里插入图片描述

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param n int整型 最大位数
     * @return int整型vector
     */
    vector<int> printNumbers(int n) {
        // write code here
        vector<int> res;
        for(int i = 1; i < pow(10,n); i++)
            res.push_back(i);
        return res;
    }
};

8.16-JZ18.删除链表的节点

在这里插入图片描述
比较基础的链表操作

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 *	ListNode(int x) : val(x), next(nullptr) {}
 * };
 */
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 
     * @param val int整型 
     * @return ListNode类
     */
    ListNode* deleteNode(ListNode* head, int val) {
        // write code here
        ListNode* res = new ListNode(0);
        res->next = head;
        
        ListNode* pre = res;
        ListNode* cur = head;
        
        while(cur != NULL){
            if(cur->val == val){
                pre->next = cur->next;
                break;
            }
            pre = cur;
            cur = cur->next;
        }
        
        return res->next;
        
    }
};

8.17-JZ19.正则表达式匹配

在这里插入图片描述
这个参考了官方解析:
    首先,两个空串是直接匹配,因此dp[0][0]=true。然后利用*字符出现0次的特性,遍历pattern字符串,如果遇到*意味着它前面的字符可以出现0次,要想匹配空串也只能出现0,那就相当于考虑再前一个字符是否能匹配,因此dp[0][i]=dp[0][i−2]
     然后分别遍历str与pattern的每个长度,开始寻找状态转移。首先考虑字符不为*的简单情况,只要遍历到的两个字符相等,或是pattern串中为.即可匹配。因此只需要二者各自前一位能完成匹配,就有dp[i][j]=dp[i−1][j−1]。然后考虑*出现的情况:
        1.pattern前一位能够多匹配一位(pattern[j - 2] == '.' || pattern[j - 2] == str[i - 1]),匹配成功则转移dp[i][j]=dp[i−1][j]∣∣dp[i][j−2]
        2.不满足上述条件,即不匹配,让前一个字符出现0次,dp[i][j]=dp[i][j−2]

class Solution {
public:
    bool match(string str, string pattern) {
        int n1 = str.length();
        int n2 = pattern.length();
        //dp[i][j]表示str前i个字符和pattern前j个字符是否匹配
        vector<vector<bool> > dp(n1 + 1, vector<bool>(n2 + 1, false)); 
        //两个都为空串自然匹配
        dp[0][0] = true; 
        
        //初始化str为空的情况,字符串下标从1开始
        for(int i = 2; i <= n2; i++){ 
            if(pattern[i - 1] == '*') 
                dp[0][i] = dp[0][i - 2]; 
        }

        
        for(int i = 1; i <= n1; i++){ 
            for(int j = 1; j <= n2; j++){ 
                //当前字符不为*,用.去匹配或者字符直接相同
                if(pattern[j - 1] != '*' && (pattern[j - 1] == '.' || pattern[j - 1] == str[i - 1])){ 
                      dp[i][j] = dp[i - 1][j - 1];
                //当前的字符为*
                }else if(j >= 2 && pattern[j - 1] == '*'){ 
                    //若是前一位为.或者前一位可以与这个数字匹配
                    if(pattern[j - 2] == '.' || pattern[j - 2] == str[i - 1]) 
                        dp[i][j] = dp[i - 1][j] || dp[i][j - 2];  
                    else
                        dp[i][j] = dp[i][j - 2]; 
                }
            }
        }
        return dp[n1][n2];
    }
};

8.18-JZ20.表示数值的字符串

在这里插入图片描述
在这里插入图片描述
一道纯纯思路题,注意各个条件,具体见代码注释

class Solution {
public:
    //设计下标为全局变量,让下标一位位检查,检查通过后后移
    int index = 0;
  
    bool judge_integer(string& s){
        //空格后的符号可能是小数或者整数的一个符号('+'或'-')
        if(index < s.length() && (s[index] == '-' || s[index] == '+'))
            //如果有的话,一个是合法的,下标后移
            index++;
        return judge_un_integer(s);
    }
    
    bool judge_un_integer(string& s){
        int tmp = index;
        //数字有多少位都是合法的,因此不断判断后移
        while(index < s.length() && (s[index] >= '0' && s[index] <= '9'))
            index++;
        //如果下标没变化,说明没有数字
        return index > tmp;
        
    }
 
    bool isNumeric(string str) {
        //空串肯定不是数值
        if(str.length() == 0)
            return false;
        
        //由于数值前后都有若干空格,所以要先去空格
        //去前面的空格
        while(index < str.length() && str[index] == ' ')
            index++;
        //去后面的空格
        int n = str.length() - 1;
        while(n >= 0 && str[n] == ' ')
            n--;
        //这样最后就一个空格,以便最后检查遍历是否结束
        n++;
        //若是长度小于下标,说明全是空格,也不是数值
        if(index > n)
            return false;
        
        //判断是否是有符号数
        bool flag = judge_integer(str);
        //这时候index已经到了下一个非数字上了
        //如果有小数点
        if(index < n && str[index] == '.'){
            index++;
            //根据要求,小数点前面或者后面至少一个数字
            //前面已经判断完了,结果是flag,后面的再判断一次即可
            flag = judge_un_integer(str) || flag;//注意这里一定是后面的判断在前,因为或运算第一个为真时第二个条件是不计算的
        }
        //如果是e
        if(index < n && (str[index] == 'e' || str[index] == 'E')){
            index++;
            //e后面要跟着一个整数
            flag = flag && judge_integer(str);

        }
        //确认遍历结束
        flag = flag && (index == n);
        
        return flag;
    }
};

8.19-JZ21.调整数组顺序使奇数位于偶数前面(一)

在这里插入图片描述

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param array int整型vector 
     * @return int整型vector
     */
    vector<int> reOrderArray(vector<int>& array) {
        // write code here
        int n = array.size();
        vector<int> res(n);
        int odd = 0;
        for(int i = 0 ; i < n; i++){
            if(array[i] % 2)
                odd++;
        }
        int x = 0, y = odd;
        for(int i = 0; i < n; i++){
            if(array[i] % 2){
                res[x] = array[i];
                x++;
            }
            else{
                res[y] = array[i];
                y++;
            }
        }
        return res;
    }
};

8.20-JZ22.链表中倒数最后k个结点

在这里插入图片描述
经典快慢指针问题

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pHead ListNode类 
     * @param k int整型 
     * @return ListNode类
     */
    ListNode* FindKthToTail(ListNode* pHead, int k) {
        // write code here
        ListNode* fast = pHead;
        ListNode* slow = pHead;
        
        for(int i = 0; i < k; i++){
            if(fast != NULL)
                fast = fast->next;
            else 
                return NULL;
        }
        
        while(fast != NULL){
            fast = fast->next;
            slow = slow->next;
        }
        return slow;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值