1. Sum
Original title address:https://leetcode.com/problems/two-sum/description/
Title Description:
Given an array of integers, return indices of the both numbers such that they add-to a specific target.
You may assume this each input would has exactly one solution, and you could not use the same element twice.
Example:
Given nums = [2, 7, one, +], target = 9,
Because Nums[0] + nums[1] = 2 + 7 = 9, return [0,1].
idea : Set up a hash table to store the element num and subscript so that the target-num element can be found in the complexity of O (1). If there is an index that returns two elements.
AC Code:
Vector<int> twosum (vector<int> &numbers, int target) {//key is the number and value are its
index In the vector.
Unordered_map<int, int> hash;
vector<int> result;
for (int i = 0; i < numbers.size (); i++) {
int numbertofind = target-numbers[i];
If Numbertofind exists in the hash table, it returns a two-digit subscript
if (Hash.find (numbertofind)! = Hash.end ()) {
//+1 because indices is not Zero based
Result.push_back (Hash[numbertofind] + 1);
Result.push_back (i + 1);
return result;
}
If not in the hash table, put the current element into the hash table
Hash[numbers[i]] = i;
}
return result;
}
(2) 3sum
Original title address : https://leetcode.com/problems/3sum/description/
Title Description :
Given an array S of n integers, is there elements a, B, C in S such that A + B + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:the solution set must not contain duplicate triplets.
For example, given array S = [-1, 0, 1, 2,-1,-4],
A solution Set is: [[-1, 0, 1], [-1,-1, 2]]
idea: the idea of referring to the previous question, when traversing to the element num, is equivalent to seeking after two elements can be composed and for-num. However, there is a case for repeating elements, so you need to sort them first.
First, then second points to the next element, third points to the last element to find out Second+third=-first.
---------------------------------------------------- ^ ^ ^ | | | | +-Second third +-first if Nums[first] + Nums[second] + Nums[third] < 0, which is the need to increase sum, the With second++
----------------------------------------------------^ ^ ^ | | | | +- second Third +- First if sum > target, i.e. Nums[first] + Nums[second] + nums[third] >0,third--。 If sum = target, save the current result directly.
---------------------------------------------------- ^ ^ ^ | | | | +-Second Third +-first
The condition of the loop is Second<third
---------------------------------------------------- ^ ^ ^ | | | | +-Second Third +-first
End Condition first=len-3, second = len-2, third = len-1---------------------------------------------------- ^ ^ ^ | | '-Third | +-Second +-first
AC Code:
Class Solution {public:vector<vector<int>> threesum (vector<int>& nums) {int len = num
S.size ();
vector<vector<int> > Res;
Sort (Nums.begin (), Nums.end ());
for (int index = 0;index < len;index++) {int target =-nums[index];
int front = index+1;
int back = len-1;
while (front < back) {int sum = Nums[front] + nums[back];
if (sum < target) {front++;
}else if (sum > Target) {back--;
}else{vector<int> triplet (3, 0);
Triplet[0] = Nums[index];
TRIPLET[1] = Nums[front];
TRIPLET[2] = Nums[back];
Res.push_back (triplet);
while (Front < back && Nums[front] = = triplet[1]) front++;
while (Front < back && Nums[back] = = triplet[2]) back--
; }}//while while (Index+1 < len && nums[index+1] = = Nums[index]) {index+
+;
}}//for return res; }
};
(3) 3Sum Closest
Original title address : https://leetcode.com/problems/3sum-closest/description/
Title Description:
Given an array S of n integers, find three integers in S such, the sum was closest to a Given number, target. Return the sum of the three integers. You may assume this each input would has exactly one solution.
For example, given array S = {-1 2 1-4}, and target = 1.
The sum is closest to the target is 2. (-1 + 2 + 1 = 2).
Ideas:
The previous and the same idea, just in the process of the calculation of the difference in the diff, each calculation of a result when compared with diff, if smaller than the diff, with the current results to cover the results of the previous calculation
AC Code:
Class Solution {Public:int threesumclosest (vector<int>& nums, int target) {int len = nums.size ();
if (len<3) {return 0;
} sort (Nums.begin (), Nums.end ());
int First,second,third; int diff =int_max; interval int value;
Value for (first=0;first<len-2;++first) {second = first+1;
Third = len-1;
while (second < third) {int sum = Nums[first]+nums[second]+nums[third];
if (sum = = target) {return sum;
}else if (sum < target) {if ((target-sum) < diff) {diff = target-sum;
value = SUM;
} second++;
}else{if ((Sum-target) < diff) {diff = sum-target;
value = SUM;
} third--;
}}//while}//for return value; }
};
(4) 4Sum
Original title address : https://leetcode.com/problems/4sum/description/
Title Description:
Given an array S of n integers, is there elements a, B, C, and D in S such that A + B + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
Note:the solution set must not contain duplicate quadruplets.
For example, given array S = [1, 0,-1, 0,-2, 2], and target = 0.
A solution Set is: [[-1, 0, 0, 1], [-2,-1, 1, 2], [-2, 0, 0, 2]]
Ideas:
The first two digits, the last two numbers are the same as the previous one.
AC Code:
Class Solution {public:vector<vector<int>> foursum (vector<int>& nums, int target) {ve
ctor<vector<int> > Res;
int len = Nums.size ();
if (len<4) {return res;
} sort (Nums.begin (), Nums.end ()); for (int i=0;i<len-3;++i) {if (i>0 && nums[i] = = Nums[i-1]) continue; Remove the duplicate number if ((Nums[i]+nums[i+1]+nums[i+2]+nums[i+3]) > target) break; To do some pruning, the smallest four numbers added are larger than target, there is definitely no solution if ((Nums[i]+nums[len-1]+nums[len-2]+nums[len-3]) < target) continue; To do some pruning, when I fixed, the current largest addition is more than the target small i++ for (int j=i+1;j<len-1;++j) {//And then fixed the second number if (
J>i+1 && nums[j] = = Nums[j-1]) continue;
if ((Nums[i] + nums[j] + nums[j+1] + nums[j+2]) > target) break;
if ((Nums[i] + nums[j] + nums[len-1] + nums[len-2]) < target) continue;
int left = j+1; Int right = len-1;
while (left < right) {int sum = Nums[i]+nums[j]+nums[left]+nums[right];
if (sum = = target) {res.push_back (vector<int>{nums[i], nums[j], Nums[left], Nums[right]}); do{left++;}
while (left<right && nums[left] = = nums[left-1]); do{right--;}
while (left<right && nums[right] = = nums[right+1]);
}else if (sum < target) {left++;
}else{right--;
}}}}//for return res; }
};
(5) This year Tencent's written question: patchwork coins
Title Description: Small q is very rich, has a lot of coins, small q has a regular coin, for all non-negative integer k, the small Q happens to have two denominations of 2^k coins, all small q has the coin is 1,1,2,2,4,4,8,8 ... Little Q one day to shop to buy things need to pay n yuan money, small Q want to know how many options from his own coins to pick up a piece of it is just N-yuan (if the two schemes a value of the coin selected different number of options to consider as a different scheme)
Input:
The input includes an integer n (1<=n<=10^18), which indicates how much the small Q needs to pay, and the range of n
Output:
Output an integer indicating that the small q can piece together the number of schemes of n dollars
Example input: 6
Sample output: 3 (e.g. 4+2, 4+1+1, 2+2+1+1)
General method: Use dynamic planning
Using the array dp[n, I] represents the number of scenarios that use 1,1,2,2,4,4, ..., 2^i, 2^i can be combined into n
Dp[0, I] = 1, when n=0, that is, all denominations of the coin are not selected, so there is only one solution
Dp[1, I] = 1, when n=1, only one dollar coin can be selected, so there is only one option
Res[2, 0]=1, that is, only select two one-dollar coin, so there is only one solution
Res[n, 0] = 0, when n>=3, can not only use 1 to make up more than 2 of the number, so the number of scenarios is 0
Res[n, I] = SUM (num[n-2^i*m, i-1]), N, I take other, 0<=m<=2
Code:
#include <iostream> #include <cmath> using namespace std;
int main () {int n;
while (cin>>n) {//Some special cases handle if (n = = 0 | | n = = 1) {return 1;
} int m = log (n)/log (2) + 1;
DP[N,M] int i,j;
int** DP = new INT*[N+1];
for (I=0;i<=n;++i) {dp[i] = new Int[m];
}//Initialize the two-dimensional array for (i=0;i<m;++i) {dp[0][i] = 1;
Dp[1][i] = 1;
} dp[1][0] = 1;
Dp[2][0] = 1;
for (I=1;i<=n;++i) {for (j=1;j<m;++j) {int sum = 0;
for (int m=0;m<3;++m) {int rest = (int) (I-pow (2, j) *m);
if (rest >= 0) {sum+=dp[rest][j-1];
}} Dp[i][j] = sum;
}} cout<<dp[n][m-1]<<endl;
} return 0; }
a very second thought :
Divide the coin into two parts: 1,2,4,8,16, ... and 1,2,4,8,16, ...
Composed of two values of a, b of two numbers, their and is a+b=n;
A in the first part there is only one possible combination (using the idea of a binary, any one number can be added and composed of several 2^i numbers), and B = N-a will only have a combined form.
A and B are represented using binary notation, for example n=11, with a=101, b=110 this combination, i.e. A = 1+0+4=5,b=0+2+4=6. Note, however, that there are duplicates, such as 111+100 and 101+110, which are essentially the same combination of methods, so you need to make two numbers binary or then go heavy.
Code:
#include <iostream>
#include <set>
using namespace std;
int main ()
{
int n;
while (cin>>n) {
set<int> countset;
for (int i=1;i<=n/2;i++) {
int result =i^ (n-i);
Countset.insert (result);
}
Cout<<countset.size () <<endl;
}
return 0;
}