【问题标题】:Searching an array recursively - CodingBat递归搜索数组 - CodingBat
【发布时间】:2015-01-21 02:34:13
【问题描述】:

抱歉标题模棱两可,我想不出更具体的东西。

为了更好地递归解决问题,我一直在处理CodingBat 上发布的问题。我的问题与以下问题的变体有关。

original problem 是:

给定一个整数数组,如果数组包含,则递归计算 在数组中某个值乘以该值乘以 10。我们将 使用只考虑数组的一部分的约定 从给定的索引开始。这样一个递归调用就可以通过 index+1 向下移动数组。初始调用将传入索引为 0.

  • array220({1, 2, 20}, 0) → true
  • array220({3, 30}, 0) → 真
  • array220({3}, 0) → 假

我对这个问题的解决方法是:

public boolean array220(int[] nums, int index) {
  if (index >= nums.length-1) return false;

  if (nums[index+1] == nums[index] * 10) return true; 

  return array220(nums, ++index);
}

但是,为了挑战自己,我想知道如何解决我构想的这个问题的以下变体:

给定一个整数数组,递归计算如果数组包含 某处的值比任何其他值大 10 倍。我们将使用 只考虑数组开始部分的约定 在给定的索引处。这样,递归调用可以将 index+1 传递给 向下移动阵列。初始调用将传入索引为 0。

例如:

  • array220({1, 2, 10}, 0) → true
  • array220({3, 2, 9, 38, 20}, 0) → true
  • array220({3}, 0) → 假

所以基本上,与原始问题的区别在于这些值可能不一定彼此相邻(参见上面的示例)。

我将如何递归地执行此操作?我将不胜感激。

我不想更改方法签名或使用全局变量。

【问题讨论】:

  • 这不是一个真正的递归问题,即使在它的第一个版本中也是如此。但是,迭代算法始终可以转换为尾递归算法,因此您可以以递归方式编写您的仓促解决方案
  • @Dici CodingBat 上发布的问题只能使用递归来解决。我这样做是为了练习。在不使用数据结构的情况下,我将如何递归地执行此操作?看来我需要一种方法来执行嵌套循环。
  • 与原版类似,只是在递归方法中添加一个额外的哈希表作为参数。
  • @sparrow 这个活动的全部目的是练习递归。 CodingBat 上的问题被设计为无需循环即可解决。请仔细阅读问题。效率或优雅与这个问题无关。
  • @PhamTrung 我将如何在不使用其他数据结构的情况下递归地执行此操作?你能提供一些伪代码吗?

标签: java arrays algorithm recursion


【解决方案1】:

这可能是答案,只需使用 HashSet,并在您进行递归调用时将其传递:

public boolean array220(int[] nums,HashSet<Integer> set,  int index) {
  if (index >= nums.length-1) return false;

  if (set.contains(nums[index]*10)) 
      return true; 
  set.add(nums[index]);
  return array220(nums,set, ++index);
}

如果你不想使用额外的数据结构,排序数组和使用二分查找可以为你带来 O(nlogn) 的解决方案,有两种递归方法。

Arrays.sort(nums);

public boolean array220(int[] nums,  int index) {
  if (index >= nums.length-1) return false;

  if (binarySearch(index + 1, nums.length - 1,nums[index]*10,nums)) 
      return true; 

  return array220(nums, ++index);
}

public boolean binarySearch(int start, int end,int value, int[] nums){
     if(start > end)
        return false;
     int mid = (start + end)/2;
     if(nums[mid] == value){
         return true;
     }else if(nums[mid] > value){
         return binarySearch(start, mid - 1, value, nums);
     }else{
         return binarySearch(mid + 1, end, value, nums);
     } 
}

如果您不想对数组进行排序,使用线性递归搜索将给出 O(n^2) 的解决方案。

public boolean array220(int[] nums,  int index) {
  if (index >= nums.length-1) return false;

  if (linearSearch(0,nums[index]*10,nums)) 
      return true; 

  return array220(nums, ++index);
}

public boolean linearSearch(int start, int value, int[] nums){
     if(start >= nums.length)
        return false;

     if(nums[start] == value){
         return true;
     }else {
         return linearSearch(start + 1, value, nums);
     } 
}

【讨论】:

  • 不使用数据结构我们如何做到这一点?我不关心效率。我不想更改方法签名或使用任何全局变量。
  • @gentleArt,看第二种和第三种方案,方案不需要额外的数据结构
  • 您能否澄清以下布尔条件: (nums[index] % 10 == 0 && linearSearch(0,nums[index]/10,nums)) 我不太确定这是在做什么?是检查 0 吗?谢谢!
  • @gentleArt nums[index] % 10 == 0表示当前nums[index]是否除以10,例如:10,20,30,...如果是,那么我们需要找到1,2 , 3..., 即nums[index]/10
  • @gentleArt 嗯,那部分没必要,去掉那部分
猜你喜欢
  • 2015-04-12
  • 2013-05-12
  • 2012-09-16
  • 2015-03-01
  • 1970-01-01
  • 2016-02-27
  • 2011-04-27
  • 2014-10-15
相关资源
最近更新 更多