1.第一题:编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
每行中的整数从左到右按升序排列。
每行的第一个整数大于前一行的最后一个整数。
思路,二分查找(递归版)
class Solution {
public boolean binarySearch(int[][] matrix,int low,int high,int n,int target){
if(low<=high)
{
int mid=(low+high)/2;
int i=mid/n;
int j=mid%n;
if(matrix[i][j]==target){
return true;
}
else if(matrix[i][j]>target){
return binarySearch(matrix,low,mid-1,n,target);
}
else if(matrix[i][j]<target){
return binarySearch(matrix,mid+1,high,n,target);
}
}
return false;
}
public boolean searchMatrix(int[][] matrix, int target) {
int m=matrix.length;
int n=matrix[0].length;
boolean result=binarySearch(matrix,0,m*n-1,n,target);
return result;
}
}
不递归,用while循环版
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m=matrix.length;
int n=matrix[0].length;
boolean result=false;
int low=0;
int high=m*n-1;
while(low<=high){
int mid=(low+high)/2;
int i=mid/n;
int j=mid%n;
if(matrix[i][j]==target){
result=true;
break;
}
else if(matrix[i][j]>target){
high=mid-1;
}
else if(matrix[i][j]<target){
low=mid+1;
}
}
return result;
}
}
我感觉,这个测评效率着实不准。。。
2.第二题:最长回文子串
题目描述:
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
感觉我的方法非常的死板,没有用到算法技巧
class Solution {
public String longestPalindrome(String s) {
String result;
int start=-1;
int end=-1;
int maxlen=0;
int evenflag=0;
int oddflag=0;
if(s.length()>1){
for(int i=0;i<s.length()-1;i++){
char item=s.charAt(i);
char nextitem=s.charAt(i+1);
if(item==nextitem){
evenflag=1;
int m=i;
int n=i+1;
while(m>=0&&n<=s.length()-1&&s.charAt(m)==s.charAt(n)){
m=m-1;
n=n+1;
}
m++;
n--;
if(n-m+1>maxlen){
maxlen=n-m+1;
start=m;
end=n;
}
}
int p=i-1;
int q=i+1;
while(p>=0&&q<=s.length()-1&&s.charAt(p)==s.charAt(q)){
oddflag=1;
p=p-1;
q=q+1;
}
p=p+1;
q=q-1;
if(maxlen<(q-p+1)){
maxlen=q-p+1;
start=p;
end=q;
}
}
}
if(evenflag==0&&oddflag==0) { //表示连两个相同的都没有
result=s.substring(0,1);
}
else{
result=s.substring(start,end+1);
}
return result;
}
}
插播大佬的解法:
大佬的思路:将回文字符串看成是中心为n个相同的字符,两遍对称的情况。最关键的点在于,下次可以直接跳到中间重复的那串的下一个。中心思想:(1)将中间的多个字符看成一个整体,看成一个字符。
(2)并且下次搜索可以直接跳过重复字符。
经过验证发现,为什么可以跳过呢,是因为假设以:baacdeeedcfg为例,当到第二个字符时,检测出aa,如果此时明确知道第三个a与该字符串第四位一定不相同,故如果不跳过相同的字符,而是i从第三个字符a接着开始的话,明显得到的回文字符长度一定小于当前得到的回文字符长度。
class Solution {
public String longestPalindrome(String s) {
/*大佬的思路:将回文字符看成是中间有n(>=1)个相同字符,两边对称相同!
*/
int []record=new int[]{0,0};
char[] str=s.toCharArray();
for(int i=0;i<s.length();i++){
i=findLongest(str,i,record);
}
return s.substring(record[0],record[1]+1);
}
public int findLongest(char[] str,int low,int[] record){
int high=low;
while(high<str.length-1&&str[low]==str[high+1]){
high++;
}
int ans=high;
while(low>=1&&high<str.length-1&&str[high+1]==str[low-1]){
high++;
low--;
}
if(high-low>(record[1]-record[0])){
record[0]=low;
record[1]=high;
}
return ans;
}
}