2025-03-15:判断矩形的两个角落是否可达。用go语言,给定两个正整数 xCorner 和 yCorner,以及一个二维整数数组 circles,表示若干

2025-03-15:判断矩形的两个角落是否可达。用go语言,给定两个正整数 xCorner 和 yCorner,以及一个二维整数数组 circles,表示若干个圆的信息。判断是否存在一条从矩形的左下角到右上角的路径,这条路径完全在矩形内部,不会触碰或经过任何圆的内部和边界,只在起点和终点与矩形接触。如果存在这样的路径返回true,否则返回false。

3 <= xCorner, yCorner <= 1000000000。

1 <= circles.length <= 1000。

circles[i].length == 3。

1 <= xi, yi, ri <= 1000000000。

输入:X = 3, Y = 4, circles = [[2,1,1]]。

输出:true。

黑色曲线表示一条从 (0, 0) 到 (3, 4) 的路径。

题目来自leetcode3235。

大体步骤如下:

1.定义一个函数 canReachCorner,用于判断矩形的两个角落是否可达。

2.初始化一个记录圆是否被访问过的布尔数组 visited,长度为圆的数量。

3.定义深度优先搜索函数 dfs,用于遍历圆并判断是否存在可达路径。

4.实现函数 pointInCircle,用于判断点是否在圆内部。

5.实现函数 circleIntersectsTopLeftOfRectangle,用于判断圆是否与矩形左上角相交。

6.实现函数 circleIntersectsBottomRightOfRectangle,用于判断圆是否与矩形右下角相交。

7.实现函数 circlesIntersectInRectangle,用于判断两个圆是否在矩形内相交。

8.实现函数 abs,用于求取整数的绝对值。

9.在 main 函数中,给定矩形边界和圆的信息,调用 canReachCorner 函数判断路径是否可达,并输出结果。

总的时间复杂度分析:

  • 遍历圆的过程中,需要对每个圆进行判断和搜索,因此最坏情况下时间复杂度为 O(N^2),其中 N 为圆的数量。

  • 在判断点是否在圆内、判断圆与矩形相交等操作中,时间复杂度为 O(1)。

  • 因此总的时间复杂度为 O(N^2),其中 N 为圆的数量。

总的额外空间复杂度分析:

  • 程序中额外使用了 visited 数组来记录圆是否被访问过,其大小与圆的数量成正比,因此额外空间复杂度为 O(N),其中 N 为圆的数量。

Go完整代码如下:

go 复制代码
package main

import (
	"fmt"
)

func canReachCorner(xCorner int, yCorner int, circles [][]int) bool {
	visited := make([]bool, len(circles))

	var dfs func(i int) bool
	dfs = func(i int) bool {
		x1, y1, r1 := circles[i][0], circles[i][1], circles[i][2]
		if circleIntersectsBottomRightOfRectangle(x1, y1, r1, xCorner, yCorner) {
			return true
		}
		visited[i] = true
		for j := 0; j < len(circles); j++ {
			if !visited[j] && circlesIntersectInRectangle(x1, y1, r1, circles[j][0], circles[j][1], circles[j][2], xCorner, yCorner) && dfs(j) {
				return true
			}
		}
		return false
	}

	for i := range circles {
		x, y, r := circles[i][0], circles[i][1], circles[i][2]
		if pointInCircle(0, 0, x, y, r) || pointInCircle(xCorner, yCorner, x, y, r) {
			return false
		}
		if !visited[i] && circleIntersectsTopLeftOfRectangle(x, y, r, xCorner, yCorner) && dfs(i) {
			return false
		}
	}
	return true
}

func pointInCircle(px, py, x, y, r int) bool {
	return (x-px)*(x-px)+(y-py)*(y-py) <= r*r
}

func circleIntersectsTopLeftOfRectangle(x, y, r, xCorner, yCorner int) bool {
	return (abs(x) <= r && 0 <= y && y <= yCorner) ||
		(0 <= x && x <= xCorner && abs(y-yCorner) <= r) ||
		pointInCircle(x, y, 0, yCorner, r)
}

func circleIntersectsBottomRightOfRectangle(x, y, r, xCorner, yCorner int) bool {
	return (abs(y) <= r && 0 <= x && x <= xCorner) ||
		(0 <= y && y <= yCorner && abs(x-xCorner) <= r) ||
		pointInCircle(x, y, xCorner, 0, r)
}

func circlesIntersectInRectangle(x1, y1, r1, x2, y2, r2, xCorner, yCorner int) bool {
	return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2) <= (r1+r2)*(r1+r2) &&
		x1*r2+x2*r1 < (r1+r2)*xCorner &&
		y1*r2+y2*r1 < (r1+r2)*yCorner
}

func abs(x int) int {
	if x < 0 {
		return -x
	}
	return x
}

func main() {
	X := 3
	Y := 4
	circles := [][]int{{2, 1, 1}}
	result := canReachCorner(X, Y, circles)
	fmt.Println(result)
}

Python完整代码如下:

python 复制代码
# -*-coding:utf-8-*-

def can_reach_corner(x_corner, y_corner, circles):
    visited = [False] * len(circles)

    def dfs(i):
        x1, y1, r1 = circles[i][0], circles[i][1], circles[i][2]
        if circle_intersects_bottom_right_of_rectangle(x1, y1, r1, x_corner, y_corner):
            return True
        visited[i] = True
        for j in range(len(circles)):
            if not visited[j] and circles_intersect_in_rectangle(x1, y1, r1, circles[j][0], circles[j][1], circles[j][2], x_corner, y_corner) and dfs(j):
                return True
        return False

    for i in range(len(circles)):
        x, y, r = circles[i][0], circles[i][1], circles[i][2]
        if point_in_circle(0, 0, x, y, r) or point_in_circle(x_corner, y_corner, x, y, r):
            return False
        if not visited[i] and circle_intersects_top_left_of_rectangle(x, y, r, x_corner, y_corner) and dfs(i):
            return False
    return True

def point_in_circle(px, py, x, y, r):
    return (x-px)*(x-px) + (y-py)*(y-py) <= r*r

def circle_intersects_top_left_of_rectangle(x, y, r, x_corner, y_corner):
    return (abs(x) <= r and 0 <= y <= y_corner) or \
           (0 <= x <= x_corner and abs(y-y_corner) <= r) or \
           point_in_circle(x, y, 0, y_corner, r)

def circle_intersects_bottom_right_of_rectangle(x, y, r, x_corner, y_corner):
    return (abs(y) <= r and 0 <= x <= x_corner) or \
           (0 <= y <= y_corner and abs(x-x_corner) <= r) or \
           point_in_circle(x, y, x_corner, 0, r)

def circles_intersect_in_rectangle(x1, y1, r1, x2, y2, r2, x_corner, y_corner):
    return (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) <= (r1+r2)*(r1+r2) and \
           x1*r2 + x2*r1 < (r1+r2)*x_corner and \
           y1*r2 + y2*r1 < (r1+r2)*y_corner

def abs_val(x):
    return -x if x < 0 else x

def main():
    x = 3
    y = 4
    circles = [[2, 1, 1]]
    result = can_reach_corner(x, y, circles)
    print(result)

if __name__ == "__main__":
    main()
相关推荐
Imagine Miracle36 分钟前
【Rust】枚举和模式匹配——Rust语言基础14
开发语言·后端·rust
无名之逆36 分钟前
探索 Rust 高效 Web 开发:Hyperlane 框架深度解析
开发语言·后端·算法·面试·rust
Asthenia04121 小时前
从零聊起:RocketMQ Producer 的预绑定主题列表和事务消息
后端
小程序设计1 小时前
【2025】基于springboot+vue的体育场馆预约管理系统(源码、万字文档、图文修改、调试答疑)
vue.js·spring boot·后端
程序视点1 小时前
Linux内核与基础命令学习总结
linux·后端
alicema11112 小时前
Python+Django网页前后端rsp云端摄像头人数监控系统
开发语言·网络·后端·python·神经网络·算法·django
考虑考虑2 小时前
JDK21中的Switch模式匹配
java·后端·java ee
Victoria Zhu3 小时前
零基础小白如何系统学习Spring Boot
spring boot·后端·学习
Aska_Lv3 小时前
mybatis---MybatisPlus自定义insertBatchSomeColumn实现真正批量插入
后端·架构
竣峰5 小时前
简单商品管理页开发-基于yzpass-admin-template 后台管理系统模版
前端·后端