递归搜索数组 - CodingBat

时间:2015-01-21 02:34:14

标签: java arrays algorithm recursion

为模棱两可的标题道歉,我想不出更具体的内容。

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

original problem是:

  

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

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

我对此问题的解决方案是:

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);
}

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

  

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

     

例如:

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

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

我将如何递归地执行此操作?我会很感激一些指示。

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

1 个答案:

答案 0 :(得分:2)

这可以是答案,只需使用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);
     } 
}