1, two Sum
Original title address:https://leetcode.com/problems/two-sum/description/
Topic Description:
Given an array of integers, return indices of the two numbers such this they add to a specific target.
You could assume that each input would have 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 you can find out if the Target-num element exists in the complexity of O (1). If there is a subscript that returns two elements.
AC Code:
Vector<int> twosum (vector<int> &numbers, int target) {//key is the "number and value is it
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 are not
Zero based
Result.push_back (Hash[numbertofind] + 1);
Result.push_back (i + 1);
return result;
}
If it is not in the hash table, put the current element in the hash table
hash[numbers[i] = i;
}
return result;
}
(2) 3sum
Original title address : https://leetcode.com/problems/3sum/description/
Topic Description :
Given an array s of n integers, are there elements a, B, c into 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]]
train of thought: the idea of quoting the previous question, when traversing to the element num, is equivalent to two elements can be composed and for-num. However, there are occurrences of duplicate elements, so you need to sort them first.
The first element first is fixed, then second points to the next element, third points to the last element to find the Second+third=-first
---------------------------------------------------- ^ ^ ^ | | | | +-second Third +-first if Nums[first] + Nums[second] + Nums[third] < 0, this is the need to increase sum, the With second++
----------------------------------------------------^ ^ ^ | | | | +- second Third +- If sum > target, i.e. Nums[first] + Nums[second] + nums[third] >0,third--。 If sum = target, save directly the current result
---------------------------------------------------- ^ ^ ^ | | | | +-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/
Topic Description:
Given an array S of n integers, find three integers in s such so the sum is closest to a Given number, target. Return the sum of the three integers. You may assume this each input would have 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).
idea:
The previous and the same idea, just in the process of the calculation of the difference between the diff, each calculated a result of the time and diff, if smaller than the diff, with the current results covered before the results calculated
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/
Topic Description:
Given an array s of n integers, are 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]]
idea:
The first two digits, the last two are the same idea as the previous question
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 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, certainly 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 maximum addition is more than target small i++ for (int j=i+1;j<len-1;++j) {//again 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) A written question by Tencent this year: piecing together coins
Topic Description: Little Q is very rich, with a lot of coins, small q owned coins are regular, for all nonnegative integer k, small q happens to have two 2^k coins, all small q owned coins is 1,1,2,2,4,4,8,8 ... Little Q one day to shop to buy things need to pay n yuan money, little Q want to know how many options from his own coin to choose some pieces of the piece is just N-yuan (if the two options for a certain denomination of the coin selected is not the same as the number of options to consider as a different scheme)
Input:
The input includes an integer n (1<=n<=10^18), which indicates how much money the little Q needs to pay, and the range of n
Output:
Output an integer, which means that little Q can be pieced together the number of N-yuan money scheme
Sample input: 6
Sample output: 3 (e.g. 4+2, 4+1+1, 2+2+1+1)
General method: Using dynamic planning
Using the array dp[n, I] means to use 1,1,2,2,4,4, ..., 2^i, 2^i the number of schemes that can be combined into n
Dp[0, I] = 1, when n=0, that is, all the nominal coins 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 solution
Res[2, 0]=1, that is, select only two dollar coins, so there is only one solution
Res[n, 0] = 0, when n>=3, you cannot use only 1 to make up more than 2, 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) {//Special case Handling 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 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 coins into two parts: 1,2,4,8,16, ... and 1,2,4,8,16, ...
Consisting of two numbers of two of a, B, their and is a+b=n;
A in the first part there may only be a combination (binary thought, any number can be added and composed of several 2^i numbers), and B = N-a will only have a combination form.
Use A and B as a binary representation, for example n=11, a=101, b=110 This combination, that is, a = 1+0+4=5,b=0+2+4=6. But note that there are repetitions, such as 111+100 and 101+110, which are essentially the same combination method, so you need to make two numbers binary xor 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;
}