【算法】行星碰撞&机器人碰撞(栈的使用)

这篇具有很好参考价值的文章主要介绍了【算法】行星碰撞&机器人碰撞(栈的使用)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文记录了两个使用栈来处理碰撞问题的算法题目。

行星碰撞

https://leetcode.cn/problems/asteroid-collision/
【算法】行星碰撞&机器人碰撞(栈的使用),算法,算法,行星碰撞,机器人碰撞,栈

对于这种题目,各个元素分别会向左或向右移动,可以使用栈模拟碰撞的过程。
由于从左往右进行遍历,因此遍历当前元素时,如果它是向右移动的,就只可能会碰撞到它右边还没有被遍历到的元素,因此可以将其直接放入栈中。
当遍历到向左移动的元素时,它只可能碰撞到当前已经在栈中的元素,需要进行一些处理。

class Solution {
    public int[] asteroidCollision(int[] asteroids) {
        Deque<Integer> stk = new ArrayDeque();
        for (int asteroid: asteroids) {
            if (asteroid > 0) {		// 向右移动的直接放入栈中
                stk.push(asteroid);
                continue;
            }
            boolean f = true;  // 记录这个向左的陨石是否还活着
            while (!stk.isEmpty() && stk.peek() > 0) {
                if (stk.peek() + asteroid >= 0) {
                    if (stk.peek() + asteroid == 0) stk.pop();
                    f = false;  // 被撞死了
                    break;
                }
                f = true;
                stk.pop();
            }
            if (f) stk.push(asteroid);		// 没被撞死就放入栈中
        }
        int n = stk.size();		// 由于下面取元素的时候,栈中元素会不断减少,因此需要提前声明 n
        int[] ans = new int[n];
        for (int i = 0; i < n; ++i) ans[n - 1 - i] = stk.pop();
        return ans;
    }
}

对于这道题目来说,无非只有三种结果:1.没撞过 2.撞过了 3.同归于尽了。分类写 if 即可。

注意在取出栈中元素的过程中,stk.size() 一直在发生变化,因此代码最后不能写成:

for (int i = 0; i < stk.size(); ++i) ans[stk.size() - 1 - i] = stk.pop();

而必须是事先 通过 int n = stk.size() 接收原始结果中元素的个数。

机器人碰撞

https://leetcode.cn/problems/robot-collisions/
题目出自:第 351 场周赛
【算法】行星碰撞&机器人碰撞(栈的使用),算法,算法,行星碰撞,机器人碰撞,栈

这道题目与 行星碰撞 几乎如出一辙,因此代码模板是一样的,差异几乎只存在于 遍历到向左移动的元素时,处理的方式不同。

class Solution {
    public List<Integer> survivedRobotsHealths(int[] positions, int[] healths, String directions) {
        int n = positions.length;
        Integer[] id = new Integer[n];
        for (int i = 0; i < n; ++i) id[i] = i;  // 记录下标用于排序
        Arrays.sort(id, (i, j) -> positions[i] - positions[j]); // 按照位置从左往右排序

        Deque<Integer> stk = new ArrayDeque();
        for (int i: id) {
            if (directions.charAt(i) == 'R') {  // 向右,加入栈
                stk.push(i);
                continue;
            }
            while (!stk.isEmpty()) {
                int top = stk.peek();
                if (healths[top] > healths[i]) {    // 栈顶的健康度大
                    healths[top]--;
                    healths[i] = 0;
                    break;
                }
                if (healths[top] == healths[i]) {    // 一样大
                    healths[stk.pop()] = 0;
                    healths[i] = 0;
                    break;
                } 
                // 新来的健康度大
                healths[stk.pop()] = 0;     
                healths[i]--;
                // 不需要将向左移动的机器人加入栈,因为如果它撞完了左边向右移动的,就不会再与任何机器人发生碰撞了
            }
        }
        List<Integer> ans = new ArrayList();
        for (int h: healths) {
            if (h != 0) ans.add(h);
        }
        return ans;
    }
}

注意由于机器人的 positions 是乱序的,而我们是需要按照位置的从左到右关系进行遍历,因此常用如下操作对下标进行排序。

Integer[] id = new Integer[n];
for (int i = 0; i < n; ++i) id[i] = i;  // 记录下标用于排序
Arrays.sort(id, (i, j) -> positions[i] - positions[j]); // 按照位置从左往右排序

之所以声明 Integer[] 而不是 int[] 是因为 在 Java 中 int[] 不支持自定义排序。(关于Java 自定义排序可见:【Java】自定义排序)

注意虽然 int[] 不支持,但 int[][] 是支持的,因为 int[][] 的元素是 int[],已经是引用类型了。

补充题目:2731. 移动机器人

2731. 移动机器人
【算法】行星碰撞&机器人碰撞(栈的使用),算法,算法,行星碰撞,机器人碰撞,栈
乍一看这道题目很像是这一类题目,因为两个机器人相撞之后只是改变位置而已,不会对两者的数值或是否存在造成影响。

因此这道题目更像是脑筋急转弯,需要将其相撞转换成——擦肩而过,两者的相撞并不会对结果造成什么影响。既然如此,那么可以把机器人都看成是完全一样的,无法区分。

class Solution {
    public int sumDistance(int[] nums, String s, int d) {
        int n = nums.length;
        final int mod = (int)1e9 + 7;
        long[] lnums = new long[n];
        for (int i = 0; i < n; ++i) {
            lnums[i] = nums[i];
            if (s.charAt(i) == 'R') lnums[i] += d;
            else lnums[i] -= d;
        }
        Arrays.sort(lnums);
        long last = 0, ans = 0;
        for (int i = 1; i < n; ++i) {
            last = (i * (lnums[i] - lnums[i - 1]) + last) % mod;
            ans = (ans + last) % mod;
        }
        return (int)ans;
    }
}

关于机器人之间的两两距离如何计算:
【算法】行星碰撞&机器人碰撞(栈的使用),算法,算法,行星碰撞,机器人碰撞,栈

计算时,为了避免溢出,需要取模。(关于取模参见:【算法】数学相关知识总结)


参考资料


栈模拟(Python/Java/C++/Go)文章来源地址https://www.toymoban.com/news/detail-589078.html

到了这里,关于【算法】行星碰撞&机器人碰撞(栈的使用)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 协作机器人(Collaborative-Robot)安全碰撞的速度与接触力

    协作机器人(Collaborative-Robot)的安全碰撞速度和接触力是一个非常重要的安全指标。在设计和使用协作机器人时,必须确保其与人类或其他物体的碰撞不会对人员造成伤害。 对于协作机器人的安全碰撞速度,一般会设定一个上限值,以确保机器人在与人类或其他物体发生碰

    2024年02月03日
    浏览(44)
  • 遨博协作机器人高级编程 - 遨博机器人SDK用户自定义算法接口介绍与使用

    目录 一、简介 二、环境版本 三、开发环境部署 1.二次开发资料下载 2. AUBO PE编程仿真环境配置 四、linux C++ SDK示例 1. 编程环境 2. 加载C++ SDK工程 3. linux C++ SDK 文件构成 4.运行SDK示例 五、构建用户自定义算法SDK示例工程 1.Linux C++ SDK透传接口 2.  创建新项目 3.导入遨博机器人

    2024年02月14日
    浏览(53)
  • 机器人控制算法——移动机器人横向控制最优控制LQR算法

    1.Introduction LQR (外文名linear quadratic regulator)即线性二次型调节器,LQR可得到状态线性反馈的最优控制规律,易于构成闭环最优控制。LQR最优控制利用廉价成本可以使原系统达到较好的性能指标(事实也可以对不稳定的系统进行整定) ,而且方法简单便于实现 ,同时利用 Matlab 强

    2024年02月04日
    浏览(47)
  • 扫地机器人(二分算法+贪心算法)

    1.  if(robot[i]-len=sweep)这个代码的意思是——如果机器人向左移动len个长度后,比现在sweep的位置(现在已经覆盖的范围)还要靠左,就是覆盖连续不起来,呢么这个len就是有问题的,退出函数,再继续循环。 2.  显然当每个机器人清扫的范围相同时,所用时间最小,所以这时

    2024年01月20日
    浏览(43)
  • 基于C#的机器人仿真平台和机器人运动学算法实现

    一、平台搭建 1.利用wpf自带的库进行机器人各关节导入 相关代码段: 导入效果如图: 效果视频: 2.通过正运动学显示机器人当前位置信息 拖动机器人并且实时改变其位置信息: xaml代码部分: 算法部分:  3.功能实现(在X/Y/Z轴上设置一个移动距离,然后机器人自动移动该

    2024年02月16日
    浏览(53)
  • 机器人集群控制算法概述

    机器人集群控制算法是指一组算法,用于协调和控制多个机器人协同工作,以完成特定任务或达到特定目标。以下是一些常见的机器人集群控制算法: 集群协同行为算法: 领航者/跟随者(Leader/Follower): 一个机器人被指定为领导者,其他机器人跟随领导者的运动。这种方法

    2024年03月15日
    浏览(52)
  • 机器人控制算法——TEB算法—Obstacle Avoidance and Robot Footprint Model(避障与机器人足迹模型)

    1.1处罚条款 避障是作为整体轨迹优化的一部分来实现的。显然,优化涉及到找到指定成本函数(目标函数)的最小成本解(轨迹)。简单地说:如果一个计划的(未来)姿势违反了与障碍物的期望分离,那么成本函数的成本必须增加。理想情况下,在这些情况下,成本函数值

    2024年02月06日
    浏览(46)
  • 算法题——机器人的运动范围

    声明 该系列文章仅仅展示个人的解题思路和分析过程,并非一定是优质题解,重要的是通过分析和解决问题能让我们逐渐熟练和成长,从新手到大佬离不开一个磨练的过程,加油! 原题链接 机器人的运动范围 https://leetcode.cn/leetbook/read/illustration-of-algorithm/9h6vo2/ 算法分析 图

    2024年02月11日
    浏览(43)
  • 【多机器人】基于A_Star算法实现多机器人路径规划附Matlab代码

     ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进, 代码获取、论文复现及科研仿真合作可私信。 🍎个人主页:Matlab科研工作室 🍊个人信条:格物致知。 更多Matlab完整代码及仿真定制内容点击👇 智能优化算法       神经网络预测       雷达通信    

    2024年02月04日
    浏览(51)
  • 【算法-数组-pyhton】模拟行走机器人

    💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学习,不断总结,共同进步,活到老学到老 导航 檀越剑指大厂系列:全面总

    2024年02月12日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包