day66-day67-day68-day69【代码随想录】二刷链表


前言

1、交错字符串
2、移除链表元素
3、反转链表
4、反转链表||
5、赢得比赛需要的最少训练时长
6、给定行和列的和求可行矩阵
7、最大网络秩
8、统计中位数为 K 的子数组

一、交错字符串(力扣97)【动态规划】****

在这里插入图片描述
在这里插入图片描述

class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {  
        int ss1 = s1.length();
        int ss2 = s2.length();
        int ss3 = s3.length();
        if(ss1+ss2!=ss3) return false;

        boolean[][] dp = new boolean[ss1+1][ss2+1];
        dp[0][0] = true;
        //初始化
        for(int i=1;i<=ss1 && s1.charAt(i-1)==s3.charAt(i-1);i++){
            dp[i][0] = true;
        }

        for(int j=1;j<=ss2 && s2.charAt(j-1)==s3.charAt(j-1);j++){
            dp[0][j] = true;
        }

        for(int i=1;i<=ss1;i++){
            for(int j=1;j<=ss2;j++){
                dp[i][j] = (dp[i-1][j] && s1.charAt(i-1)==s3.charAt(i+j-1)) || (dp[i][j-1]&& s2.charAt(j-1)==s3.charAt(i+j-1));               
            }
        }
        return dp[ss1][ss2];
    }
}

二、移除链表元素(力扣203)

在这里插入图片描述
分析:
需要定义一个头节点!(为了方便操作,不需要单独处理头节点)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        if(head==null) return head;
        ListNode p,pre;
        //增加头节点
        ListNode dummy = new ListNode(-1,head);
        dummy.next = head;
        pre = dummy;
        p=pre.next;
        while(p!=null){
            if(p.val==val){
                pre.next = p.next;
            }
            else{
                pre = p;
            }
            p=pre.next;
        }
        return dummy.next;
    }
}

三、反转链表(力扣206)

在这里插入图片描述
分析:

请添加图片描述
递归:
题解来源:大佬题解

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        if(head==null) return null;
       if(head.next==null){
           return head;
       }
       ListNode last = reverseList(head.next);
       head.next.next = head;
       head.next=null;
       return last;
    }
}

四、反转链表||(力扣92)

在这里插入图片描述
分析:
与上一题思路基本一致

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    ListNode succesor = null;
    public ListNode reverseBetween(ListNode head, int left, int right) {
        if(left==1){
            return reverseN(head,right);
        }
        head.next = reverseBetween(head.next,left-1,right-1);
        return head;
    }

    public ListNode reverseN(ListNode head, int n) {
        if(n==1) {
            succesor = head.next;
            return head;
        }
        ListNode last = reverseN(head.next,n-1);
        head.next.next = head;
        head.next = succesor;
        return last;
    }
}

每日一题day66:赢得比赛需要的最少训练时长(力扣2383)

在这里插入图片描述
在这里插入图片描述
模拟:
把过程顺下来

class Solution {
    public int minNumberOfHours(int initialEnergy, int initialExperience, int[] energy, int[] experience) {
        int hour = 0;
        int ehour = 0;
        int res = 0;
        int sum = 0;
        //精力值:
        for(int i=0;i<energy.length;i++){
            sum+=energy[i];
        }
        if(initialEnergy<=sum){
            hour = sum-initialEnergy+1;
        }
        int trainingTime = 0;
        //经验值:
        for(int i=0;i<experience.length;i++){
            if(initialExperience-experience[i]>0){
                //可以打败 收获经验值即可
                initialExperience += experience[i];
            }else{
                    //打败不了 计算需要多长时间训练
                    ehour += experience[i] - initialExperience+1;
                    trainingTime = experience[i] - initialExperience+1;
                    //训练完后 初始值发生了变化 可以打败了
                    initialExperience += trainingTime + experience[i];
            }
        }
        res = hour+ehour;
        return res;
    }
}

每日一题day67:给定行和列的和求可行矩阵【力扣1605】

在这里插入图片描述
**分析:**模拟过程即可

class Solution {
    public int[][] restoreMatrix(int[] rowSum, int[] colSum) {
        int m = rowSum.length;
        int n = colSum.length;
        int[][] res = new int[m][n];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(rowSum[i]<=colSum[j]){
                    res[i][j] = rowSum[i];
                    colSum[j] = colSum[j]-rowSum[i];
                    rowSum[i] -= res[i][j]; 
                }else{
                    res[i][j] = colSum[j];
                    rowSum[i] = rowSum[i]-colSum[j];
                    colSum[j] -= res[i][j];
                }
            }
        }
        return res;
    }
}

每日一题day68:最大网络秩(力扣1615)

在这里插入图片描述
分析:
其实就是两个结点之间的度数之和
需要注意的是:
在这里插入图片描述

class Solution {
    public int maximalNetworkRank(int n, int[][] roads) {
        boolean[][] connect = new boolean[n][n];
        int[] degree = new int[n]; //度数
        for(int[] v:roads){ //一条无向边
            connect[v[0]][v[1]]=true;
            connect[v[1]][v[0]]=true;
            degree[v[0]]++;
            degree[v[1]]++;
        }

        int maxRank = 0;
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                int rank=degree[i]+degree[j]-(connect[i][j]==true?1:0);
                maxRank = Math.max(maxRank,rank);
            }
        }
        return maxRank;

    }
}

每日一题day69:统计中位数为 K 的子数组(力扣2488)【前缀和+哈希表】

在这里插入图片描述
在这里插入图片描述
分析:
连续数组问题一定要想想前缀和!!!
在这里插入图片描述
在这里插入图片描述

大佬题解

class Solution {
    public int countSubarrays(int[] nums, int k) {
        //前缀和+哈希表
        HashMap<Integer,Integer> map = new HashMap<>();
        map.put(0,1);

        int index =0;
        //先找k在num数组中所在的位置
        for(int i=0;i<nums.length;i++){
            if(nums[i]==k)
                index = i;
        }
        int preLeft =0;
        int res =0;
        //左边已经准备好了
        for(int i=index-1;i>=0;i--){
            preLeft+=nums[i]>k?-1:1;
            map.put(preLeft,map.getOrDefault(preLeft,0)+1);
        }
        //开始计算右边
        int preRight =0;
        if(map.containsKey(0)){
            res+=map.get(0);
        }
        if(map.containsKey(-1)){
            res+=map.get(-1);
        }

        for(int i=index+1;i<nums.length;i++){
            preRight+=nums[i]<k?-1:1;
            if(map.containsKey(preRight)){
                res+=map.get(preRight);
            }
            if(map.containsKey(preRight-1)){
                res+=map.get(preRight-1);
            }
        }
        return res;
    }
}

注意:
计算左边map值时不是从左到右 ,而是需要从k值所在下标开始–一直到0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值