leetcode 复习(更新中)

来源:互联网 发布:python 验证码识别 编辑:程序博客网 时间:2024/05/21 00:20

1:

题目:

Median of Two Sorted Arrays

 

描述:There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

思路:想法方向没错,但是没有转换成更简洁的寻找第N个数的形式,具体代码如下:

double findKth(int a[], int m, int b[], int n, int k)  {      //always assume that m is equal or smaller than n      if (m > n)          return findKth(b, n, a, m, k);      if(m==0 && n==0)        return 0;    if (m == 0)          return b[k - 1];      if (k == 1)          return min(a[0], b[0]);      //divide k into two parts      int pa = min(k / 2, m), pb = k - pa;      if (a[pa - 1] < b[pb - 1])          return findKth(a + pa, m - pa, b, n, k - pa);      else if (a[pa - 1] > b[pb - 1])          return findKth(a, m, b + pb, n - pb, k - pb);      else          return a[pa - 1];  }    class Solution  {  public:      double findMedianSortedArrays(int A[], int m, int B[], int n)      {          int total = m + n;          if (total & 0x1)              return findKth(A, m, B, n, total / 2 + 1);          else              return (findKth(A, m, B, n, total / 2)                      + findKth(A, m, B, n, total / 2 + 1)) / 2;      }  };  
2:

题目:

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, and there exists one unique longest palindromic substring.

思路:Manacher算法,根据对称性,首先对数组进行扩充,这样奇数偶数情况都可以一起处理。代码如下:

class Solution {public:    string longestPalindrome(string s) {        int size=s.size();        if(size<=1)            return s;                string t("#");        for(int i=0;i<size;++i)            t=t+s[i]+'#';        int c=0,r=0,max=0,pos=0;        size=t.size();        vector<int> len(size,0);        for(int i=1;i<size;++i){            int mir=2*c-i;            len[i]=(i<r)?((r-i)>len[mir]?len[mir]:r-i):0;            while(i-len[i]-1>=0 && i+len[i]+1<size && t[i+len[i]+1]==t[i-len[i]-1])                len[i]++;            if(i+len[i]>r){                c=i;                r=i+len[i];            }            if(len[i]>max){                max=len[i];                pos=i;            }        }        return s.substr((pos  - max)/2, max);    } };

3:

题目: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   NA P L S I I GY   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".

思路:自己的解法比较麻烦,这个比较简明:

class Solution {public:    string convert(string s, int nRows){    if(nRows == 1) return s;    string res[nRows];    int i = 0, j, gap = nRows-2;    while(i < s.size()){        for(j = 0; i < s.size() && j < nRows; ++j) res[j] += s[i++];        for(j = gap; i < s.size() && j > 0; --j) res[j] += s[i++];    }    string str = "";    for(i = 0; i < nRows; ++i)        str += res[i];    return str;}};


4:

题目:

Container With Most Water

 

描述:

Given n non-negative integers a1a2, ..., an, where each represents a point at coordinate (iai). n vertical lines are drawn such that the two endpoints of line i is at (iai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.

Note: You may not slant the container.

思路:贪心,类似2SUM,代码如下:

int maxArea(vector<int> &height) {    int capability = 0;    size_t left = 0, right = height.size() - 1;        while (left < right)    {        const int water =             min(height[left], height[right]) * (right - left);                if (water > capability) capability = water;                if (height[left] < height[right])        {            ++left;        }        else        {            --right;        }    }        return capability;}

5:

题目: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:

"((()))", "(()())", "(())()", "()(())", "()()()"

思路:利用一个递归函数来产生,用一个参数来记录当前剩下可对应的左扩号数,只有leftNum > 0,才能加入右括号,同时增加一些剪支,例如leftNumTotal > n时说明左括号太多了,不可能产生合理解。代码如下:

class Solution {private:    vector<string> ret;public:    void solve(int dep, int maxDep, int leftNum, int leftNumTotal, string s)    {        if (leftNumTotal * 2 > maxDep)            return;                    if (dep == maxDep)        {            ret.push_back(s);            return;        }                for(int i = 0; i < 2; i++)            if (i == 0)            {                solve(dep + 1, maxDep, leftNum + 1, leftNumTotal + 1, s + '(');            }            else            {                if (leftNum > 0)                    solve(dep + 1, maxDep, leftNum - 1, leftNumTotal, s + ')');            }    }        vector<string> generateParenthesis(int n) {        // Start typing your C/C++ solution below        // DO NOT write int main() function        ret.clear();        solve(0, 2 * n, 0, 0, "");        return ret;    }};


6:Substring with Concatenation of All Words

题目:

You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any intervening characters.

For example, given:
S"barfoothefoobarman"
L["foo", "bar"]

You should return the indices: [0,9].
(order does not matter).

思路:这题整体思路没问题,但是有很多细节需要考虑,不然很容易写错,下次复习时争取一次性搞定,代码如下:

class Solution {public:    vector<int> findSubstring(string S, vector<string> &L) {        unordered_map<string, int>wordTimes;//L中单词出现的次数        for(int i = 0; i < L.size(); i++)            wordTimes[L[i]]++;        int wordLen = L[0].size();                 vector<int> res;        for(int i = 0; i < wordLen; i++)        {//为了不遗漏从s的每一个位置开始的子串,第一层循环为单词的长度            unordered_map<string, int>wordTimes2;//当前窗口中单词出现的次数            int winStart = i, cnt = 0;//winStart为窗口起始位置,cnt为当前窗口中的单词数目            for(int winEnd = i; winEnd <= (int)S.size()-wordLen; winEnd+=wordLen)            {//窗口为[winStart,winEnd)                string word = S.substr(winEnd, wordLen);                if(wordTimes.find(word) != wordTimes.end())                {                    wordTimes2[word]++;                                         if(wordTimes2[word] <= wordTimes[word])                        cnt++;                    else                    {//当前的单词在L中,但是它已经在窗口中出现了相应的次数,不应该加入窗口                     //此时,应该把窗口起始位置想左移动到,该单词第一次出现的位置的下一个单词位置                        for(int k = winStart; ; k += wordLen)                        {                            string tmpstr = S.substr(k, wordLen);                            wordTimes2[tmpstr]--;                            if(tmpstr == word)                            {                                winStart = k + wordLen;                                break;                            }                            cnt--;                        }                    }                                         if(cnt == L.size())                        res.push_back(winStart);                }                else                {//发现不在L中的单词                    winStart = winEnd + wordLen;                    wordTimes2.clear();                    cnt = 0;                }            }        }        return res;    }};


7:

题目:

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

思路:这题主要是自己求逆序数的函数不过简洁。从右往左找到第一个非增的位置,也就是找到最右递减的开始位置的前一个。定位这个。然后又从右往左找比这个数大的。交换着两个数。然后reverse之前的递减序列。代码如下:

class Solution {public:    void nextPermutation(vector<int> &num) {        int end = num.size() - 1;        int povit = end;        while(povit > 0){            if(num[povit] > num[povit - 1]) break;            povit --;        }        if(povit > 0){            povit --;             int large = end;            while(num[large] <= num[povit]) large --;            swap(num[large] , num[povit]);            reverse(num.begin() + povit + 1 , num.end());        }else{            reverse(num.begin() , num.end());        }    }};


8:

题目:

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.

思路:用一个数组保存当前下标是否是一个符合的组合中的一个,然后找出连续最长的长度。代码如下:

class Solution {  public:      int longestValidParentheses(string s) {          bool *a = new bool[s.length()];          memset(a, false, s.length());          stack<int> st;          for (int i = 0; i < s.length(); ++i) {              if (s[i] == '(') {                  st.push(i);             } else if (s[i] == ')' && !st.empty()) {                 a[i] = true;                 a[st.top()] = true;                 st.pop();             }         }         int max_len = 0, cur_len = 0;         for (int i = 0; i < s.length(); ++i) {             if (a[i]) ++cur_len;             else cur_len = 0;             max_len = max(max_len, cur_len);         }         return max_len;     } };


9:

题目:

Search in Rotated Sorted Array

 

描述:

Suppose a sorted array is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

You are given a target value to search. If found in the array return its index, otherwise return -1.

You may assume no duplicate exists in the array.

思路:总是写得不够简洁,时间效率是可以。比较简洁的代码如下:

class Solution {public:    int search(int A[], int n, int target) {        if(n<=0)            return -1;        if(n==1)            if(target==A[0])               return 0;              else return -1;                      int left=0,right=n-1;        while( left <= right){             int mid = (left + right)/2;             if(A[mid] == target) return mid;             if(A[left] < A[mid]){                 if(target <= A[mid] && target >= A[left])                     right = mid - 1;                 else left = mid + 1;             } else                 if (A[left] > A[mid]){                    if(target >= A[left] || target <= A[mid])                        right = mid -1;                    else left = mid + 1;                }                else left ++;         }         return -1;    }};


10:

题目:Combination Sum II

描述:

Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.

Each number in C may only be used once in the combination.

Note:

  • All numbers (including target) will be positive integers.
  • Elements in a combination (a1a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
  • The solution set must not contain duplicate combinations.

For example, given candidate set 10,1,2,7,6,1,5 and target 8
A solution set is: 
[1, 7] 
[1, 2, 5] 
[2, 6] 
[1, 1, 6] 

思路:要注意,每次递归过程少一次整体上能省很多时间,做到尽可能的减枝,比如,如果不考虑target<num[I],把他交给下一个递归处理判断target<0。不处理的情况,约为80多MS,而处理了直接降低到16ms。这个要注意,要尽可能的减枝。代码如下:

class Solution {public:    vector<vector<int> > combinationSum2(vector<int> &num, int target) {        vector<int> temp;        vector<vector<int> > rst;        sort(num.begin(), num.end());        dfs(num, target, temp, rst, 0);        return rst;    }    void dfs(vector<int> &num, int target, vector<int> &temp, vector<vector<int> > &rst, int pos)    {                if (target == 0)        {            rst.push_back(temp);            return;        }        for (int i = pos; i < num.size(); i++)        {            if(target>=num[i]){                temp.push_back(num[i]);                dfs(num, target - num[i], temp, rst, i + 1);                temp.pop_back();            }            while (i < num.size() - 1 && num[i] == num[i+1])                i++;        }    }};

11:

题目:

First Missing Positive

 

描述:

Given an unsorted integer array, find the first missing positive integer.

For example,
Given [1,2,0] return 3,
and [3,4,-1,1] return 2.

Your algorithm should run in O(n) time and uses constant space.

思路:感觉今天晚上状态真烂。。。代码如下,话不多说:

class Solution {public:    int firstMissingPositive(int A[], int n) {        int i;        for(i=0;i<n;){            if(A[i]<=0 || A[i]>n-1 || A[i]==i+1 || A[A[i]-1]==A[i])                i++;            else{                swap(A[A[i]-1],A[i]);            }        }        for(i=0;i<n;++i)            if(A[i]!=i+1)                break;        return i+1;    }};

题目:

Trapping Rain Water

 

描述:Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.

For example, 
Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.


The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!

思路:L,R分别设置为两头,因为移动较矮一边是可能增加area的,只要他移动的方向存在比他大的数,依次算下去,就可以得到结果,代码如下:

class Solution {public:    int trap(int A[], int n) {int secHight = 0;int left = 0;int right = n-1;int area = 0;while (left < right){if (A[left] < A[right]){secHight = max(A[left], secHight);area += secHight-A[left];//计算当前格的能装雨水的容量left++;} else {secHight = max(A[right], secHight);area += secHight-A[right];right--;}}return area;}};


13:

题目:Wildcard Matching

描述:

Implement wildcard pattern matching with support for '?' and '*'.

'?' Matches any single character.'*' Matches any sequence of characters (including the empty sequence).The matching should cover the entire input string (not partial).The function prototype should be:bool isMatch(const char *s, const char *p)Some examples:isMatch("aa","a") → falseisMatch("aa","aa") → trueisMatch("aaa","aa") → falseisMatch("aa", "*") → trueisMatch("aa", "a*") → trueisMatch("ab", "?*") → trueisMatch("aab", "c*a*b") → false


思路:用dp会超时,因为处理的数据比之前那题多,用贪心,代码如下:


class Solution {public:    bool isMatch(const char *s, const char *p) {        //? match one        //* match 0,1,2,3..        // aaaabc *c true        const char* star = nullptr;        const char* rs = nullptr;                while(*s) {            if(*s == *p || *p == '?') { //match                s++; p++;                continue;            }            if(*p == '*') {                 star = p; // record star                p++; //match from next p                rs = s; // record the position of s , star match 0                continue;            }             if(star != nullptr) { //if have star in front then backtrace                p = star + 1; //reset the position of p                 s = rs + 1;                 rs ++; //star match 1,2,3,4,5....                continue;            }            return false; //if not match return false        }        while(*p == '*') p++; //skip continue star        return *p == '\0'; // successful match    }};


14:

题目:

Rotate Image

 

描述:

You are given an n x n 2D matrix representing an image.

Rotate the image by 90 degrees (clockwise).

Follow up:
Could you do this in-place?

思路:减少循环数,每次可以得到4个连成环的数,可以不需要额外空间,主要是要控制好基数的选取,代码如下:

class Solution {public:    void rotate(vector<vector<int> > &matrix) {        int row=matrix.size();        if(row==0)            return;        int col=matrix[0].size();        if(col==0 || col!=row)            return;        if(row==1)            return;        int colmax=row-1;        for(int i=0;i<row/2;++i){            colmax--;            for(int j=i;j<=colmax;++j){                int curr,curc,nextr,nextc,curval,temp;                curr=i;curc=j;nextr=j;nextc=row-1-i;                temp=matrix[nextr][nextc];                curval=matrix[curr][curc];                if(curr==nextr && curc==nextc)                    return;                                for(int k=0;k<4;++k){                    matrix[nextr][nextc]=curval;                    curval=temp;                    curr=nextr;curc=nextc;                    nextr=curc;nextc=row-1-curr;                    temp=matrix[nextr][nextc];                }            }        }        return ;    }};


15:

题目:Permutation Sequence

描述:

The set [1,2,3,…,n] contains a total of n! unique permutations.

By listing and labeling all of the permutations in order,
We get the following sequence (ie, for n = 3):

  1. "123"
  2. "132"
  3. "213"
  4. "231"
  5. "312"
  6. "321"

Given n and k, return the kth permutation sequence.

思路:以1开头的有n-1!个,通过除法和取余确定每一位,注意当k=0时的处理,代码如下:

class Solution {public:    string getPermutation(int n, int k) {        if(n<=0)            return string();        vector<int> factorial(n);        vector<bool> check(n+1,false);                factorial[0]=1;        for(int i=1;i<n;++i){            factorial[i]=factorial[i-1]*(i+1);        }        if(k>factorial[n-1])            return string();        if(n==1)            return string("1");        string ret;        int cur;        for(int i=n-2;i>=0;i--){            cur=k/factorial[i];            k=k%factorial[i];            int j;            for(j=1;j<=n;++j){                if(check[j]==false){                    if(cur==0)                        break;                    cur--;                }            }                        if(k==0){                j--;                while(j>=1 && check[j]==true)                    j--;                ret.push_back(j+'0');                check[j]=true;                for(int l=n;l>=1;--l)                    if(check[l]==false)                        ret.push_back(l+'0');                return ret;            }            else{                check[j]=true;                ret.push_back(j+'0');            }        }        for(int j=1;j<=n ;++j){                if(check[j]==false){                    ret.push_back(j+'0');                    break;                }            }        return ret;    }};


16:

题目:

Edit Distance

 

描述:

Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)

You have the following 3 operations permitted on a word:

a) Insert a character
b) Delete a character
c) Replace a character

思路:DP,具体见代码:

class Solution {public:    int minDistance(string word1, string word2) {        int s1=word1.size(),s2=word2.size();        if(s1==0 || s2==0)            return max(s1,s2);        int row=s1+1,col=s2+1;        int pre[col],cur[col];        for(int i=0;i<col;++i)            pre[i]=i;                for(int i=1;i<row;++i){            cur[0]=i;            for(int j=1;j<col;++j){                if(word1[i-1]==word2[j-1]){                    cur[j]=pre[j-1];                }                else{                    cur[j]=pre[j-1]+1;                    cur[j]=min(cur[j],min(cur[j-1]+1,pre[j]+1));                }            }            memcpy(pre,cur,sizeof(int)*col);        }        return cur[col-1];            }};


17:
题目:Set Matrix Zeroes

描述:Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place.

思路:用第一行与第一列来保存每行的是否为0信息,提前先判断第一行与第一列是否为0

class Solution {public:    void setZeroes(vector<vector<int>>& matrix) {        int row=matrix.size();        if(row==0)            return;        int col=matrix[0].size();        if(col==0)            return;        int fr,fc;        for(int i=0;i<col;++i)            if(matrix[0][i]==0){                fr=0;                break;            }        for(int j=0;j<row;++j)            if(matrix[j][0]==0){                fc=0;                break;            }        for(int i=1;i<row;++i)            for(int j=1;j<col;++j)                if(matrix[i][j]==0){                    matrix[i][0]=0;                    matrix[0][j]=0;                }        vector<int> allzero(col,0);        for(int i=1;i<row;++i)            if(matrix[i][0]==0)                matrix[i]=allzero;        for(int i=1;i<col;++i)            if(matrix[0][i]==0)                for(int j=0;j<row;++j)                    matrix[j][i]=0;        if(fr==0)            matrix[0]=allzero;        if(fc==0)            for(int j=0;j<row;++j)                matrix[j][0]=0;        return;    }};

18:

题目:Search in Rotated Sorted Array II

描述:

Follow up for "Search in Rotated Sorted Array":
What if duplicates are allowed?

Would this affect the run-time complexity? How and why?

Write a function to determine if a given target is in the array.

代码:

class Solution {public:    bool search(vector<int>& nums, int target) {        int i = 0;        int j = nums.size() - 1;        while ( i <= j ) {            int k = (i + j) / 2;            if ( target == nums[k] )                return true;            if ( nums[k] > nums[j] /* i..k -> sorted, k+1..j -> rotated sorted */ ) {                if ( target > nums[k] ) {                    i = k + 1;                } else {                    if ( target < nums[i] ) {                        i = k + 1;                    } else if ( target > nums[i] ) {                        i = i + 1;                        j = k - 1;                    } else {                        return true;                    }                }            } else if ( nums[k] < nums[j] /* i..k -> rotated sorted, k+1..j -> sorted */ ) {                if ( target < nums[k] ) {                    j = k - 1;                } else {                    if ( target > nums[j] ) {                        j = k - 1;                    } else if ( target < nums[j] ) {                        i = k + 1;                        j = j - 1;                    } else {                        return true;                    }                }            } else {                j--; // this is introduced for duplicates            }        }        return false;    }};


19:

题目:Largest Rectangle in Histogram

Largest Rectangle in Histogram


20:

题目:Maximal Rectangle

Maximal Rectangle


21:

题目:Recover Binary Search Tree

Recover Binary Search Tree








mark:下次从序号115开始


0 0