---
# System prepended metadata

title: Algorithm

---

# Algorithm
## Knapsack 
Low efficient solution
![](https://i.imgur.com/yrKkd4R.png)
Dynamic programming
![](https://i.imgur.com/GLsUVXq.png)

https://leetcode.com/problems/coin-change/submissions/
Because in this case we tend to use larger coin, we directly substitute the smaller one with larger.
```

#define min(i, j) ((i) < (j) ? (i): (j))
int coinChange(int coins, int coinsSize, int amount){
    if(amount == 0) return 0;
    int dp[amount + 1];
    dp[0] = 0;
    for(int i = 1; i <= amount; ++i) dp[i] = amount + 1;
    for(int i = 1; i <= amount; ++i){
        for(int j = 0; j < coinsSize; ++j){
            if(coins[j] <= i){
                dp[i] = min(dp[i - coins[j]] + 1, dp[i]);
            } 
        }
    }
    if(dp[amount] == amount + 1) return -1;
    return dp[amount];
    //  0 1 2 3 4 5
    //1 0 1 2
    //2 0 0 
    //5 0 0
    //    1
}
```


## Backtracking
make sure that the value of the target doesn't exceed the sum of other numbers.
![](https://i.imgur.com/wXaxLQX.png)
## Kadane
Just compare the max_current to the current, and identify if the former is larger than the latter.
![](https://i.imgur.com/8tK0RFo.png)
https://leetcode.com/problems/maximum-product-subarray/discuss/48230/Possibly-simplest-solution-with-O(n)-time-complexity
There is an example : 
    3 -1 2
cur 3 2 4
glo 3 2 4
When cur is equal to -1, it compare 3 + -1 to -1. It turns out to be 3 + -1. As a result, we can get the maximum value when having a negative number.
very nice . I guess a bit of more explanation would help people understand:

this is very similar to the " max cumulative sum subarray" problem. here you keep 2 values: the max cumulative product UP TO current element starting from SOMEWHERE in the past, and the minimum cumuliative product UP TO current element . it would be easier to see the DP structure if we store these 2 values for each index, like maxProduct[i],minProduct[i] .

at each new element, u could either add the new element to the existing product, or start fresh the product from current index (wipe out previous results), hence the 2 Math.max() lines.

if we see a negative number, the "candidate" for max should instead become the previous min product, because a bigger number multiplied by negative becomes smaller, hence the swap()：
```
int maxProduct(int A[], int n) {
    int r = A[0];
     imax/imin stores the max/min product of
     subarray that ends with the current number A[i]
    for (int i = 1, imax = r, imin = r; i < n; i++) {
        if (A[i] < 0)
           swap(imax, imin);
        imax = max(A[i], imax * A[i]);
        imin = min(A[i], imin * A[i]);
        r = max(r, imax);
    }
    return r;
}
```

My code:
```
#define max(i, j) ((i > j) ? i : j)
#define min(i, j) ((i < j) ? i : j)
#define swap(i, j) ((i)^=(j)^=(i)^=(j))
int maxProduct(int nums, int numsSize){
    int maxn, minn;
    int num = maxn = minn = nums[0];
    for(int i = 1; i < numsSize; ++i){
        if(nums[i] < 0) swap(maxn, minn);
        maxn = max(nums[i], maxn * nums[i]);
        minn = min(nums[i], minn * nums[i]);
        num = max(maxn, num);
    }
    return num;
}*
```
# Algorithm for C++
## map.find(key value): return its iterator
If it doesn't find the value, return map.end()
## map.erase(key value): remove the value
## std::string::npos
It is usually defined like this:
static const size_t npos = -1;
```
size_t startpos = string.find_first_not_of("0");
if(string::npos != startpos) 
    return sum.substr(startpos);
```
## string.find_first_not_of('char'): finding the element that isn't included in the string.
```
string str = "000011111111";
size_t startpos = str.find_first_not_of('0');
//it returns the first value that doens't equal to the element in the string.
//If there is no such a value, it will equal string::npos.
```
![](https://i.imgur.com/EQ2xgt4.png)
## string.substr(...)
1. string.substr(pos): from the position to the end.
![](https://i.imgur.com/NbkQRg8.png)
2. string.substr(fistpos, secondpos): from the first position to the second position.
![](https://i.imgur.com/ZR7TfWI.png)
## vector_name.clear()
## vector_name.erase(iterator)
1. vector.erase(iterator)
![](https://i.imgur.com/jrDIpwb.png)
2. vector.erase(iterator1, iterator2)
![](https://i.imgur.com/6mQyis7.png)
## unique and erase
![](https://i.imgur.com/VBLYA99.png)
```
#include<algorithm>
#include<vector>
int main() {
    vector<int> v{ 1, 1, 3, 3, 3, 10, 1, 3, 3, 7, 7, 8 };
    vector<int>::iterator it = unique(v.begin(), v.end());
    //unique will shorten the vector, and it points to the fist element that 
    //is put to the last of the vector.
    //As a result, we use erase to eliminate those elements which are put backwards.
    for (auto i : v) cout << i << " ";
    cout << "\nThe first element which is put to the last " << *it << endl;
    v.erase(it, v.end());
    for (auto i : v) cout << i << " ";
    cout << "\n" << *it << endl;
}
```

# implemetation in C++
## Use a class to remove and insert the element.
Note that: there is no any duplicate allowed.
```
#include<vector>
#include<iostream>
#include<algorithm>
#include<string>
#include<unordered_map>
using namespace std;
class store {
public:
    unordered_map<int, int>map;
    vector<int> v;
    bool insert(int value) {
        if (map.find(value) != map.end()) {
            cout << "there is dupliate\n";
            return false;
        }
        v.emplace_back(value);
        map[value] = v.size() - 1;
        return true;
    }
    bool remove(int value) {
        auto it = find(v.begin(), v.end(), value);
        if (it != v.end()) {
            v.erase(it);
            int index = map[value];
            for (auto &i : map) {
                if (i.second > index) --i.second;
            }
            map.erase(value);
            //1 2 3
            return true;
        }
        else {
            cout << "no such a element in the vector\n";
            return false;
        }
    }
    bool getindex(int value) {
        if(v.size() > 0 && map.find(value) != map.end()){
            cout << value << "'s index: " << map[value] << endl;
            return true;
        }
        else {
            cout << "no such a value in the vector\n";
            return false;
        }
    }
};

int main() {
    store s;
    string ans;
    int value;
    cout << "Input: remove, insert, getindex, show map, or show array\n";
    while (1) {
        if (getline(cin, ans)){}
        else { break; }
        if (ans == "remove") {
            cout << "input the element you want to remove\n";
            value = 0;
            cin >> value;
            s.remove(value);
        }
        else if (ans == "insert") {
            cout << "input the element you want to insert\n";
            value = 0;
            cin >> value;
            s.insert(value);
        }
        else if (ans == "show map") {
            if (s.map.size() == 0) {
                cout << "no element in the map\n";
            }
            else
                for (auto i : s.map) {
                    cout << i.first << ": " << i.second << endl;
                }
        }
        else if (ans == "show array") {
            if (s.v.size() == 0)
                cout << "no element in the vector\n";
            else{
                for (auto i : s.v) {
                    cout << i << ' ';
                }
                cout << endl;
            }
        }
        else if (ans == "getindex") {
            if (s.v.size() != 0) {
                value = 0;
                cin >> value;
                s.getindex(value);
            }
            else {
                cout << "there is no value in the vector" << endl;
            }
        }
    }
}
```
![](https://i.imgur.com/4d6avGb.png)

