LeetCode经典题目笔记(一)

关于算法与数据结构的相关博文:

KMP算法相关学习资料
二叉树相关练习题(C++)
经典排序算法的C++实现
与字符串有关的一些典型问题的C++解法
一些可以用动态规划(DP)算法解决的问题(C++)
排列组合相关笔试面试题(C++)
与概率相关的算法题C++解法(附证明过程)
二分查找的巧妙运用(C++)
位运算在算法题中的使用(C++)
链表相关练习题(C++)
用实例讲解栈和队列(C++)
一些智力题的C++解法

一、求字符串的最长无重复字符子串的长度。
解法:动态规划。优化方案为:在查找与当前字符相同的字符位置时,可以用一个循环遍历之前的子串,也可以用hash表直接查找,更省时间。
class   Solution {
public :
     int  lengthOfLongestSubstring(string s) {
         int   len = s.size(),start =  0 ;
         if  (s.empty()||len ==  0 )
             return  0 ;
         int  dp[len+ 1 ] = { 0 };
         vector< int > hash( 256 , -1 );
      for  ( int  i =  0 ;i < len;i++) {
             if  (hash[s[i]] >= start)
                start = hash[s[i]]+ 1 ;
            hash[s[i]] = i;
            dp[i+ 1 ] = max(i-start+ 1 ,dp[i]);
        }
         return  dp[len];
    }
};

二、字符串转整数
解法:第一个非空格字符之前的空格忽略;第一个非空格字符是+或-则做相应标记;从第一个非空格字符开始遍历字符串,遇到数字则按规律叠加起来,遇到非数字字符则停止遍历。
class  Solution { 
public
    int  myAtoi(string str) { 
        int  positive =  1 ,i = str.find_first_not_of(' '); 
        long  sum =  0
        if  (str[i] == '+' || str[i] == '-') 
            positive = str[i++] == '-'?- 1 :positive; 
        while  (isdigit(str[i])) { 
            sum = (sum<<1) + (sum<< 3 ) + str[i++]-' 0 '; 
            if  (sum > INT_MAX) 
                return  positive ==  1 ?INT_MAX:INT_MIN; 
        }
        return  positive*sum; 
    }
};

三、判断一个整数是不是回文序列
解法:
class  Solution {
public
:
     bool  isPalindrome( int  x) {
         if  (x> 0  && x% 10  ==  0 )
             return false ;
         int  sum =  0 ;
         while  (sum < x) {
            sum = (sum<< 1 )+(sum<< 3 )+x% 10 ;
            x /=  10 ;
        }
         if  (sum == x||sum/ 10  == x)
             return true ;
         else
             return false ;
    }
};

四、求两个已排序数组的中位数
解法:二分查找。
①中位数将所有数据分成个数相等的两个部分,且其中一部分全部大于另一部分;
②同时在两个有序数组中查找合适的划分点,由于要保证划分出的两部分数据个数相等,所以只在其中一个数组的下标中进行二分搜索划分点i,从而确定出另外一个数组中的划分点j;
③为了确保由i推导出的j>=0,需选择长度较小的数组进行二分搜索,这样能确保j合法;
④两个划分点左侧的数据为较小的一半,右侧为较大的一半,所以判断搜索出的划分点是否合法的条件为:较小一半的最大值小于较大一半的最小值。否则更新二分搜索的范围。
class  Solution {
public
:
     double  findMedianSortedArrays(vector< int >& nums1, vector< int >& nums2) {
         int  len1 = nums1.size(),len2 = nums2.size(),half_len = (len1+len2+ 1 )/ 2 ;
         if  (len1 > len2) 
             return  findMedianSortedArrays(nums2,nums1);
         int  start =  0 ,end = len1,i,j,numleft,numright;
         while (start <= end) {
            i = (start+end)/ 2 ;
            j = half_len-i;
             if  (i>0&&j nums2[j]) 
                end = i-1;
             else if  (j>0&&i nums1[i])
                start = i+1;
             else  {
                 if  (i ==  0 ) {
                    numleft = nums2[j- 1 ];
                }
                 else if  (j ==  0 ) {
                    numleft = nums1[i- 1 ];
                }
                 else  {
                    numleft = max(nums1[i- 1 ],nums2[j- 1 ]);
                }
                 break ;
            }
        }
         if  (j == len2 && len1 !=  0 ) numright = nums1[i];
         else if  (i == len1 && len2 !=  0 ) numright = nums2[j];
         else  numright = min(nums1[i],nums2[j]);
         return  (len1+len2)% 2  ==  1 ?(double)numleft:(numleft+numright)/ 2.0 ;
    }
};

五、求字符串的最长回文子串
解法:遍历字符串,以每个字符为中间点向两边扩展比较,记录下最长的回文子串长度和起始位置即可。遇到连续相同的字符要跳过,他们一定包含在同一个回文中。
class  Solution {
public
:
    string longestPalindrome(string s) {
         int  len = s.size();
         if  (len <  2 )
             return  s;
         int  mid =  0 ,maxLen =  1 ,start =  0 ;
         while  (mid < len) {
             if  (len-mid <= maxLen/ 2 )
                break;
             int  left = mid,right = mid;
             while  (right < len- 1  && s[right+1] == s[right])
                ++right;
            mid = right+1;
             while  (left >  0  && right < len- 1  && s[left- 1 ] == s[right+ 1 ]) {
                --left;
                ++right;
            }
             if  (right-left+ 1  > maxLen) {
                maxLen = right-left+ 1 ;
                start = left;
            }
        }
         return  s.substr(start,maxLen);
    }
};

六、删除链表中某个结点
解法一:循环到链表尾,依次将结点值向前复制一步。
class  Solution {
public
:
     void  deleteNode(ListNode* node) {
         while  (node->next->next) {
            node->val = node->next->val;
            node = node->next;
        }
        node->val = node->next->val;
         delete  node->next;
        node->next =  NULL ;
    }
};
解法二:直接将下一个结点的内容全部复制到当前结点,再删除下一个结点。
class  Solution {
public
:
     void  deleteNode(ListNode* node) {
        ListNode* next = node->next;
        *node = *next;
         delete  next;
    }
};

七、求小于正整数n的素数个数




class  Solution {
public
:
     int  countPrimes( int  n) {
        vector< int > hmap(n, 1 );
         if  (n <  3 )
             return  0 ;
         int  upper = sqrt(n);
         for  ( int  i =  2 ;i <= upper;++i) {
             if  (hmap[i] ==  0 )
                 continue ;             
        for  ( int  non_prime = i*i;non_prime < n;) {
                hmap[non_prime] =  0 ;
                non_prime += i;
            }
        }
         int  count =  0 ;
         for  (int k =  2 ;k < n;++k)
             if  (hmap[k] ==  1 )
                ++count;
         return  count;
    }
};

八、找到二叉树中所有路径

注意:题中的""不需要输出,""只代表字符串。

解法:递归。
class  Solution {
public
:
     void  binaryTreePaths(vector& result, TreeNode* root, string t) {
         if  (!root->left && !root->right) {
            result.push_back(t);
             return ;
        }

         if  (root->left) 
            binaryTreePaths(result, root->left, t + "->" + to_string(root->left->val));
         if  (root->right) 
            binaryTreePaths(result, root->right, t + "->" + to_string(root->right->val));
    }

    vector binaryTreePaths(TreeNode* root) {
        vector result;
         if  (!root)  return  result;

        binaryTreePaths(result, root, to_string(root->val));
         return  result;
    }
};

你可能感兴趣的:(数据结构与基本算法)