LeetCode Algorithm

LeetCode Algorithm

原文出处:【LeetCode

算法参考:【陈皓 coolshell

1. Two Sum

3. Longest Substring Without Repeating Characters

5. Longest Palindromic Substring

6. ZigZag Conversion

7. Reverse Integer

8. String to Integer (atoi)

9. Palindrome Number

12. Integer to Roman

13. Roman to Integer

14. Longest Common Prefix

15. 3Sum

17. Letter Combinations of a Phone Number

19. Remove Nth Node From End of List

20. Valid Parentheses

22. Generate Parentheses

24. Swap Nodes in Pairs

26. Remove Duplicates from Sorted Array

27. Remove Element

28. Implement strStr()

31. Next Permutation

32. Longest Valid Parentheses

34. Search for a Range

35. Search Insert Position

1. Two Sum

/**********************************************************
** 1. Two Sum
** Given an array of integers, return indices of the two numbers such that they add up to a specific target.
** You may assume that each input would have exactly one solution, and you may not use the same element twice.

** Example:
** Given nums = [2, 7, 11, 15], target = 9,
** Because nums[0] + nums[1] = 2 + 7 = 9,
** return [0, 1].
**********************************************************/
#include <iostream>
#include <unordered_map>
#include <vector>

using namespace std;

vector<int> twoSum(vector<int> &numbers, int target) {
    unordered_map<int, int> m;
    vector<int> result;

    for (int i=0; i<numbers.size(); ++i) {
        if (m.find(numbers[i]) == m.end()) {
            m[target-numbers[i]] = i;
        }else {
            result.push_back(m[numbers[i]]);
            result.push_back(i);
            break;
        }
    }

    return result;
}

//-----example-----
int main(int argc, char **argv) {
    vector<int> numbers = {2, 7, 11, 15};
    int target = 9;

    vector<int> result = twoSum(numbers, target);
    cout << "result[";
    for (auto it=result.begin(); it!=result.end(); ++it) {
        cout << *it;
        if (it != result.end()-1) {
            cout << ", ";
        }
    }
    cout << "]" << endl;

    return 0;
}

//-----output-----
//result[0, 1] 

3.Longest Substring Without Repeating Characters

/**********************************************************
** 3.Longest Substring Without Repeating Characters
** Given a string, find the length of the longest substring without repeating characters.
**
** Examples:
** Given "abcabcbb", the answer is "abc", which the length is 3.
** Given "bbbbb", the answer is "b", with the length of 1.
** Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring.
**********************************************************/
#include <string>
#include <iostream>
#include <map>

using namespace std;

int lengthOfLongestSubstring(string s) {
    int longestLen = 0;
    int lastRepeatPos = -1;
    map<char, int> matchCharacters;

    for (int i=0; i<s.size(); ++i) {
        if (matchCharacters.find(s[i]) != matchCharacters.end() && lastRepeatPos < matchCharacters[s[i]]) {
            lastRepeatPos = matchCharacters[s[i]];
        } 

        if (i-lastRepeatPos > longestLen) {
            longestLen = i-lastRepeatPos;
        }

        matchCharacters[s[i]] = i;
    } 

    return longestLen;    
}

//-----example-----
int main(int argc, char ** argv) {
    string s = "abcabcbb";
    cout << s << ":" << lengthOfLongestSubstring(s) << endl;

    s = "bbbbb";
    cout << s << ":" << lengthOfLongestSubstring(s) << endl;

    s = "pwwkew";
    cout << s << ":" << lengthOfLongestSubstring(s) << endl;

    return 0;
}

//-----output-----
//abcabcbb:3
//bbbbb:1
//pwwkew:3

5. Longest Palindromic Substring

/**********************************************************
** 5. Longest Palindromic Substring
** Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
** 
** Example:
** Input: "babad"
** Output: "bab"
**
** Note: "aba" is also a valid answer.
**
** Example:
** Input: "cbbd"
** Output: "bb"
**********************************************************/
#include <string>
#include <iostream>
#include <vector>

using namespace std;

string findPalindrom(string s, int left, int right) {
    while (left>=0 && right<=s.size()-1 && s[left]==s[right]) {
        left--;
        right++;
    }

    return s.substr(left+1, right-left-1);
}

string longestPalindrom(string s) {
    int n = s.size();
    if (n <= 1) return s;

    string longest;
    string str;
    for (int i=0; i<n-1; ++i) {
        str = findPalindrom(s, i, i);
        if (str.size() > longest.size()) {
            longest = str;
        }

        str = findPalindrom(s, i, i+1);
        if (str.size() > longest.size()) {
            longest = str;
        }
    }

    return longest;
}

//-----example-----
int main(int argc, char **argv) {
    string s = "babad";
    cout << s << " : " << longestPalindrom(s) << endl;

    s = "cbbd";
    cout << s << " : " << longestPalindrom(s) << endl;

    return 0;
}

//-----output-----
//babad : bab
//cbbd : bb

 6. ZigZag Conversion

/**********************************************************
** 6. ZigZag Conversion
** The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)
**
** P   A   H   N
** A P L S I I G
** Y   I   R
** And then read line by line: "PAHNAPLSIIGYIR"
** Write the code that will take a string and make this conversion given a number of rows:
** 
** string convert(string text, int nRows);
** convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR".
**********************************************************/
#include <string>
#include <iostream>
#include <vector>

using namespace std;

string zigzagConvert(string s, int rows) {
    if (rows<=1 || rows>=s.size()) return s;

    vector<string> r(rows);
    int index = 0;
    int step = 1;
    for (int i=0; i<s.size(); ++i) {
        if (index == 0) step = 1;
        if (index == rows-1) step = -1;
        r[index] += s[i];
        index += step;
    }

    string result;
    for (int i=0; i<rows; ++i)
    {
        result += r[i];
    }

    return result;
}

//-----example-----
int main(int argc, char **argv) {
    string s = "PAYPALISHIRING";
    int rows = 3;

    cout << s << "[" << rows << "]:" <<zigzagConvert(s, rows) << endl;

    return 0;
}

//-----output-----
//PAYPALISHIRING[3]:PAHNAPLSIIGYIR

7. Reverse Integer

/**********************************************************
** 7. Reverse Integer
** Reverse digits of an integer.
** 
** Example1: x = 123, return 321
** Example2: x = -123, return -321
** 
** click to show spoilers.
** 
** Note:
** The input is assumed to be a 32-bit signed integer. Your function should return 0 when the reversed integer overflows.
**********************************************************/
#include <iostream>

using namespace std;

#define INT_MAX_VALUE 2147483647
#define INT_MIN_VALUE (-INT_MAX_VALUE-1)

int reverseInterget(int x) {
    int result = 0;
    int n = 0;

    while (x != 0) {
        n = x%10;
        if (result>INT_MAX_VALUE/10 || result <INT_MIN_VALUE/10) {
            return 0;
        }

        result = result*10+n;
        x /=10;
    }

    return result;
}

//-----example-----
int main(int argc, char **argv) {
    cout << "123 : " << reverseInterget(123) << endl;
    cout << "-123 : " << reverseInterget(-123) << endl;
    cout << "1020 : " << reverseInterget(1020) << endl;
    cout << "2147483647 : " << reverseInterget(2147483647) << endl;
    cout << "-2147483648 : " << reverseInterget(-2147483648) << endl;

    return 0;
}

//-----output-----
//123 : 321
//-123 : -321
//1020 : 201
//2147483647 : 0
//-2147483648 : 0

8. String to Integer (atoi)

/**********************************************************
** 8. String to Integer (atoi)
** Implement atoi to convert a string to an integer.
**
** Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases.
**
** Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front.
**********************************************************/
#include <iostream>
#include <ctype.h>

using namespace std;

#define INT_MAX_VALUE 2147483647
#define INT_MIN_VALUE (-INT_MAX_VALUE-1)

int stringToInterget(const char *str) {
    if (str==nullptr || *str=='') {
        return 0;
    }

    int ret = 0;
    for (; isspace(*str); str++);

    bool bNeg = false;
    if (*str=='-' || *str=='+') {
        bNeg = (*str=='-');
        str++;
    }

    for (; isdigit(*str); str++) {
        int digit = (*str-'0');
        if (bNeg) {
            if (-ret < (INT_MIN_VALUE+digit)/10) {
                return INT_MIN_VALUE;
            }
        } else {
            if (ret > (INT_MAX_VALUE-digit)/10) {
                return INT_MAX_VALUE;
            }
        }

        ret = 10*ret + digit;
    }

    return bNeg?-ret:ret;
}

//-----example-----
int main(int argc, char **argv) {
    cout << "123:" << stringToInterget("123") << endl;
    cout << "+123:" << stringToInterget("+123") << endl;
    cout << "-123:" << stringToInterget("-123") << endl;
    cout << "123abc:" << stringToInterget("123abc") << endl;
    cout << "abc123:" << stringToInterget("abc123") << endl;
    cout << "   123:" << stringToInterget("   123") << endl;
    cout << "123   :" << stringToInterget("123   ") << endl;
    cout << "0123:" << stringToInterget("0123") << endl;
    cout << "2147483647:" << stringToInterget("2147483647") << endl;
    cout << "2147483648:" << stringToInterget("2147483648") << endl;
    cout << "-2147483648:" << stringToInterget("-2147483648") << endl;
    cout << "-2147483649:" << stringToInterget("-2147483649") << endl;

    return 0;
}

//-----output-----
//123:123
//+123:123
//-123:-123
//123abc:123
//abc123:0
//   123:123
//123   :123
//0123:123
//2147483647:2147483647
//2147483648:2147483647
//-2147483648:-2147483648
//-2147483649:-2147483648

9. Palindrome Number

/**********************************************************
** 9. Palindrome Number
** Determine whether an integer is a palindrome. Do this without extra space.
**********************************************************/
#include <iostream>
using namespace std;

bool isPalindromeNum(int x) {
    if (x < 0) return false;

    int sourceX = x;
    int reverseX = 0;
    int n = 0;
    while (x != 0) {
        n = x % 10;
        reverseX = reverseX*10 + n;
        x /= 10;
    }

    return (sourceX == reverseX);
}

//-----example-----
int main(int argc, char **argv) {
    cout << "0 : " << isPalindromeNum(0) << endl;
    cout << "121 : " << isPalindromeNum(121) << endl;
    cout << "-121 : " << isPalindromeNum(-121) << endl;
    cout << "1234 : " << isPalindromeNum(1234) << endl;

    return 0;
}

//-----output-----
//0 : 1
//121 : 1
//-121 : 0
//1234 : 0

12. Integer to Roman

/**********************************************************
** 12. Integer to Roman
** Given an integer, convert it to a roman numeral.
** 
** Input is guaranteed to be within the range from 1 to 3999.

** Roman and Integer
** 1    5    10   50   100  500  1000
** I    V    X    L    C    D    M
**
** 1    2    3    4    5    6    7    8    9
** I    II   III  IV   V    VI   VII  VIII IX
**
** 10   20   30   40   50   60   70   80   90
** X    XX   XXX  XL   L    LX   LXX  LXXX XC
**
** 100  200  300  400  500  600  700  800  900
** C    CC   CCC  CD   D    DC   DCC  DCCC CM
**********************************************************/
#include <iostream>
#include <string>

using namespace std;

string intToRoman(int num) {
    string romanSymbol[] = { "M",  "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
    int intValue[] =       {1000,   900, 500,  400, 100,   90,  50,   40,  10,    9,   5,    4,  1};

    if (num < 1 || num > 3999) return "-";

    string result;
    for (int i=0; num!=0; ++i) {
        while (num >= intValue[i]) {
            num -= intValue[i];
            result += romanSymbol[i];
        }
    }

    return result;
}

//-----example-----
int main(int argc, char ** argv) {
    cout << "0    : " << intToRoman(0) << endl;
    cout << "1    : " << intToRoman(1) << endl;
    cout << "19   : " << intToRoman(19) << endl;
    cout << "198  : " << intToRoman(198) << endl;
    cout << "1984 : " << intToRoman(1984) << endl;
    cout << "4000 : " << intToRoman(4000) << endl;

    return 0;
}

//-----output-----
//0    : -
//1    : I
//19   : XIX
//198  : CXCVIII
//1984 : MCMLXXXIV
//4000 : -

13. Roman to Integer

/**********************************************************
** 13. Roman to Integer
**
** Given a roman numeral, convert it to an integer.
** Input is guaranteed to be within the range from 1 to 3999.
**
** Roman and Integer
** 1    5    10   50   100  500  1000
** I    V    X    L    C    D    M
**
** Rule
** If a numeric symbol appears after a larger numeric symbol, use "+"
** eg: VI = V, I = 5+1 = 6

** If a numeric symbol appears in front of a larger numeric symbol, use "-"
** eg: IX = X, I = 10-1 = 9
**********************************************************/
#include <iostream>
#include <string>
#include <map>

using namespace std;

int valueOfRomanChar(char ch) {
    map<char, int> romanValue = {{'I',1}, {'V',5}, {'X',10}, {'L',50}, {'C',100}, {'D',500}, {'M',1000}};
    return romanValue[ch];
}

int romanToInteger(string s) {
    if (s.size() <= 0) return 0;

    int result = valueOfRomanChar(s[0]);
    if (result == 0) return 0;

    for (int i=1; i<s.size(); ++i) {
        int prev = valueOfRomanChar(s[i-1]);
        int curr = valueOfRomanChar(s[i]);
        if (curr == 0) return 0;

        if (prev < curr) {
            result = result - prev + (curr-prev);
        } else {
            result += curr; 
        }
    }

    return result;
}

//-----example-----
int main(int argc, char **argv) {
    cout << "          : " << romanToInteger("") << endl;
    cout << "ABC       : " << romanToInteger("ABC") << endl;
    cout << "MCMLXXXIV : " << romanToInteger("MCMLXXXIV") << endl;
    cout << "CXCVIII   : " << romanToInteger("CXCVIII") << endl;
    cout << "XIX       : " << romanToInteger("XIX") << endl;
    cout << "I         : " << romanToInteger("I") << endl;

    return 0;
}

//-----output-----
//          : 0
//ABC       : 0
//MCMLXXXIV : 1984
//CXCVIII   : 198
//XIX       : 19
//I         : 1

14. Longest Common Prefix

/**********************************************************
** 14. Longest Common Prefix
** Write a function to find the longest common prefix string amongst an array of strings.
**********************************************************/
#include <iostream>
#include <string>
#include <vector>

using namespace std;

string longestCommonPrefix(vector<string> &strs) {
    string commonPrefix = "";
    if (strs.size() <= 0) return commonPrefix;

    for (int i=1; i<strs[0].size(); ++i) {
        string matchPrefix = strs[0].substr(0, i);
        bool bMatch = true;
        for (int j=1; j<strs.size(); j++) {
            if (i>strs[j].size() || matchPrefix!=strs[j].substr(0,i)) {
                bMatch = false;
                break;
            }
        }

        if (!bMatch) {
            return commonPrefix;
        }
        commonPrefix = matchPrefix;
    }

    return commonPrefix;
}

//-----example-----
int main(int argc, char **argv) {
    vector<string> strs = {"abab", "aba", "ab"};
    cout << "["abab", "aba", "ab"] : " << longestCommonPrefix(strs) << endl;

    vector<string> strs2 = {"abab", "ba"};
    cout << "["abab", "ba"] : " << longestCommonPrefix(strs2) << endl;
    return 0;
}

//-----output-----
//["abab", "aba", "ab"] : ab
//["abab", "ba"] : 

15. 3Sum

/**********************************************************
** 15. 3Sum
** Given an array S of n integers, are 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]
** ]
**********************************************************/
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

vector<vector<int> > threeSum(vector<int> &arrayNum) {
    vector<vector<int> > result;

    if (arrayNum.size() < 3) return result;
    sort(arrayNum.begin(), arrayNum.end());

    int n = arrayNum.size();
    for (int i=0; i<n-2; ++i) {
        if (i>0 && arrayNum[i-1]==arrayNum[i]) continue;

        int a = arrayNum[i];
        int low = i+1;
        int high = n-1;
        while (low < high) {
            int b = arrayNum[low];
            int c = arrayNum[high];
            if (a+b+c == 0) {
                vector<int> v = {a, b, c};
                result.push_back(v);

                while (low<n-1 && arrayNum[low]==arrayNum[low+1]) ++low;
                while (high>0 && arrayNum[high]==arrayNum[high-1]) --high;
                ++low;
                --high;
            } else if (a+b+c > 0){
                while (high>0 && arrayNum[high]==arrayNum[high-1]) --high;
                --high;
            } else {
                while (low<n-1 && arrayNum[low]==arrayNum[low+1]) ++low;
                ++low;
            }
        }
    }

    return result;
}

void printVector(vector<int> &vectorArray) {
    cout << "[";
    for (auto it=vectorArray.begin(); it!=vectorArray.end(); ++it) {
        cout << *it;
        if (it != vectorArray.end()-1) cout << ", ";
    }
    cout << "]";
}

//-----example-----
int main(int argc, char **argv) {
    vector<int> arrayNum = {-1, 0, 1, 2, -1, -4};
    printVector(arrayNum);
    cout << " : {";

    vector<vector<int> > result = threeSum(arrayNum);
    for (auto it=result.begin(); it!=result.end(); ++it) {
        printVector(*it);
        if (it != result.end()-1) cout << ", ";
    }
    cout << "}" << endl;

    return 0;    
}

//-----output-----
//[-1, 0, 1, 2, -1, -4] : {[-1, -1, 2], [-1, 0, 1]}

17. Letter Combinations of a Phone Number

/**********************************************************
** 17. Letter Combinations of a Phone Number
** Given a digit string, return all possible letter combinations that the number could represent.
**
** A mapping of digit to letters (just like on the telephone buttons).
**
** Input:Digit string "23"
** Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
**
** Note:
** Although the above answer is in lexicographical order, your answer could be in any order you want.
**********************************************************/
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

vector <string> telLetterCombinations(string strDigit) {
    vector<string> result;
    int digitNums = strDigit.size();

    if (digitNums <= 0) {
        result.push_back("");
        return result;
    }

    char phoneSymbols[10][4] = {
        {' ', '_', '_', '_'}, //0
        {'_', '_', '_', '_'}, //1
        {'a', 'b', 'c', '_'}, //2
        {'d', 'e', 'f', '_'}, //3
        {'g', 'h', 'i', '_'}, //4
        {'j', 'k', 'l', '_'}, //5
        {'m', 'n', 'o', '_'}, //6
        {'p', 'q', 'r', 's'}, //7
        {'t', 'u', 'v', '_'}, //8
        {'w', 'x', 'y', 'z'}  //9
    };
    
    for (int i=0; i<digitNums; ++i) {
        if (!isdigit(strDigit[i])) {
            result.clear();
            return result;
        }

        int index = strDigit[i] - '0';
        if (result.size() <= 0) {
            for (int j=0; j<4&&phoneSymbols[index][j]!='_'; ++j) {
                string s;
                s += phoneSymbols[index][j];
                result.push_back(s);
            }
            continue;
        }

        vector<string> r;
        for (int j=0; j<result.size(); ++j) {
            for (int k=0; k<4&&phoneSymbols[index][k]!='_'; ++k) {
                string s = result[j] + phoneSymbols[index][k];
                r.push_back(s);
            }
        }
        result = r;
    }

    return result;
}

void printVector(vector<string> &s) {
    cout << "[";
    for (auto it=s.begin(); it!=s.end(); ++it) {
        cout << *it;
        if (it != s.end()-1) cout << ", ";
    }
    cout << "]" << endl;
}

int main(int argc, char **argv) {
    vector<string> str23 = telLetterCombinations("23");
    cout << "23  : ";
    printVector(str23);

    vector<string> str1 = telLetterCombinations("1");
    cout << "1   : ";
    printVector(str1);

    vector<string> str3a = telLetterCombinations("3a");
    cout << "3a  : ";
    printVector(str3a);

    vector<string> str203 = telLetterCombinations("203");
    cout << "203 : ";
    printVector(str203);
    
    return 0;
}

//-----output-----
//23  : [ad, ae, af, bd, be, bf, cd, ce, cf]
//1   : []
//3a  : []
//203 : [a d, a e, a f, b d, b e, b f, c d, c e, c f]

19. Remove Nth Node From End of List

/**********************************************************
** 19. Remove Nth Node From End of List
** Given a linked list, remove the nth node from the end of list and return its head.
**
** For example,
**
** Given linked list: 1->2->3->4->5, and n = 2.
** After removing the second node from the end, the linked list becomes 1->2->3->5.
**
** Note:
** Given n will always be valid.
** Try to do this in one pass.
**********************************************************/
#include <iostream>
#include <vector>

using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(nullptr) {}
};

ListNode *removeNthNodeOfEnd(ListNode *head, int n) {
    if (head==nullptr || n<=0) return nullptr;

    ListNode fakeHead(0);
    fakeHead.next = head;
    head = &fakeHead;

    ListNode *p1 = head;
    ListNode *p2 = head;
    for (int i=0; i<n; ++i) {
        if (p2 == nullptr) return nullptr;
        p2 = p2->next;
    }

    while (p2->next != nullptr) {
        p2 = p2->next;
        p1 = p1->next;
    }

    p1->next = p1->next->next;

    return head->next;
}

ListNode *createListNode(vector<int> valVector) {
    ListNode *head = nullptr;
    ListNode *p = nullptr;

    for (auto it=valVector.begin(); it!=valVector.end(); ++it) {
        if (head == nullptr) {
            p = new ListNode(*it);
            head = p;
        } else {
            p->next = new ListNode(*it);
            p = p->next;
        }
    }

    return head;
}

void printListNode(ListNode *pListNode) {
    while (pListNode != nullptr) {
        cout << pListNode->val;
        if (pListNode->next != nullptr) cout << "->";
        pListNode = pListNode->next;
    }
}

//-----example-----
int main(int argc, char **argv) {
    vector<int> arrayList = {1,2,3,4,5};
    ListNode *pList = createListNode(arrayList);
    printListNode(pList);
    cout << ", n=2" <<endl;
    
    ListNode *pRemoveList = removeNthNodeOfEnd(pList, 2);
    printListNode(pRemoveList);
    cout << endl;

    return 0;
}

//-----output-----
//1->2->3->4->5, n=2
//1->2->3->5

20. Valid Parentheses

/**********************************************************
** 20. Valid Parentheses
**
** Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.
**
** The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not.
**********************************************************/
#include <iostream>
#include <string>
#include <stack>

using namespace std;

bool isValidParentheses(string s) {
    if (s.size() <= 0) return true;

    stack<char> stackCh;
    for (auto ch : s) {
        if (ch=='(' || ch=='{' || ch=='[') {
            stackCh.push(ch);
        } else if (ch==')' || ch=='}' || ch==']') {
            if (stackCh.empty()) return false;

            char sch = stackCh.top();
            if ((ch==')' && sch=='(') || (ch=='}' && sch=='{') || (ch==']' && sch=='[')) {
                stackCh.pop();
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    return stackCh.empty();
}

//-----example-----
int main(int argc, char **argv) {
    cout << """       : " << isValidParentheses("") << endl;    
    cout << ""()"     : " << isValidParentheses("()") << endl;
    cout << ""()[]{}" : " << isValidParentheses("()[]{}") << endl;
    cout << ""([)]"   : " << isValidParentheses("([)]") << endl;

    return 0;
}

//-----output-----
//""       : 1
//"()"     : 1
//"()[]{}" : 1
//"([)]"   : 0

22. Generate Parentheses

/**********************************************************
** 22. Generate Parentheses
** Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
** 
** For example, given n = 3, a solution set is:
**
** [
**   "((()))",
**   "(()())",
**   "(())()",
**   "()(())",
**   "()()()"
** ]
**********************************************************/
#include <iostream>
#include <vector>
#include <string>

using namespace std;

void generatorSubParentheses(vector<string> &result, int left, int right, string s) {
    if (left==0 && right==0) {
        result.push_back(s);
        return;
    }

    if (left > 0) {
        generatorSubParentheses(result, left-1, right, s+'(');
    }

    if (right>0 && right>left) {
        generatorSubParentheses(result, left, right-1, s+')');
    }
}

vector<string> generatorParentheses(int n) {
    vector<string> result;
    string s;
    generatorSubParentheses(result, n, n, s);

    return result;
}

void printVector(vector<string> &result) {
    for (int i=0; i<result.size(); ++i) {
        cout << "  "" <<result[i] << """;
        if (i != result.size()-1) cout << ",";
        cout << endl;
    }
}

//-----example-----
int main(int argc, char **argv) {
    vector<string> result = generatorParentheses(3);
    cout << "3 parentheses:" << endl;
    cout <<"[" << endl;
    printVector(result);
    cout << "]" << endl;

    return 0;
}

//-----output-----
//3 parentheses:
//[
//  "((()))",
//  "(()())",
//  "(())()",
//  "()(())",
//  "()()()"
//]

24. Swap Nodes in Pairs

/**********************************************************
** 24. Swap Nodes in Pairs
** Given a linked list, swap every two adjacent nodes and return its head.
**
** For example,
** Given 1->2->3->4, you should return the list as 2->1->4->3.
** 
** Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.
**********************************************************/
#include <iostream>
#include <vector>

using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(nullptr) {}
};

ListNode *swapPairsNodes(ListNode *head) {
    for (auto p=head; p!=nullptr&&p->next!=nullptr; p=p->next->next) {
        int tempVal = p->val;
        p->val = p->next->val;
        p->next->val = tempVal;
    }

    return head;
}

ListNode *createListNode(vector<int> vectorVal) {
    ListNode *head = nullptr;
    ListNode *p = nullptr;

    for (auto it=vectorVal.begin(); it!=vectorVal.end(); ++it) {
        if (head == nullptr) {
            p = new ListNode(*it);
            head = p;
        } else {
            p->next = new ListNode(*it);
            p = p->next;
        }
    }

    return head;
}

void printListNode(ListNode *pListNode) {
    while (pListNode != nullptr) {
        cout << pListNode->val;
        if (pListNode->next != nullptr) cout << "->";
        pListNode = pListNode->next;
    }
}

//-----example-----
int main(int argc, char **argv) {
    vector<int> listVector = {1,2,3,4};
    ListNode *sourceListNode = createListNode(listVector);
    printListNode(sourceListNode);
    cout << endl << "swap nodes in pairs:" << endl;

    ListNode *destListNode = swapPairsNodes(sourceListNode);
    printListNode(destListNode);
    cout << endl;

    return 0;
}

//-----output-----
//1->2->3->4
//swap nodes in pairs:
//2->1->4->3

26. Remove Duplicates from Sorted Array

/**********************************************************
** 26. Remove Duplicates from Sorted Array
** Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length.
**
** Do not allocate extra space for another array, you must do this in place with constant memory.
**
** For example,
** Given input array nums = [1,1,2],
** 
** Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length.
**********************************************************/
#include <iostream>

using namespace std;

int removeDuplicatesSortedArray(int A[], int n) {
    if (n <= 1) return n;

    int index = 0;
    for (int i=0; i<n-1; ++i) {
        if (A[i] != A[i+1]) {
            A[++index] = A[i+1];
        }
    }

    return index+1;
}

//-----example-----
int main(int argc, char **argv) {
    int A[] = {1, 1, 2};
    int n = sizeof(A)/sizeof(int);

    cout << "Given array :[";
    for (int i=0; i<n; ++i) {
        cout << A[i];
        if (i != n-1) cout << ",";
    }
    cout << "]" << endl;

    int len = removeDuplicatesSortedArray(A,n);
    cout << "length = " << len << endl;
    cout << "Dest array :[";
    for (int i=0; i<len; ++i) {
        cout << A[i];
        if (i != len-1) cout << ",";
    }
    cout << "]" << endl;

    return 0;
}

//-----output-----
//Given array :[1,1,2]
//length = 2
//Dest array :[1,2]

27. Remove Element

/**********************************************************
** 27. Remove Element
** Given an array and a value, remove all instances of that value in place and return the new length.
** 
** Do not allocate extra space for another array, you must do this in place with constant memory.
** 
** The order of elements can be changed. It doesn't matter what you leave beyond the new length.
** 
** Example:
** Given input array nums = [3,2,2,3], val = 3
** 
** Your function should return length = 2, with the first two elements of nums being 2.
**********************************************************/
#include <iostream>
#include <vector>

using namespace std;

int removeElement(vector<int> &array, int val) {
    int length = 0;
    int arraySize = array.size();
    
    if (arraySize <= 0) return length;

    for (int i=0; i<arraySize; ++i) {
        if (array[i] != val) {
            array[length++] = array[i];
        }
    }

    array.resize(length);

    return length;
}

void printVector(vector<int> &array) {
    cout << "[";
    for (int i=0; i<array.size(); ++i) {
        cout << array[i];
        if (i != array.size()-1) cout << ",";
    }
    cout << "]";
}

//-----example-----
int main(int argc, char **argv) {
    vector<int> array = {3,2,2,3};
    cout << "Source array:";
    printVector(array);
    cout << endl;

    cout << "Remove element val=3, then length = " << removeElement(array, 3) << endl;

    cout << "Dest array:";
    printVector(array);
    cout << endl;

    return 0;
}

//-----output-----
//Source array:[3,2,2,3]
//Remove element val=3, then length = 2
//Dest array:[2,2]

28. Implement strStr()

/**********************************************************
** 28. Implement strStr()
** 
** Returns a pointer to the first occurrence of needle in haystack, or null if needle is not part of haystack.
**********************************************************/
#include <iostream>
#include <string>

using namespace std;

int strStr(string haystack, string needle) {
    int lenH = haystack.size();
    int lenN = needle.size();

    if (lenH<=0 || lenN<=0 || lenN>lenH) return -1;

    int indexH = 0;
    int indexN = 0;
    while (indexH<lenH && indexN<lenN) {
        if (indexN >= lenN) break;

        if (haystack[indexH] == needle[indexN]) {
            ++indexN;    
        } else {
            indexN = 0;
        }
        ++indexH;
    }

    if (indexN >= lenN) return (indexH-lenN);

    return -1;
}

//-----example-----
int main(int argc, char **argv) {
    cout <<  ""hello world", ""      : " << strStr("hello world", "") << endl; 
    cout <<  """, "world"            : " << strStr("", "world") << endl;
    cout << ""hello world", "world" : " << strStr("hello world", "world") << endl;
    cout << ""hello world", "word"  : " << strStr("hello world", "word") << endl;
        
    return 0;    
}

//-----output-----
//"hello world", ""      : -1
//"", "world"            : -1
//"hello world", "world" : 6
//"hello world", "word"  : -1

31. Next Permutation

/**********************************************************
** 31. Next Permutation
** Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.
**
** If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).
** 
** The replacement must be in-place, do not allocate extra memory.
**
** Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
** 1,2,3 → 1,3,2
** 3,2,1 → 1,2,3
** 1,1,5 → 1,5,1
**
** ---------------------------------------
** The pattern can be descripted as below:
**
**    1) from n-1 to 0, find the first place [i-1] which num[i-1] < num[i]
**    2) from n-1 to i, find the first number from n-1 to i which >= num[i-1]
**    3) swap the 2) num with the num[i-1]
**    4) sort the sub-array [i, n) //actuall sort is fine as well
** 
** For example:
** 
**     1 4 3 2   <-- 1) find the first place which num[i-1] < num[i]
**     ^
** 
**     1 4 3 2   <-- 2) find the first number from n-1 to i which >= num[i-1]
**     ^     ^  
** 
**     2 4 3 1   <-- 3) swap them
**     ^     ^
** 
**     2 4 3 1   <-- 4) sort
**       ^   ^
**
**     2 1 3 4   
** 
** Edge Case:
**
**     4 3 2 1, the next permutation is 1 2 3 4
**********************************************************/
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

void nextPermutation(vector<int> &num) {
    if (num.size() <= 1) return;

    for (int i=num.size()-1; i>0; --i) {
        if (num[i-1] < num[i]) {
            int j = num.size()-1;
            while (num[i-1] > num[j]) --j;

            int tmp = num[j];
            num[j] = num[i-1];
            num[i-1] = tmp;
            
            sort(num.begin()+i, num.end());
            return;
        }

        if (i == 1) {
            sort(num.begin(), num.end());
            return;
        }
    }
}

void printVector(vector<int> &num) {
    for (auto it=num.begin(); it!=num.end(); ++it) {
        cout << *it;
        if (it != num.end()-1) cout << ",";
    }
}

void testVector(vector<int> &num) {
    printVector(num);
    cout << " -> ";
    nextPermutation(num);
    printVector(num);
    cout << endl;
}

//-----example-----
int main(int argc, char **argv) {
    vector<int> num = {1,2,3};
    testVector(num);

    num = {3,2,1};
    testVector(num);

    num = {1,1,5};
    testVector(num);

    num = {1,4,3,2};
    testVector(num);

    num = {4,3,2,1};
    testVector(num);

    return 0;
}

//-----output-----
//1,2,3 -> 1,3,2
//3,2,1 -> 1,2,3
//1,1,5 -> 1,5,1
//1,4,3,2 -> 2,1,3,4
//4,3,2,1 -> 1,2,3,4

32. Longest Valid Parentheses

/**********************************************************
** 32. Longest Valid Parentheses
** Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.
** 
** For "(()", the longest valid parentheses substring is "()", which has length = 2.
** 
** Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4.
**********************************************************/

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int longestValidParentheses(string s, string &subs) {
    if (s.size() <= 1) return 0;

    int longestLen = 0;
    int lastErrPos = -1;
    int matchPos = -1;
    vector<int> matchStack;

    for (int i=0; i<s.size(); ++i) {
        if (s[i] == '(') {
            matchStack.push_back(i);
        } else if (s[i] == ')') {
            if (matchStack.size() > 0) {
                matchStack.pop_back();
                int len;
                if (matchStack.size() == 0) {
                    len = i - lastErrPos;
                    matchPos = lastErrPos + 1;
                } else {
                    len = i - matchStack.back();
                    matchPos = matchStack.back() + 1;
                }

                if (len > longestLen) {
                    longestLen = len;
                    subs = s.substr(matchPos, longestLen);
                }
            } else {
                lastErrPos = i;
            }
        }

    }

    return longestLen;
}

void testFun(string s, string &subs) {
    cout << "string   : " << s << endl;
    cout << "length   : " << longestValidParentheses(s, subs) << endl;
    cout << "substring: " << subs << endl;
    cout << "------------------------" << endl;
}

//-----example-----
int main(int argc, char **argv) {
    string subs;

    string s = "(()";
    testFun(s, subs);

    s = ")()())";
    testFun(s, subs);

    s = "()((())))()";
    testFun(s, subs);

    return 0;
}

//-----output-----
//string   : (()
//length   : 2
//substring: ()
//------------------------
//string   : )()())
//length   : 4
//substring: ()()
//------------------------
//string   : ()((())))()
//length   : 8
//substring: ()((()))
//------------------------

34. Search for a Range

/**********************************************************
** 34. Search for a Range
** Given an array of integers sorted in ascending order, find the starting and ending position of a given target value.
**
** Your algorithm's runtime complexity must be in the order of O(log n).
**
** If the target is not found in the array, return [-1, -1].
**
** For example,
** Given [5, 7, 7, 8, 8, 10] and target value 8,
** return [3, 4].
**********************************************************/
#include <iostream>
#include <vector>

using namespace std;

int binarySearch(vector<int> array, int low, int high, int key) {
    while (low <= high) {
        int mid = low + (high - low) / 2;
        if (array[mid] == key) {
            return mid;
        }

        if (key > array[mid]) {
            low = mid + 1;
        }

        if (key < array[mid]) {
            high = mid - 1;
        }
    }

    return -1;
}

vector<int> searchRange(vector<int> array, int target) {
    vector<int> result;
    
    int nums = array.size();
    if (nums <= 0) {
        result = {-1, -1};
    }

    int pos = binarySearch(array, 0, nums-1, target);
    int low = -1;
    int high = -1;

    if (pos >= 0) {
        low = pos;
        high = pos;

        int lowPos = low;
        do {
            low = lowPos;
            lowPos = binarySearch(array, 0, low-1, target);
        } while(lowPos >= 0);

        int highPos = high;
        do {
            high = highPos;
            highPos = binarySearch(array, high+1, nums-1, target);
        } while (highPos >= 0);
    }

    result.push_back(low);
    result.push_back(high);

    return result;
}

void printVector(vector<int> array) {
    cout << "[";
    for (int i=0; i<array.size(); ++i) {
        cout << array[i];
        if (i != array.size()-1) cout << ",";
    }
    cout << "]";
}

//-----example-----
int main(int argc, char **argv) {
    vector<int> array = {5,7,7,8,8,10};
    int target = 8;

    vector<int> result = searchRange(array, target);
    printVector(array);
    cout << ", target:" << target << " then result:";
       printVector(result);
    cout << endl;

    target = 9;
    result = searchRange(array, target);
    printVector(array);
    cout << ", target:" << target << " then result:";
       printVector(result);
    cout << endl;

    array = {5,5,5,5,5,5};
    target = 5;
    result = searchRange(array, target);
    printVector(array);
    cout << ",  target:" << target << " then result:";
       printVector(result);
    cout << endl;

    return 0;
}

//-----output-----
//[5,7,7,8,8,10], target:8 then result:[3,4]
//[5,7,7,8,8,10], target:9 then result:[-1,-1]
//[8,8,8,8,8,8],  target:8 then result:[0,5]

35. Search Insert Position

/**********************************************************
** 35. Search Insert Position
** Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.
**
** You may assume no duplicates in the array.
**
** Here are few examples.
** [1,3,5,6], 5 → 2
** [1,3,5,6], 2 → 1
** [1,3,5,6], 7 → 4
** [1,3,5,6], 0 → 0
**********************************************************/
#include <iostream>
#include <vector>

using namespace std;

int searchInsertPos(vector<int> array, int target) {
    int nums = array.size();
    if (nums <= 0) return 0;

    for (int i=0; i<nums; ++i) {
        if (array[i] >= target) {
            return i;
        }
    }

    return nums;
}

//-----example-----
int main(int argc, char **argv) {
    vector<int> array = {1,3,5,6};
    cout << "[1,3,5,6], 5 -> " << searchInsertPos(array, 5) << endl;
    cout << "[1,3,5,6], 2 -> " << searchInsertPos(array, 2) << endl;
    cout << "[1,3,5,6], 7 -> " << searchInsertPos(array, 7) << endl;
    cout << "[1,3,5,6], 0 -> " << searchInsertPos(array, 0) << endl;

    return 0;
}

//-----output-----
//[1,3,5,6], 5 -> 2
//[1,3,5,6], 2 -> 1
//[1,3,5,6], 7 -> 4
//[1,3,5,6], 0 -> 0
原文地址:https://www.cnblogs.com/sz-leez/p/6873841.html