首页 > 试题广场 >

最长公共前缀

[编程题]最长公共前缀
  • 热度指数:142785 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给你一个大小为 n 的字符串数组 strs ,其中包含n个字符串 , 编写一个函数来查找字符串数组中的最长公共前缀,返回这个公共前缀。

数据范围:
进阶:空间复杂度 O(1),时间复杂度 O(n*len)
示例1

输入

["abca","abc","abca","abc","abcc"]

输出

"abc"
示例2

输入

["abc"]

输出

"abc"
import java.util.*;


public class Solution {
    /**
     * 
     * @param strs string字符串一维数组 
     * @return string字符串
     */
    public String longestCommonPrefix (String[] strs) {
        // write code here
        if(strs.length==0)
            return "";
        if(strs.length==1)
            return strs[0];
        int length=strs[0].length();
        for(int i=1;i<strs.length;i++){
            if(strs[i].length()<length)
            {
                length=strs[i].length();
            }
        }
        String result="";
        outer:
        for(int i=0;i<length;i++){
            
            for(int j=1;j<strs.length;j++){
                if(strs[j].charAt(i)!=strs[0].charAt(i))
                    break outer;
            }
            result+=strs[0].charAt(i);
            
        }
        return result;
            
       
    }
}
发表于 2021-08-04 20:40:55 回复(0)
function longestCommonPrefix( strs ) {
    // write code here
    if (strs.length < 1) return '';
    if (strs.length === 1) return strs[0];
    strs.sort();
    const first = strs[0], end = strs[strs.length - 1];
    let res = '';
    for (let i = 0; i < first.length; i++) {
        if (first[i] !== end[i]) break;
        res += first[i];
    }
    return res;
}

发表于 2021-04-15 12:31:12 回复(0)
    public String longestCommonPrefix (String[] strs) {
        int n=strs.length;
        if(n==0) return ""; 
        String pre=strs[0];
        for(int i=1;i<n;i++){
            while(!pre.equals("")&&!strs[i].startsWith(pre)){
                pre=pre.substring(0,pre.length()-1);//只要不匹配,就减小pre
            }
            if(pre.equals("")) break;
        }
        return pre;
    }

发表于 2021-03-26 15:44:14 回复(0)
解题思路:二分法
import java.util.*;


public class Solution {
    /**
     * 
     * @param strs string字符串一维数组 
     * @return string字符串
     */
    public String longestCommonPrefix (String[] strs) {
        // write code here
        if (strs == null || strs.length == 0)
            return "";
        int begin = 1;
        int end = strs[0].length();
        int maxcomidx = -1;
        while(begin <= end) {
            int mid = (begin + end) >> 1;
            if(isCommonPrefix(strs, mid)) {
                begin = mid + 1;
                maxcomidx = mid;
            }else {
                end = mid - 1;
            }
        }
        if(maxcomidx == -1) {
            return "";
        }else {
            return strs[0].substring(0, maxcomidx);
        }
    }
    public static boolean isCommonPrefix(String[] strs, int idx) {
        String prefix = strs[0].substring(0, idx);
        for(int i = 1; i < strs.length; i++) {
            if(!strs[i].startsWith(prefix)) {
                return false;
            }
        }
        return true;
    }
}


发表于 2021-03-17 21:20:32 回复(0)
class Solution {
private:
    string findCommonPrefix(const string& a,const string& b)
    {
        string res;
        int i = 0;
        int size = min(a.size(),b.size());
        while(i < size && a[i] == b[i])
            res += a[i++];
        return res;
    }
public:
    string longestCommonPrefix(vector<string> &strs) {
        if(strs.size() == 0)
            return string();
        string res = strs[0];
        for(int i = 1; i < strs.size() && res.size(); ++i)
            res = findCommonPrefix(res,strs[i]);
        return res;
    }
};

发表于 2019-12-19 15:25:48 回复(1)
先排序,然后两个两个找就行了(看了评论区,可以优化一下,就是最小的和最大的字符串先求,这个就不写了)
public class Solution {
    public String longestCommonPrefix(String[] strs) {
        if (strs==null||strs.length==0)
            return "";
        Arrays.sort(strs);
        for (int i=1;i<strs.length;i++){
            String s1 = strs[i];
            String s2 = strs[i-1];
            if (getPrfix(s1,s2)!=null){
                strs[i]=getPrfix(s1,s2);
            }else 
                return "";
        }
        return strs[strs.length-1];
    }
    
    private String getPrfix(String s1,String s2){
        StringBuilder sb = new StringBuilder();
        if (s1==null||s2==null)
            return null;
        int i=0;
        while (i<s1.length()&&i<s2.length()){
            if (s1.charAt(i)==s2.charAt(i)){
                sb.append(s1.charAt(i));
                i++;
            }else 
                break;
        }
        return sb.toString();
    }
}

编辑于 2018-04-27 20:29:41 回复(0)
//字典树
public class Solution {
    class Node{
        int num  = 0 ; 
        Node[] next = new Node[26] ; 
        public void add(){
            num++ ; 
        }
    }
    int result = Integer.MAX_VALUE ; 
    public String longestCommonPrefix(String[] strs) {
        if(strs.length == 0){
            return "" ; 
        }
        Node root = new Node() ; 
        int pos = 0 ; 
        result = strs[0].length() ; 
        for(String s:strs){
            result = Math.min(s.length(),result) ; 
            add(root,0,s,pos) ; 
            pos++ ; 
        }
        return strs[0].substring(0,result) ; 
    }
    
    public void add(Node root, int pos , String s,int needNum){
        if(pos == s.length()){
            return ; 
        }
        char c = s.charAt(pos) ; 
        int nn = (int)(c-'a') ; 
        if(root.next[nn] == null){
            root.next[nn] = new Node() ; 
        }
        if(root.next[nn].num != needNum){
            result = Math.min(result,pos) ; 
        }
        root.next[nn].num++ ; 
        add(root.next[nn],pos+1,s,needNum) ; 
    }
    
    
}

发表于 2018-01-08 19:57:15 回复(0)
string longestCommonPrefix(vector<string> &strs) {
        int n=strs.size();
        if(n==0)
            return "";
        string prefix=strs[0];
        for(int i=1;i<n;i++){
            if(prefix.length()==0||strs[i].length()==0)
                return "";
            int len=std::min(prefix.length(),strs[i].length());
            int j;
            for(j=0;j<len;j++){
                if(prefix[j]!=strs[i][j])
                    break;
            }
            prefix=strs[i].substr(0,j);
        }
        return prefix;
    }


发表于 2017-11-06 11:16:00 回复(0)
class Solution {
public:
    string longestCommonPrefix(vector<string> &strs) {
        if(strs.empty())return "";
        sort(strs.begin(),strs.end());
        int i=0,len=min(strs[0].size(),strs.back().size());
        for(;i<len;++i)
            if(strs[0][i]!=strs.back()[i])break;
        return strs[0].substr(0,i);
    }
};

发表于 2017-09-11 22:10:11 回复(0)
// 这个办法需要排序vector
class Solution {
public:
    string longestCommonPrefix(vector<string> &strs)
    {
        if(strs.size()== 0)
            return "";
        sort(strs.begin(),strs.end());
        string small = strs[0],large = strs.back();
        int index = 0,len = min(small.length(),large.length());
        for(;index<len;index++)
        {
            if(small[index] != large[index])
                break;
        }
        return large.substr(0,index);  // 注释,此处index多移动了一步
    }
};

发表于 2017-07-11 17:07:40 回复(0)
// 只有好愚蠢的O(n^2)的算法.....
public class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs == null || strs.length <= 0)
        	return "";
        
        String prefix = "";
        boolean isPrefix = true;
        for(int i = 0; i < strs[0].length(); i++){
        	String tmp = strs[0].substring(0, i + 1);
        	for(int j = 1; j < strs.length; j++){
        		if(strs[j].indexOf(tmp) != 0){
        			isPrefix = false;
        		}
        	}
        	if(isPrefix){
        		prefix = tmp;
        	}
        	else {
				break;
			}
        }
        return prefix;
    }
}

发表于 2017-05-05 16:43:23 回复(0)
function longestCommonPrefix(strs) {

    strs = strs.sort()
    var str1 = strs[0]
    var str2 = strs[strs.length - 1]

    var index = 0
    var str = ""
    if (strs.length == 0) {
        return str 
    } else if (str2.startsWith(str1)) {
        return str1
    } 

    while (true) {
        if (str1[index] === str2[index]) {
            str += str1[index]
            index++         
        }else {
            break
        }
    }
    return str

}

发表于 2021-09-05 14:17:54 回复(0)
import java.util.*;
public class Solution {
    public static String longestCommonPrefix(String[] strs) {
		if(strs == null || strs.length == 0) return "";
		Arrays.sort(strs, new Comparator<String>() {
			@Override
			public int compare(String o1, String o2) {
				return o1.length() - o2.length();
			}
		});
		for (int i = 1; i < strs.length; i ++ ) {
			if(strs[i].startsWith(strs[0])) continue;
			else {
				for (int j = 0; j < strs[0].length(); j ++ ) {
					if(strs[0].charAt(j) != strs[i].charAt(j)) {
						strs[0] = strs[0].substring(0, j);
						break;
					}
				}
			}
		}
		return strs[0];
	}
}

发表于 2016-11-06 00:16:02 回复(0)

一共有5种方法:

1.水平扫描法

2.垂直扫描法

3.分治算法

4.二分算法

5.前缀树/字典树(Prefix Tree)

/**
 * 
 * @author ChopinXBP
 * Write a function to find the longest common prefix string amongst an array of strings.
 * If there is no common prefix, return an empty string "".
 * Note: All given inputs are in lowercase letters a-z.
 * 编写一个函数来查找字符串数组中的最长公共前缀。
 * 如果不存在公共前缀,返回空字符串 ""。
 * 说明: 所有输入只包含小写字母 a-z 。
 *
 */

public class LongestCommonPrefix {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String[] strs = {"flower","flow","flight"};
        String[] strs2 = {"aa","aa"};
        String[] strs3 = {"a"};
        System.out.println(longestCommonPrefix(strs));
        System.out.println(longestCommonPrefix2(strs));
        System.out.println(longestCommonPrefix3(strs));
        System.out.println(longestCommonPrefix4(strs));
        System.out.println(longestCommonPrefix4(strs2));
        System.out.println(longestCommonPrefix4(strs3));
    }

    //水平扫描法:在线处理,不断调整公共前缀的长度
    public static String longestCommonPrefix(String[] strs) {
        if (strs == null || strs.length == 0)
            return "";

        int maxcomidx = strs[0].length() - 1;
        for(int i = 1; i < strs.length; i++) {
            int idx = -1;
            while(idx < maxcomidx && idx < strs[i].length() - 1) {
                if(strs[0].charAt(idx + 1) == strs[i].charAt(idx + 1)) {
                    idx++;
                }else {
                    break;
                }
            }

            if(idx == -1) return "";
            maxcomidx = idx;
        }

        return strs[0].substring(0, maxcomidx + 1);
    }

    //垂直扫描法:按列扫描,先验证所有字符串的第一个元素
    public static String longestCommonPrefix2(String[] strs) {
        if (strs == null || strs.length == 0)
            return "";
        for (int i = 0; i < strs[0].length(); i++) {
            char c = strs[0].charAt(i);
            for (int j = 1; j < strs.length; j++) {
                if (i == strs[j].length() || strs[j].charAt(i) != c)
                    return strs[0].substring(0, i);
            }
        }
        return strs[0];
    }

    //分治算法,在水平扫描法的基础上改进
    public static String longestCommonPrefix3(String[] strs) {
        if (strs == null || strs.length == 0)
            return "";

        return Solution(strs, 0, strs.length - 1);
    }

    public static String Solution(String[] strs, int begin, int end) {
        if(begin == end) {
            return strs[begin];
        }
        else {
            int mid = (begin + end) >> 1;
            String str1 = Solution(strs, begin, mid);
            String str2 = Solution(strs, mid + 1, end);
            if(str1 == "" || str2 == "") return "";

            int idx = -1;
            while(idx < str1.length() - 1 && idx < str2.length() - 1) {
                if(str1.charAt(idx + 1) == str2.charAt(idx + 1)) {
                    idx++;
                }else {
                    break;
                }
            }
            if(idx == -1) return "";
            return strs[begin].substring(0, idx + 1);
        }
    }

    //二分查找算法
    public static String longestCommonPrefix4(String[] strs) {
        if (strs == null || strs.length == 0)
            return "";

        int begin = 1;
        int end = strs[0].length();
        int maxcomidx = -1;

        while(begin <= end) {
            int mid = (begin + end) >> 1;
            if(isCommonPrefix(strs, mid)) {
                begin = mid + 1;
                maxcomidx = mid;
            }else {
                end = mid - 1;
            }
        }

        if(maxcomidx == -1) {
            return "";
        }else {
            return strs[0].substring(0, maxcomidx);
        }
    }

    public static boolean isCommonPrefix(String[] strs, int idx) {
        String prefix = strs[0].substring(0, idx);
        for(int i = 1; i < strs.length; i++) {
            if(!strs[i].startsWith(prefix)) {
                return false;
            }
        }
        return true;
    }

    //拓展:给定一些键值字符串 S = [S1……Sn],我们要找到字符串 q与 S的最长公共前缀。
    //可以利用前缀树/字典树(Prefix Tree)
    //https://leetcode.com/articles/implement-trie-prefix-tree/
}
编辑于 2019-02-23 14:36:40 回复(4)
//先对字符串排序,然后考虑第一个和最后一个的首字符,这两个字符必定是差距最大的两个
//(因为排序首先从第一个开始排),如果这两个不等,就返回空,否则,说明所有字符串的首
//字符相等,那么接着判断第二个。
class Solution {
public:
    string longestCommonPrefix(vector<string> &strs) {
           if(!strs.size()) return "";
           sort(strs.begin(),strs.end());
           int i=0,sz=strs.size(),l=min(strs[0].size(),strs[sz-1].size());
           for(;i<l;i++)
               if(strs[0][i]!=strs[sz-1][i])
                  return strs[0].substr(0,i); 
           return strs[0].substr(0,l);
    }
};

发表于 2017-08-07 10:02:53 回复(5)
class Solution {
public:
    string longestCommonPrefix(vector<string> &strs) {
  		if(strs.empty())
  			return "";
  		sort(strs.begin(),strs.end());
  		
  		int n = strs.size();
  		int l = min(strs[0].size(),strs[n-1].size());
  		for(int i=0;i<l;i++)
  			if(strs[0][i] != strs[n-1][i])
  				return strs[0].substr(0,i);
  		return strs[0].substr(0,l);
    }
};

发表于 2017-08-10 01:19:47 回复(1)
**
 * 
 * @author Jacob
 *
 */
public class Demo1 {
	/*
	 * 对字符串数组进行排序,然后只要比较首尾两个字符串即可
	 */
	public String longestCommonPrefix(String[] strs) {
        StringBuilder result = new StringBuilder();
        
        if (strs!= null && strs.length > 0){
        
            Arrays.sort(strs);
            
            char [] a = strs[0].toCharArray();
            char [] b = strs[strs.length-1].toCharArray();
            
            for (int i = 0; i < a.length; i ++){
                if (b.length > i && b[i] == a[i]){
                    result.append(b[i]);
                }
                else {
                    return result.toString();
                }
            }
        return result.toString();
    }

	/*
	 * O(N^2)的解法
	 */
	public String longestCommonPrefix_1(String[] strs) {
		if (strs == null || strs.length == 0)
			return "";
		int len = strs.length;
		int min = strs[0].length();
		for (int i = 1; i < len; i++) {
			if (strs[i].length() < min)
				min = strs[i].length();
		}
		int res = -1;
		boolean flag = false;
		for (int i = 0; i < min; i++) {
			char tmp = strs[0].charAt(i);
			for (int j = 1; j < len; j++) {
				if (strs[j].charAt(i) != tmp) {
					flag = true;
					break;
				}
			}
			if (flag)
				break;
			res = i;
		}

		return strs[0].substring(0, res + 1);
	}
}

编辑于 2017-07-18 10:01:51 回复(4)
# @param strs string字符串一维数组 
# @return string字符串
class Solution:
    def longestCommonPrefix(self , strs ):
        # write code here
        n = len(strs)
        if n == 0:
            return ""
        
        strs.sort()
        m = min(len(strs[0]),len(strs[n-1]))
        for i in range(m):
            if strs[0][i] != strs[n-1][i]:
                return strs[0][0:i]
        return strs[0][0:m]


编辑于 2020-06-16 10:59:42 回复(1)
public String longestCommonPrefix (String[] strs) {
        if(strs.length==0) return "";
        String tmp=strs[0];
        for(int i=1;i<strs.length;i++){
            while(strs[i].indexOf(tmp)!=0){//如果返回的索引位置不是0
                tmp=tmp.substring(0,tmp.length()-1);

            }

        }
        return tmp;//一直在缩短tmp,直至缩短到公共前缀
    }

发表于 2023-05-02 23:00:47 回复(0)
class Solution:
    def longestCommonPrefix(self , strs: List[str]) -> str:
        if not strs:
            return ''
        else:
            min_len = min([len(i) for i in strs])
            result = ""
            for j in range(min_len): 
                compare_list = [strs[i][j] for i in range(len(strs))]
                if len(set(compare_list)) == 1:
                    result += strs[0][j]
        return  result

发表于 2022-07-18 23:45:53 回复(0)