从零学算法2833

2833.给你一个长度为 n 的字符串 moves ,该字符串仅由字符 ‘L’、‘R’ 和 ‘’ 组成。字符串表示你在一条原点为 0 的数轴上的若干次移动。
你的初始位置就在原点(0),第 i 次移动过程中,你可以根据对应字符选择移动方向:
如果 moves[i] = ‘L’ 或 moves[i] = '
’ ,可以选择向左移动一个单位距离
如果 moves[i] = ‘R’ 或 moves[i] = '’ ,可以选择向右移动一个单位距离
移动 n 次之后,请你找出可以到达的距离原点 最远 的点,并返回 从原点到这一点的距离 。
示例 1:
输入:moves = “L_RL__R”
输出:3
解释:可以到达的距离原点 0 最远的点是 -3 ,移动的序列为 “LLRLLLR” 。
示例 2:
输入:moves = “R__LL
输出:5
解释:可以到达的距离原点 0 最远的点是 -5 ,移动的序列为 “LRLLLLL” 。
示例 3:
输入:moves = "
______"
输出:7
解释:可以到达的距离原点 0 最远的点是 7 ,移动的序列为 “RRRRRRR” 。

  • 我的思路:首先这可以看成一棵二叉树,所以直接 dfs。首先入参,为了知道遍历到哪里了,用一个 int 表示当前 moves 下标。由于可以向左或者向右,所以用两个 int 表示向两边移动的距离;递归出口,当遍历完这棵树也就是 moves 遍历到最后一个字符时返回 max(左距离,右距离)。如果在遍历的过程中发现遍历到某个点时已经遇到过此时向(左,右)移动了多少距离这种情况,那可以直接返回 0 了,因为这种可能性我们已经考虑过了(比如 l__r_,我们可能是 llrr_ ,也可能是lrlr_,那此时其实就是重复的情况了,遍历到第五个点的 _ 时都是还在原点);否则就看当前字符了,为 L 说明向左走了一步,左距离 加 1,相对应的,别忘了,这就代表着右距离减了 1, R 同理,如果为 _ 就返回 max(左,右)
  •   char[] moves;
      // l[i][j] 遍历到第 i 个点并且此时往左走了长度 j
      int[][] l;
      // // l[i][j] 遍历到第 i 个点并且此时往右走了长度 j
      int[][] r;
      public int furthestDistanceFromOrigin(String moves) {
          this.moves = moves.toCharArray();
          int n = this.moves.length;
          l=new int[n][n];
          r=new int[n][n];
          return dfs(0,0,0);
      }
      // left 和 right 最多只可能有一个大于 0,一正一负,或者都为 0
      int dfs(int cur,int left,int right){
      	// 遍历完了
          if(cur==moves.length){
              return Math.max(left,right);
          }
          // 如果这种情况已经考虑过了 return 0
          if((left>=0 && l[cur][left]==1) || (right>=0 && r[cur][right]==1))return 0;
          // 如果在左边,记录这种情况
          if(left>=0)l[cur][left]=1;
          // // 如果在右边,记录这种情况
          if(right>=0)r[cur][right]=1;
          if(moves[cur]=='L')return dfs(cur+1,left+1,right-1);
          if(moves[cur]=='R')return dfs(cur+1,left-1,right+1);
          return Math.max(dfs(cur+1,left+1,right-1),dfs(cur+1,left-1,right+1));
      }
    
  • 其实这题我想的复杂了,因为当遇到 _ 时,你的选择丝毫不影响之后的选择。也就是说你只需要记录有几个 _ ,然后看剩下的 L 和 R 会让你走到哪里,如果在左边你就把 _ 都选择往左走,在右边同理。
  •   public int furthestDistanceFromOrigin(String moves) {
          int x=0;
          int distance=0;
          for(char c:moves.toCharArray()){
              if(c=='_')x++;
              else distance+=c=='L'?-1:1;
          }
          return x+Math.abs(distance);
      }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值