剑指 Offer 57 - II. 和为s的连续正数序列
思路
方法一:枚举 + 暴力
1 class Solution { 2 public: 3 vector<vector<int>> findContinuousSequence(int target) { 4 vector<vector<int>> res; 5 for(int i = 1; i <= target/2; ++i) { 6 vector<int> tmp; 7 int sum = 0; 8 for(int j = i; j < target && sum < target; ++j) { 9 sum += j; 10 tmp.push_back(j); 11 } 12 13 if(sum == target) { 14 res.push_back(tmp); 15 } 16 } 17 18 return res; 19 } 20 };
1 class Solution { 2 public: 3 vector<vector<int>> findContinuousSequence(int target) { 4 vector<vector<int>> vec; 5 vector<int> res; 6 int sum = 0, limit = (target - 1) / 2; // (target - 1) / 2 等效于 target / 2 下取整 7 for (int x = 1; x <= limit; ++x) { 8 long long delta = 1 - 4 * (x - 1ll * x * x - 2 * target); 9 if (delta < 0) { 10 continue; 11 } 12 int delta_sqrt = (int)sqrt(delta + 0.5); 13 if (1ll * delta_sqrt * delta_sqrt == delta && (delta_sqrt - 1) % 2 == 0) { 14 int y = (-1 + delta_sqrt) / 2; // 另一个解(-1-delta_sqrt)/2必然小于0,不用考虑 15 if (x < y) { 16 res.clear(); 17 for (int i = x; i <= y; ++i) { 18 res.push_back(i); 19 } 20 vec.push_back(res); 21 } 22 } 23 } 24 return vec; 25 } 26 };
1 class Solution { 2 public: 3 vector<vector<int>> findContinuousSequence(int target) { 4 vector<vector<int>> res; 5 int l = 1, r = 2; 6 while(l < r) { 7 int sum = (r-l+1)*(l+r)/2; 8 if(sum == target) { 9 vector<int> tmp; 10 for(int i = l; i <= r; ++i) 11 tmp.push_back(i); 12 res.push_back(tmp); 13 ++l; 14 } else if(sum < target) { 15 ++r; 16 } else { 17 ++l; 18 } 19 } 20 21 return res; 22 } 23 };
也可以不使用求和公式求sum,而是每次对指针进行移动的时候,同时对sum的值进行改变。代码如下:
1 class Solution { 2 public: 3 vector<vector<int>> findContinuousSequence(int target) { 4 vector<vector<int>> res; 5 int i = 1, j = 2; 6 int sum = 3; 7 while(i < j) { 8 if(sum < target) { 9 ++j; 10 sum += j; 11 } else if (sum > target) { 12 sum -= i; 13 ++i; 14 } else { 15 vector<int> v; 16 for(int k = i; k <= j; ++k) { 17 v.push_back(k); 18 } 19 res.push_back(v); 20 sum -= i; 21 ++i; 22 } 23 } 24 25 return res; 26 } 27 };