每日一题补题记录6

这篇博客探讨了如何在编程问题中运用数学和算法。首先,通过欧几里得算法计算最简分数,接着讨论了在限制条件下最小化学生分数差值的问题。最后,介绍了一种使用多源BFS寻找二进制矩阵中飞地数量的方法。这些示例展示了数学和算法在解决实际编程挑战中的重要性。
摘要由CSDN通过智能技术生成

2.10

1447. 最简分数

给你一个整数 n ,请你返回所有 0 到 1 之间(不包括 0 和 1)满足分母小于等于 n最简 分数 。分数可以以 任意 顺序返回。

这里要搞清楚最简分数的定义,也就是分子分母的最大公约数为1的分数,因为我们i/j递增,可以确保不会有重复分数,只需要满足最简即可,想要计算最大公约数,我们使用欧几里得算法gcd,

也就是gcd(x,y)=gcd(y,x%y),如果xy可以整除返回较小数即可,我们始终保证大数在前。

class Solution {
    public List<String> simplifiedFractions(int n) {
        List<String>ans=new ArrayList<>();
        for(int i=1;i<n;i++){
            for(int j=i+1;j<=n;j++){
                if(gcd(j, i)==1)
                ans.add(i+"/"+j);
            }
        }
        return ans;
    }
    int gcd(int x,int y){
        if(x%y==0)return y;
        return gcd(y,x%y);
    }
}

2.11

1984. 学生分数的最小差值

给你一个 下标从 0 开始 的整数数组 nums ,其中 nums[i] 表示第 i 名学生的分数。另给你一个整数 k 。

从数组中选出任意 k 名学生的分数,使这 k 个分数间 最高分 和 最低分 的 差值 达到 最小化 。

返回可能的 最小差值 。

class Solution {
    public int minimumDifference(int[] nums, int k) {
        //剪枝
        if(k==1)return 0;
        //升序排列,我们选定一个大小为k的滑动窗口
        //窗口两端的数值差,对应当前窗口极差
        //最小极差即为我们所求答案
        Arrays.sort(nums);
        int n=nums.length,ans=Integer.MAX_VALUE;
        for(int i=0;i<=n-k;i++){
            ans=Math.min(ans,nums[i+k-1]-nums[i]);
        }
        return ans;
    }
}

2.12

1020. 飞地的数量

给你一个大小为 m x n 的二进制矩阵 grid ,其中 0 表示一个海洋单元格、1 表示一个陆地单元格。

一次 移动 是指从一个陆地单元格走到另一个相邻(上、下、左、右)的陆地单元格或跨过 grid 的边界。

返回网格中 无法 在任意次数的移动中离开网格边界的陆地单元格的数量。

方法:多源BFS

统计所有陆地块数cnt,从边界的陆地开始BFS,每找到一块陆地,cnt--即可

class Solution {
    int[][]dirs=new int[][]{{0,1},{0,-1},{1,0},{-1,0}};
    public int numEnclaves(int[][] grid) {
        int m=grid.length,n=grid[0].length;
        //防止重复访问
        boolean[][]visited=new boolean[m][n];
        //首先记录所有陆地数目
        int cnt=0;
        //BFS搜索所有在边界的陆地
        //总数目-边界可达陆地数=飞地数目
        Deque<int[]>queue=new LinkedList<>();
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(grid[i][j]==1){
                    cnt++;
                    if(i==0||i==m-1||j==0||j==n-1){
                        queue.offer(new int[]{i,j});
                        visited[i][j]=true;
                    }
                }
            }
        }
        System.out.println("陆地块数"+cnt);
        while(!queue.isEmpty()){
            //可以连接到边界的陆地,数目--
            int[]cur=queue.poll();
            int x=cur[0],y=cur[1];
            System.out.println("可达陆地坐标("+x+","+y+")");
            cnt--;
            for(int[]dir:dirs){
                int dx=x+dir[0],dy=y+dir[1];
                if(dx<0||dx>=m||dy<0||dy>=n)continue;
                if(visited[dx][dy])continue;
                if(grid[dx][dy]==1){
                    queue.offer(new int[]{dx,dy});
                    visited[dx][dy]=true;
                }
            }
        }
        return cnt;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值