LeetCode刷题记 / 36 / 53 / 86

1.每日吐槽

。。。没什么可吐槽的,昨天的每日一题是困难类型的,直接copy了,自己现在还没有能力去解决困难难度的题目,所以也就没有记录下来了

2.leetcode每日一题

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

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 ‘.’ 表示。
在这里插入图片描述


public class Solution36 {
    public boolean isValidSudoku(char[][] board) {
        //直接上暴力
        //先判断行是否符合
        for(char []row : board){
            boolean []isLive = new boolean[9];
            for(char ch : row){
                if(ch != '.'){
                    if(!isLive[ch - '1']){
                        isLive[ch - '1'] = true;
                    }else {
                        return false;
                    }
                }
            }
        }
        //判断列是否符合条件
        for(int i = 0;i < 9;i++){
            boolean []isLive = new boolean[9];
            for(int j = 0;j < 9;j++){
                if(board[j][i] != '.'){
                    if(!isLive[board[j][i] - '1']){
                        isLive[board[j][i] - '1'] = true;
                    }else {
                        return false;
                    }
                }
            }
        }
        //判断九宫格是否符合条件
        for(int i = 0;i < 9;i++){
            int x = (i) / 3 * 3;
            int y = 6;
            if((i  + 1) % 3 == 1){
                y = 0;
            }
            if((i + 1) % 3 == 2){
                y = 3;
            }
            boolean []isLive = new boolean[9];
            for(int r = x;r < x + 3;r++){
                for(int c = y;c < y + 3;c++){
                    if (board[r][c] != '.') {
                        if(!isLive[board[r][c] - '1']){
                            isLive[board[r][c] - '1'] = true;
                        }else {
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }
}

今天的每日一题挺简单的,简单易懂,但是leetcode的官方题解一次遍历算是惊讶到我了,很nice

3. 53 最大子序和

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
在这里插入图片描述

class Solution {
    public int maxSubArray(int[] nums) {
        int ans = nums[0];
        int sum = 0;
        for(int num: nums) {
            if(sum > 0) {
                sum += num;
            } else {
                sum = num;
            }
            ans = Math.max(ans, sum);
        }
        return ans;
    }
}

万恶的动态规划。。。。

这题还有个版本,就是需要标记到最大子序的开始和结束下标。

大致题意:

最大子段和问题。给定由n个整数组成的序列,求序列中子段的最大和,若所有整数均为负整数时定义最大子段和为0。
例如, 当(a1,a2,a3,a4 ,a5,a6) = (-2,11,-4,13,-5,-2)时,最大子段和为: a2+a3+a4=20
输入格式:
第一行输入整数个数n(1≤n≤10000),再依次输入n个整数。
输出格式:
输出第一行为最大子段和,第二行为子段第一个数和最后一个数在整个序列中的位序。
输入样例1:
6
-2 11 -4 13 -5 -2
输出样例1:
20
2 4

附上代码:


public class SubSum {
    void maxSubSum(int n,int []nums){
        int pre = 0;
        int []ans = new int[3];       //分别存储最大值,最大值对应的第一个下标和第二个下标
        ans[0] = nums[0];
        int left = 0;
        int right = 0;
        for(int i = 0;i < n;i++){
            if(pre > 0){
                pre = pre + nums[i];
                right = i;
            }else if(pre <= 0){
                pre = nums[i];
                left = i;
            }
            if(ans[0] < pre){
                ans[0] = pre;
                ans[1] = left;
                ans[2] = right;
            }

        }
        if(ans[0] > 0){
            System.out.println(ans[0]);
            System.out.println((ans[1] + 1) + " " + (ans[2] + 1));
        }else {
            System.out.println(0);
            System.out.println(0 + " " + 0);
        }

    }
}

4. 86 分隔链表

给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。

你应当 保留 两个分区中每个节点的初始相对位置。

在这里插入图片描述

不考虑在源链表上进行操作的话还算是简单吧。
先建立一个哑节点,然后依次遍历链表,大于x的放在哑节点后面,小于的放在哑节点前面,注意两种节点的插入方式就像,然后删除哑节点。当然除此之外还要有个头节点的标记,不然完成分隔链表后找不到头节点。

代码:


import LeetCode.ListNode;

public class Solution86 {
    public ListNode partition(ListNode head, int x) {

        ListNode dumb = new ListNode();
        ListNode first = dumb;
        ListNode end = new ListNode();
        end.next = dumb;
        ListNode root = end;
        boolean isHead = false;
        while (head != null){
            if(head.val >= x){
                first.next = new ListNode(head.val);
                first = first.next;
            }else {
                ListNode store = new ListNode(head.val);
                store.next = dumb;
                end.next = store;
                end = store;
                if(!isHead){
                    root = end;
                    isHead = true;
                }
            }
            head = head.next;
        }
        end.next = end.next.next;


        return !isHead ? end.next : root;
    }
}

//这里有个LeetCode.ListNode包是自己根据LeetCode的节点要求建立的
//package LeetCode;
//
//public  class ListNode {
//        public int val;
//       public LeetCode.ListNode next;
//        public ListNode() {}
//        public ListNode(int val) { this.val = val; }
//        public ListNode(int val, LeetCode.ListNode next) { //this.val = val; this.next = next; }
//}

还有个是在原链表上操作的,考虑没什么时间了,明天或者后天有空想到再写吧,难度应该也不是很大。

OVER

2021/09/17 23:33

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值