栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

leetcode-14. 最长公共前缀

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

leetcode-14. 最长公共前缀

 JAVA:

package com.leetcode;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


public class Hot014_LongestCommonPrefix {

	// -----------------------------------Solution1:横向扫描----------------------------------

	
	
	public String longestCommonPrefix(String[] strs) {
		// CHECK parameter
		if (strs == null || strs.length == 0)
			return "";

		// ToLowerCase 因为题意仅由小写英文字母组成 , 可省略
		List list = Arrays.stream(strs).map(String::toLowerCase).collect(Collectors.toList());
		strs = list.toArray(new String[list.size()]);
		// System.out.println(Arrays.toString(strs));

		// 设第一个字符串是最大公共前缀
		String prefix = strs[0];
		for (int i = 1; i < strs.length; i++) {
			// 公共前缀
			prefix = longestCommonPrefix(prefix, strs[i]);
			if (prefix.length() == 0) {
				break;
			}
		}
		return prefix;

	}

	
	private String longestCommonPrefix(String str1, String str2) {
		int length = Math.min(str1.length(), str2.length());
		int index = 0;
		while (index < length && str1.charAt(index) == str2.charAt(index)) {
			index++;
		}
		return str1.substring(0, index);
	}

	// -----------------------------------Solution2:纵向扫描----------------------------------
	

	public 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++) {
				// i是最后一个字符时 或者 遍历到的字符串的 i位置的字符 不是 第一个串的 (不一样时 ) 退出内循环
				if (i == strs[j].length() || strs[j].charAt(i) != c) {
					return strs[0].substring(0, i);
				}
			}
		}
		return strs[0];
	}

	// -----------------------------------Solution3:分治----------------------------------
	

	public String longestCommonPrefix3(String[] strs) {
		if (strs == null || strs.length == 0)
			return "";
		return longestCommonPrefix3(strs, 0, strs.length - 1);
	}

	private String longestCommonPrefix3(String[] strs, int start, int end) {
		// BASE CASE
		if (start == end)
			return strs[start];

		// CASE 1: 二分
		int mid = (end - start) / 2 + start;
		String lcpLeft = longestCommonPrefix3(strs, start, mid);
		String lcpRight = longestCommonPrefix3(strs, mid + 1, end);

		return commonPrefix(lcpLeft, lcpRight);
	}

	
	private String commonPrefix(String str1, String str2) {
		// 获取两比较字符串的 最小 长度
		int minLength = Math.min(str1.length(), str2.length());

		for (int i = 0; i < minLength; ++i) {
			if (str1.charAt(i) != str2.charAt(i))
				return str1.substring(0, i);
		}
		return str1.substring(0, minLength);
	}

	// -----------------------------------Solution4:二分查找----------------------------------
	

	public String longestCommonPrefix4(String[] strs) {
		if (strs == null || strs.length == 0)
			return "";

		// 得到strs中 最短的 str的长度
		int minLength = Integer.MAX_VALUE;
		for (String str : strs)
			minLength = Math.min(minLength, str.length());

		// 二分
		int low = 0, high = minLength;
		while (low < high) {
			int mid = (high - low + 1) / 2 + low;
			if (isCommonPrefix(strs, mid)) {
				low = mid;
			} else {
				high = mid - 1;
			}
		}
		return strs[0].substring(0, low);
	}

	
	private boolean isCommonPrefix(String[] strs, int length) {
		// 获取前缀
		String str0 = strs[0].substring(0, length);

		// 遍历所有的 字符
		for (int i = 1; i < strs.length; i++) {
			String str = strs[i];
			// 判断 前缀 是否符合 当前 字符
			for (int j = 0; j < length; j++) {
				if (str0.charAt(j) != str.charAt(j)) {
					return false;
				}
			}
		}
		return true;
	}

	// ----------------------------------- main ----------------------------------

	public static void main(String[] args) {
		String[] strs = { "flower", "flow", "flight" };
		System.out.println("-");
		System.out.println(new Hot014_LongestCommonPrefix().longestCommonPrefix(strs));
		System.out.println("-");
		System.out.println(new Hot014_LongestCommonPrefix().longestCommonPrefix2(strs));
		System.out.println("-");
		System.out.println(new Hot014_LongestCommonPrefix().longestCommonPrefix3(strs));
		System.out.println("-");
		System.out.println(new Hot014_LongestCommonPrefix().longestCommonPrefix4(strs));
		System.out.println("-");

	}

}

Python3:

# -*- coding = utf-8 -*-
# @Time : 2022/05/11 19:05
# @Author : butupi
# @File : h14_LongestCommonPrefix.py
# @Software : PyCharm
from typing import List


class Solution:
    # 方法一:横向扫描
    def longestCommonPrefix(self, strs: List[str]) -> str:
        # CHECK parameter
        if not strs:
            return ""

        prefix, count = strs[0], len(strs)
        for i in range(1, count):
            prefix = self.lcp(prefix, str[i])
            # 前缀为空时,跳出循环
            if not prefix:
                break
        return prefix

    def lcp(self, str1, str2):
        length, index = min(len(str1), len(str2)), 0
        while index < length and str1[index] == str2[index]:
            index += 1
        return str1[:index]

    # 方法二:纵向扫描
    def longest_common_prefix(self, strs: List[str]) -> str:
        if strs is None:
            return ""
        length, count = len(strs[0]), len(strs)
        for i in range(length):
            c = str[0][i]
            if any(i == len(strs[j]) or strs[j][i] != c for j in range(1, count)):
                return strs[0][:i]
        return strs[0]

    # 方法三:分治
    def longest_common_prefix2(self, strs: List[str]) -> str:
        def lcp(start, end):
            if start == end:
                return strs[start]
            # 分治
            mid = (start + end) // 2
            lcpLeft, lcpRight = lcp(start, mid), lcp(mid + 1, end)
            # 取最长前缀
            minLength = min(len(lcpLeft), len(lcpRight))
            for i in range(minLength):
                if lcpLeft[i] != lcpRight[i]:
                    return lcpLeft[:i]
            return lcpLeft[:minLength]

        return "" if not strs else lcp(0, len(strs) - 1)

    # 方法四:二分
    def longest_common_prefix3(self, strs: List[str]) -> str:
        # 是否是公共前缀
        def is_common_prefix(length):
            str0, count = strs[0][:length], len(strs)
            return all(str[i][:length] == str0 for i in range(1, count))

        if not strs:
            return ""

        min_length = min(len(s) for s in strs)
        low, high = 0, min_length
        while low < high:
            mid = (high - low + 1) // 2 + low
            if is_common_prefix(mid):
                low = mid
            else:
                high = mid - 1
        return strs[0][:low]


if __name__ == "__main__":
    strs = ["hello", "helli", "hell"]
    print(Solution().longest_common_prefix2(strs))

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/878210.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号