小于N的最大值

294 阅读1分钟

对于一个给定的数组,里面只包含1-9的数字,以及一个给定的正整数n,问利用数组中的数字构造一个小于n的最大值?
例如,数组中包含数字{1, 2, 5, 9},给定正整数2533,求出构造的最大数字。 这道题其实是一个典型的回溯题,当然你说是DFS题也没有任何问题。毕竟DFS和回溯是一家,彼此分不开。 利用这四个数字可以构成多少个整数呢? 从数组中取出数字的过程其实类似一个求子集的问题,本数组应该有2^4个子集,去掉0也有15个。具体咱们可以参考leetcode 78题。但这里由于数字可以重复使用,需要注意一些细节。

vector<int> path;
int result = 0;

/*返回-1代表溢出,可以直接返回
 *同时注意参数是拷贝形式!!!*/
int vec2int(vector<int> vec) {
  int sum = 0, weight = 1;
  while(!vec.empty()) {
    int t = vec.back();
    vec.pop_back();
    if(sum > INT32_MAX - t * weight) return -1;
    sum += t * weight;
    weight *= 10;
  }
  return sum;
}

/*这是一个典型的回溯做法,和求子集类似,区别是数字可以重复利用
和递归结束条件不太一样*/
void dfs(vector<int>& vec, int startIndex, int target) {
  if(startIndex >= vec.size()) return;
  int num = vec2int(path);
  if(num > target || num == -1) return;
  if(num < target) {
    result = max(result, num);
  }

  for(int i = 0; i < vec.size(); i++) {
    path.push_back(vec[i]);
    //必须传入i,而不是i+1,因为数字可以重复利用
    dfs(vec, i, target);
    path.pop_back();
  }
}