小招喵的机器人

题目:
给定一个字符串,该字符串仅包含R和L字符;初始时,每个位置都有一个机器人。机器人移动10^100次,每次的移动规则是:若其所在的位置是R,则向右移动;若其所在的位置是L,则向左移动。字符串保证最左边的字符是R,最右边的字符是L。最后输出每个位置的机器人的数量。
输入:
RRLRL
输出:
0 1 2 1 1
输入:
RRRRRLRLRL
输出:
0 0 0 0 3 3 1 1 1 1

解:
不是什么聪明的做法,代码也一大堆,描述也没描述清楚……轻喷
(仅供个人复习使用…)
大概思路是:

  1. 首先遍历一遍数组,根据每个位置的R和L,进行计数,count数组。
    计数的标准是:(记当前位置为i,当前位置的字符为ch)(可以合并两个步骤。)
  • 如果ch为R,且前一个字符也是R,则count[i] = count[i - 1] + 1;
  • 如果ch为R,前一个字符是L,则count[i] = 1;(即重新计数)
  • 如果ch为L,前一个字符是R,则count[i] = 1 ;
  • 如果ch为L,且前一个字符也是L,则要更新之前连续的为L字符的位置,更新规则是:将当前位置前面所有连续的L位置的count+1。
    这样获得最后的count数组。
  1. 根据count数组获得结果数组
    遍历结果数组,并观察字符数组,更新res数组,更新规则是:
  • 如果当前字符是R,且下一个字符也是R,则res[i] = 0;
  • 如果当前字符是R,下一个字符是L,则当前是RL分界处。在10^100次移动后该位置可能累积了很多机器人。计算方式是:
    • 如果count[i] 是偶数,则说明当前位置前面有奇数个R。设其前面的一个位置为idx。
      • 如果idx与当前位置的距离为奇数距离,即走奇数步就可以到达当前位置。其剩余可走的步数也为奇数次。从当前位置开始,走奇数次,最后一定会落到当前位置的下一个位置。
      • 如果idx与当前位置的距离是偶数举例,同理,该位置的机器人最后一定会落到当前位置。
        计数方法是:res[i] += count[i] / 2,下一位置:res[i + 1] += count[i] / 2
    • 如果count[i]是奇数,res[i] += count[i] / 2 + 1;下一位置:res[i + 1] += count[i] / 2
  • 如果当前字符是L,且前一个字符也是L,则res[i] = 0;
  • 如果当前字符是L,前一个字符是R,则同理啊。更新
  1. 背后的逻辑是什么:见图片
    在这里插入图片描述

描述一大堆。下面贴代码:

	private static int[] solution2(String str) {
		int n = str.length();
		int[] count = new int[n];
		char[] array = str.toCharArray();
		int i = 1;
		count[0] = 1;
		char pre = 'R';
		while(i < n) {
			char ch = array[i];
			// 我这两段shit代码合在一起写好像也没问题 ——并不能
			if(pre == 'R') {
				if(pre == ch) {
					// 如果是连续的R
					count[i] = count[i - 1] + 1;
				}else {
					// 如果是RL的交界处
					pre = 'L';
					count[i] = 1;
				}
			}else {
				if(pre == ch) {
					// 如果是连续的L,更新前面L的取值
					// 应该可行吧(我猜
					int j = i - 1;
					while(j >= 0 && array[j] == 'L') {
						count[j]++;
						j--;
					}
					count[i] = 1;
				}else {
					// 如果是LR交界处
					pre = 'R';
					count[i] = 1;
				}
			}
			i++;
		}
		// 根据字符统计数组获得结果数组
		i = 0;
		int[] res = new int[n];// 结果数组
		while(i < n) {
			char ch = array[i];
			if(ch == 'R' && ch == array[i + 1]) {
				// 如果当前字符是R,且下一个字符也是R
				res[i] = 0;
			}else if(ch == 'R') {
				// 如果当前字符是R,下一个字符是L,统计当前R位置的计数
				if(count[i] % 2 == 0) {
					// 当前位置累加起来有偶数个R
					res[i] += count[i] / 2;
					res[i + 1] += count[i] / 2;
				}else {
					res[i] += count[i] / 2 + 1;
					res[i + 1] += count[i] / 2;
				}
			}else if(ch == 'L' && ch == array[i - 1]) {
				// 如果当前字符是L,且前一个字符也是L
				res[i] = 0;
			}else if(ch == 'L' && array[i - 1] == 'R') {
				// 如果当前字符是L,上一个字符是R,更新当前位置和前一位置的计数
				if(count[i] % 2 == 0) {
					res[i] += count[i] / 2;
					res[i - 1] += count[i] / 2;
				}else {
					res[i] += count[i] / 2 + 1;
					res[i - 1] += count[i] / 2;
				}
			}
			i++;
		}
		return res;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值