力扣练习

  • 时间:
  • 浏览:
  • 来源:互联网

力扣练习

时间太紧,接下来尽量周更来确保学习质量。接下来一段时间要做学校的项目,可能会没有时间更新。希望不偷懒吧。

废话少说,先看看这些天遇到的有趣的题目。

题目1:

8 字符串转换整数 (atoi)
请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。

函数 myAtoi(string s) 的算法如下:

读入字符串并丢弃无用的前导空格
检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
将前面步骤读入的这些数字转换为整数(即,“123” -> 123, “0032” -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。
返回整数作为最终结果。
注意:

本题中的空白字符只包括空格字符 ’ ’ 。
除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。

链接:https://leetcode-cn.com/problems/string-to-integer-atoi

示例1:

输入:s = "42"
输出:42

示例2:

输入:s = "   -42"
输出:-42

示例3:

输入:s = "4193 with words"
输出:4193

示例4:

输入:s = "words and 987"
输出:0

解析:这题不是很难,就是字符串转整形并且在转的过程中判断该字符串是否为合法整形。
判断依据:

  1. 是否第一个字符串是非数字,非 ’ ‘,’-’,’+’。
  2. 字符串是否含有连续的正负号
  3. 是否含有字母,遇到则后续不做判断
  4. 若为正确的整形,遇到’.'则忽略 退出
  5. 若整形超过了int类型的上下界值,则返回上下界

程序如下:

int myAtoi(char * s){
    if(!(s[0] >= '0' && s[0] <= '9') && s[0] != ' ' && s[0] != '-' && s[0] != '+'){
        return 0;
    }
    int flag = 1;
    int count = 0;
    int num = 0;
    long long sum = 0;
    for(int i = 0;i < strlen(s);++i){
        if(num == 1 && (s[i] == '+' || s[i] == '-' || s[i] == ' ')){
            break;
        }
        if((s[i] == '+' || s[i] == '-') && !(s[i+1] >= '0' && s[i+1] <= '9')){
            break;
        }
        if(s[i] == ' ' || s[i] == '+'){
            if(s[i] == '+'){
                count++;
            }
            continue;
        }else if(s[i] == '-'){
            count++;
            flag = -1;
        }else if(!(s[i] >= '0' && s[i] <= '9') || s[i] == '.' || count == 2){
            break;
        }else{
            sum = sum * 10 + s[i] - '0';
            num = 1;
            if(flag == -1 && -sum < -2147483647){
                return -2147483647 - 1;
            }else if(flag == 1 && sum >= 2147483647){
                return 2147483647;
            }
        }
    }
    if(flag == -1){
        return -sum;
    }
    return sum;
}

题目2:

240 搜索二维矩阵 II
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:

每行的元素从左到右升序排列。
每列的元素从上到下升序排列。

链接:https://leetcode-cn.com/problems/search-a-2d-matrix-ii

示例1:
在这里插入图片描述

输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5
输出:true

示例2:
在这里插入图片描述

输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 20
输出:false

解析1:

这题我首先会想到线性代数的主对角线,通过判断主对角线的值来确定判断位置。首先观察矩阵如果要找20这个数,只比最右下角的数字小,所以必定在最后一排于最后一列。但是并不是所有的数字都满足答案必在首次遇到主对角线上的最大数的行于列上。比如说我要找15,我首次遇到主对角线最大的是17,在17对应的行于列中并没有15这个数,但是矩阵中有。所以要判断从17开始(包含17所在)的行与列是否存在要寻找的数字。而且还要考虑非方阵的情况,关于这个又有很对点,直接看代码就好。

程序如下:

bool searchMatrix(int** matrix, int matrixSize, int* matrixColSize, int target){
    if(target < matrix[0][0] || target > matrix[matrixSize-1][*matrixColSize-1]){
        return false;
    }
    int wai = matrixSize < *matrixColSize ? matrixSize : *matrixColSize;
    for(int i = 0;i < wai;++i){
        if(matrix[i][i] == target){
            return true;
        }else if(matrix[i][i] > target){// 当首次主对角线遇到大于所需数时候
            for(int j = i-1;j >= 0;--j){
                if(matrix[i][j] == target || matrix[j][i] == target){// 查找遇到的数所在的行与列
                    return true;
                }
            }
            // 查询之后的列
            for(int j = i+1;j < *matrixColSize;++j){
                for(int k = i-1;k >= 0;--k){
                    if(matrix[k][j] == target){
                        return true;
                    }
                }
            }
            // 查询之后的行
            for(int j = i;j < matrixSize;++j){
                for(int k = i-1;k >= 0;--k){
                    if(matrix[j][k] == target){
                        return true;
                    }
                }
            }
            return false;
        }else if(i == matrixSize-1 || i == *matrixColSize-1){
        // 当行到尽头或者是列到尽头还是没有找到对应的值,那么就需要向又移动或者向下移动。
            int x = matrixSize-1 == i ? *matrixColSize-1 : matrixSize-1;
            if(i == matrixSize-1){
                for(int j = x;j > i;--j){
                    for(int k = i;k >= 0;--k){
                        if(matrix[k][j] == target){
                            return true;
                        }
                    }
                }
                return false;
            }else{
                for(int j = x;j > i;--j){
                    for(int k = i;k >= 0;--k){
                        if(matrix[j][k] == target){
                            return true;
                        }
                    }
                }
                return false;
            }
        }
    }
    return false;
}

解析2:

解析1中我忽略了一个点,一行的最大在最右边,一列的最大在最左边。那么我们直接从最右边或者最下边开始查找,遇到小的就向下移动,遇到大的就向右移动,直到到达了边界(最左,最下)位置。若这期间找到了直接返回true,若直到退出都没找到则返回false。

程序如下:

bool searchMatrix(int** matrix, int matrixSize, int* matrixColSize, int target){
    if(target < matrix[0][0] || target > matrix[matrixSize-1][*matrixColSize-1]){
        return false;
    }else if(target == matrix[0][0] || target == matrix[matrixSize-1][*matrixColSize-1]){
        return true;
    }
    for(int i = 0;i < matrixSize;++i){
        if(matrix[i][*matrixColSize-1] == target){
            return true;
        }else if(matrix[i][*matrixColSize-1] > target){
            int x = i;
            int y = *matrixColSize-2;
            while(x != matrixSize && y >= 0){
                if(matrix[x][y] == target){
                    return true;
                }else if(matrix[x][y] < target){
                    x++;
                }else{
                    y--;
                }
            }
            return false;
        }
    }
    return false;
}

若有错误请指出

本文链接http://www.dzjqx.cn/news/show-617116.html