算法刷题打卡(七)

36 有效的数独

36. 有效的数独 - 力扣(LeetCode) (leetcode-cn.com)

请你判断一个 9x9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)

数独部分空格内已填入了数字,空白格用 '.' 表示。

注意:

  • 一个有效的数独(部分已被填充)不一定是可解的。
  • 只需要根据以上规则,验证已经填入的数字是否有效即可。

示例 1:

img

输入:board = 
[["5","3",".",".","7",".",".",".","."]
,["6",".",".","1","9","5",".",".","."]
,[".","9","8",".",".",".",".","6","."]
,["8",".",".",".","6",".",".",".","3"]
,["4",".",".","8",".","3",".",".","1"]
,["7",".",".",".","2",".",".",".","6"]
,[".","6",".",".",".",".","2","8","."]
,[".",".",".","4","1","9",".",".","5"]
,[".",".",".",".","8",".",".","7","9"]]
输出:true

示例 2:

输入:board = 
[["8","3",".",".","7",".",".",".","."]
,["6",".",".","1","9","5",".",".","."]
,[".","9","8",".",".",".",".","6","."]
,["8",".",".",".","6",".",".",".","3"]
,["4",".",".","8",".","3",".",".","1"]
,["7",".",".",".","2",".",".",".","6"]
,[".","6",".",".",".",".","2","8","."]
,[".",".",".","4","1","9",".",".","5"]
,[".",".",".",".","8",".",".","7","9"]]
输出:false
解释:除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。 
但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。

这个题是看 是否有效 ,不需要解出答案

    public boolean isValidSudoku(char[][] board) {
        boolean[][] rows = new boolean[9][10];//行是否有效
        boolean[][] colums = new boolean[9][10];//列.
        boolean[][] bucket = new boolean[9][10];//格.
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                int p = 3 * (i / 3) + (j / 3);//算出是第几个九宫格
                if (board[i][j] != '.') {
                    int num = board[i][j] - '0';
                    if (rows[i][num] || colums[j][num] || bucket[p][num]) {
                        return false;
                    }
                    rows[i][num] = true;
                    colums[j][num] = true;
                    bucket[p][num] = true;
                }
            }
        }
        return true;
    }

38 外观数列

38. 外观数列 - 力扣(LeetCode) (leetcode-cn.com)

给定一个正整数 n ,输出外观数列的第 n 项。

「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。

你可以将其视作是由递归公式定义的数字字符串序列:

countAndSay(1) = “1”
countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。
前五项如下:

  1. 1
    
  2. 11
    
  3. 21
    
  4. 1211
    
  5. 111221
    第一项是数字 1 
    描述前一项,这个数是 1 即 “ 一 个 1 ”,记作 "11"
    描述前一项,这个数是 11 即 “ 二 个 1 ” ,记作 "21"
    描述前一项,这个数是 21 即 “ 一 个 2 + 一 个 1 ” ,记作 "1211"
    描述前一项,这个数是 1211 即 “ 一 个 1 + 一 个 2 + 二 个 1 ” ,记作 "111221"
    要 描述 一个数字字符串,首先要将字符串分割为 最小 数量的组,每个组都由连续的最多 相同字符 组成。然后对于每个组,先描述字符的数量,然后描述字符,形成一个描述组。要将描述转换为数字字符串,先将每组中的字符数量用数字替换,再将所有描述组连接起来。
    

例如,数字字符串 “3322251” 的描述如下图:
在这里插入图片描述
示例 1:

输入:n = 1
输出:“1”
解释:这是一个基本样例。
示例 2:

输入:n = 4
输出:“1211”
解释:
countAndSay(1) = “1”
countAndSay(2) = 读 “1” = 一 个 1 = “11”
countAndSay(3) = 读 “11” = 二 个 1 = “21”
countAndSay(4) = 读 “21” = 一 个 2 + 一 个 1 = “12” + “11” = “1211”

读第N个数的时候 ,先把N-1 的知道 - 递归

    public String countAndSay(int n) {
        if (n < 1) {
            return "";
        }
        if (n == 1) {
            return "1";
        }
        char[] c = countAndSay(n - 1).toCharArray();
        StringBuilder sb = new StringBuilder();
        int time = 1;
        for (int i = 1; i < c.length; i++) {
            if (c[i - 1] == c[i]) {
                time++;
            } else {
                sb.append(String.valueOf(time));
                sb.append(String.valueOf(c[i - 1]));
                time = 1;
            }
        }
        sb.append(String.valueOf(time));
        sb.append(String.valueOf(c[c.length-1]));
        return sb.toString();
    }

41 缺失的第一个正数

41. 缺失的第一个正数 - 力扣(LeetCode) (leetcode-cn.com)

给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。

请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。

示例 1:

输入:nums = [1,2,0]
输出:3
示例 2:

输入:nums = [3,4,-1,1]
输出:2
示例 3:

输入:nums = [7,8,9,11,12]
输出:1

要求是 时间:O(N) 空间 O(1)

在数组中 i 位置存放 i+1值 负数 和大于 arr.length 的数属于捣乱项

    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    public int firstMissingPositive(int[] nums) {
        for (int i = 0; i < nums.length; i++){
            //nums[i]在1到 nums.length之间,就进行归位
            // nums[nums[i] - 1] != nums[i]   当前位置的值 例如 i = 3 存的值应该是4
            while (nums[i] > 0 && nums[i] <= nums.length && nums[nums[i] - 1] != nums[i]){
                swap(nums, i, nums[i] - 1);
            }
        }
        //遍历找到 缺失的
        for (int i = 0; i < nums.length; i++){
            if (nums[i] != i + 1) {
             return i + 1;
            }
        }
        return nums.length + 1;
    }

42 接雨水

42. 接雨水 - 力扣(LeetCode) (leetcode-cn.com)

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

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

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
示例 2:

输入:height = [4,2,0,3,2,5]
输出:9

i位置的水量 = i位置左侧 和右侧的最大值

辅助数组 : 左侧最大值 右侧最大值

二:双指针 0位置 和N 位置 不能保存水量,可以先把左侧最大值设置为0位置的值,右侧 N位置的值

那一侧小 结算那一侧

    public int trap(int[] height) {
        if (height.length < 2) {
            return 0;
        }
        int L = 1;
        int R = height.length - 2;
        int leftMax = height[0];//左侧最大值
        int rightMax = height[height.length - 1];//右侧最大值
        int ans = 0;
        while (L <= R) {
            if (leftMax < rightMax) {//左侧 < 右侧 ,结算左侧 看看要不要更新左侧最大值,L++
                ans += Math.max(leftMax - height[L], 0);
                leftMax = Math.max(leftMax, height[L++]);
            } else {//结算右侧 R--
                ans += Math.max(rightMax - height[R], 0);
                rightMax = Math.max(rightMax, height[R--]);
            }
        }
        return ans;
    }
  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值