为模棱两可的标题道歉,我想不出更具体的内容。
为了更好地递归地解决问题,我一直在处理CodingBat上发布的问题。我的问题与以下问题的变化有关。
给定一个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
基本上,与原始问题的区别在于值可能不一定彼此相邻(参见上面的示例)。
我将如何递归地执行此操作?我会很感激一些指示。
我不想更改方法签名或使用全局变量。
答案 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);
}
}