Tag Archives: 因式分解

LeetCode Closest Divisors

1362. Closest Divisors

Given an integer num, find the closest two integers in absolute difference whose product equals num + 1 or num + 2.

Return the two integers in any order.

Example 1:

Input: num = 8
Output: [3,3]
Explanation: For num + 1 = 9, the closest divisors are 3 & 3, for num + 2 = 10, the closest divisors are 2 & 5, hence 3 & 3 is chosen.

Example 2:

Input: num = 123
Output: [5,25]

Example 3:

Input: num = 999
Output: [40,25]

Constraints:

  • 1 <= num <= 10^9

给定一个数num,找出所有a*b等于num+1或num+2的(a,b)组合中,a和b的差最小的那个组合。

子问题就是给定一个数num,找出a*b==num的(a,b)组合中,a和b的差最小的组合。根据反证法,a和b必定有一个小于等于sqrt(num),另一个大于等于sqrt(num)。所以我最开始的做法是,用之前快速求sqrt的方法,计算sqrt(num),令left和right都等于sqrt(num),然后判断left*right的积,如果大于num,则–right;否则++left。这样虽然能得到正确结果,但提交后TLE。

百思不得其解,后来看别人的解答,才理解为什么我会TLE。我的解法设置了left和right两个指针,根据乘积的大小关系,left和right都在移动,在某些情况总的移动数会很大。而正确解法是,只设置一个移动指针i,i从sqrt(num)递减,然后判断num是否能整除i,如果能整除,则肯定找到一个因式分解。这种方法相当于我的方法中只移动了left,速度快了不少。在这种解法下,用不用快速sqrt都能AC。

完整代码如下:

class Solution {
public:
	int mySqrt(int x)
	{
		long long y = x;
		while (y*y > x)
		{
			y = (y + x / y) / 2;
		}
		return y;
	}

	vector<int> work(int num) {
		for (int i = mySqrt(num) + 1; i >= 1; --i) {
			if (num%i == 0) {
				return { i,num / i };
			}
		}
		return { 1,num };
	}
	vector<int> closestDivisors(int num) {
		vector<int> plus1 = work(num + 1);
		vector<int> plus2 = work(num + 2);
		if (abs(plus1[1] - plus1[0]) < abs(plus2[1] - plus2[0]))return plus1;
		else return plus2;
	}
};

LeetCode Minimum Factorization

LeetCode Minimum Factorization Given a positive integer a, find the smallest positive integer b whose multiplication of each digit equals to a. If there is no answer or the answer is not fit in 32-bit signed integer, then return 0. Example 1 Input:

48
Output:
68
Example 2 Input:
15
Output:
35

给定一个数a,要求找一个最小的数b,使得b的各位数字相乘的结果等于a。 很有意思的一个题,考察数学,当时没做出来,参考了这个题。 首先,如果a小于10的话,那么最小的b就是a了,否则b就要变成十位数或者百位数。比如a=8,则最小的b就是8,当然b也可以是十位数比如24或者42,但是都大于个位数8自己。 当a大于等于10时,我们需要找a的因子,为了是b最小,则我们希望b的位数越少越好。所以我们要找b的因子应该越大越好。所以我们从最大的因子9开始找起,从9一直找到2,把a的所有因子都找出来。比如48从大到小的因子是8和6,则最终结果就是把因子从小到大组成一个数,即68。 这里有一个问题,48的因子还可以是4和2呀,为什么没有了呢。因为我们从9→2开始找因子的过程中,是用a除以因子得到的商来不断的找。上面48找到8和6的因子之后,商就等于1了,不需要再找因子了,所以结束。 如果在找因子的过程中,发现商变成了一个质数,因为大于10的质数不可能被分解,所以无解,返回0。 代码如下: [cpp] class Solution { public: int smallestFactorization(int a) { if (a < 10)return a; vector<int> factors; for (int i = 9; i >= 2; –i) { while (a%i == 0) { factors.push_back(i); a /= i; } } if (a != 1)return 0; // caution long long ans = 0; for (int i = factors.size() – 1; i >= 0; –i) { ans = ans * 10 + factors[i]; } return ans > INT_MAX ? 0 : ans; } }; [/cpp] 本代码提交AC,用时3MS。]]>