4、Median of Two Sorted Arrays(*)
题目
题目要求找到两个排序数组的中位数。
中位数的定义:当n为奇数时,median = array[n/2];当n为偶数时,median = (array[n/2]+array[n/2+1])/2.
暴力算法,两个数组归并排序,对合并的数组求中位数。代码如下:
1 class Solution { 2 public: 3 double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { 4 vector<int> res; 5 6 int i=0,j=0; 7 int length1 = nums1.size(); 8 int length2 = nums2.size(); 9 10 while (i<length1 && j<length2) 11 { 12 if (nums1[i] < nums2[j]) 13 { 14 res.push_back(nums1[i]); 15 i++; 16 } 17 else 18 { 19 20 res.push_back(nums2[j]); 21 j++; 22 } 23 } 24 while (i<length1) 25 { 26 res.push_back(nums1[i]); 27 i++; 28 } 29 while (j<length2) 30 { 31 res.push_back(nums1[j]); 32 j++; 33 } 34 35 if((length2 + length1) % 2 == 1) 36 return res[(length2 + length1)/2]; 37 else 38 { 39 return (res[(length2 + length1)/2] + res[(length2 + length1)/2 + 1])/2; 40 } 41 42 } 43 };
但是,题目要求时间复杂度为O(log(m+n)),因此上面的算法是不符合要求的,因为其时间复杂度为O(m+n)。
如果时间复杂度为O(log(m+n)),肯定会用到二分查找算法。问题是现在有两个数组,怎样灵活的使用二分查找呢?这就需要开动脑筋了
5、Longest Palindromic Substring(*)
题目要求寻找字符串中最长的回文子串。
国际惯例,第一想法:暴力求解,固定一个自创s[i,j]判断其是否为回文串,代码如下:
1 class Solution { 2 public: 3 string longestPalindrome(string s) { 4 if("" == s) 5 return s; 6 7 int i,j; 8 int length = s.size(); 9 string sub; 10 int max 11 string res = ""; 12 for(i=0;i<length;i++) 13 { 14 for (j=i;j<length;j++) 15 { 16 sub = s.substr(i,j-i+1); 17 if(isPalindromic(sub)) 18 { 19 if(sub.length() > max) 20 res = sub; 21 } 22 23 } 24 } 25 return res; 26 } 27 bool isPalindromic(string sub) 28 { 29 int length = sub.size(); 30 int i,j=length-1; 31 while(i<j) 32 { 33 if(sub[i] != sub[j]) 34 return false; 35 i++; 36 j--; 37 } 38 return true; 39 } 40 };
该算法时间复杂度是O(n*n),当n比较大的时候,算法的性能比较低,不能很快的解决问题。导致算法性能低下的原因是产生了回溯。如果能避免回溯,算法性能则能显著提高。
看到这道题目的时候,我们会联想到一道经典的算法题目“最长公共子串”,即求两个字符串最长公共子串(LCS),解决LCS的算法是利用动态规划,重点是求出一个二维数组,其实现代码参考如下:
1 string LCS(string s1,string s2) 2 { 3 4 int len1 = s1.length(); 5 int len2 = s2.length(); 6 7 char*c=malloc(len2),*p; 8 9 int start,end,len,i,j; 10 end=len=0; 11 12 for(i=0; i<len1; i++) //串1从前向后比较 13 { 14 //串2从后向前比较,为什么要从后向前呢?是把一维数组c[ ]当二维数组来用, 15 16 // for(j=0;j<lenRight;j++)//当c申明为一个二维数组时 17 for(j=len2-1; j>=0; j--) 18 { 19 if(s1[i] == s2[j])//元素相等时 20 { 21 if(i==0||j==0) 22 c[j]=1;//c[i][j]=1; 23 else 24 { 25 c[j]=c[j-1]+1;//c[i][j]=c[i-1][j-1]+1; 26 } 27 } 28 else 29 c[j] = 0; //c[i][j]=0; 30 if(c[j] > len) //if (c[i][j]>len) 31 { 32 len=c[j]; //len=c[i][j]; 33 end=j; 34 } 35 } 36 } 37 start=end-len+1; 38 39 //数组p纪录最长公共子串 40 p =(char*)malloc(len+1); 41 for(i=start; i<=end; i++) 42 { 43 p[i-start] = right[i]; 44 } 45 p[len]='