字符串处理专题--Leetcode

本文详细探讨了多个LeetCode上的字符串处理问题,包括字母异位词分组、翻转字符串里的单词、比较版本号、独特电子邮件地址、最长回文子串、Z字形变换、无重复字符的最长子串以及实现Trie前缀树。每部分都提供了Java代码实现,是学习和提升字符串算法能力的好资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、49. 字母异位词分组

思路:定义一个map,key值为每个排好序的字符串,value为字符串本身,key的类型为String,value的类型为ArrayList<String>。所以以上例子的map为

map={

        "aet":{"ate","eat","tea"},

        "abt":{bat},

        "ant":{"nat","tan"}

}

 以下为java代码

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        Map<String,ArrayList<String>> map = new HashMap<String,ArrayList<String>>();
		for(String str:strs) {
			//遍历每一个字符串
			String[] temp = str.split("");
			Arrays.sort(temp);
			String orderStr = Arrays.toString(temp);
			if(map.containsKey(orderStr)) {
				// 如果已经包括了
				ArrayList<String> list = new ArrayList<>();
				list = map.get(orderStr);
				list.add(str);
				map.put(orderStr, list);
			} else {
				// 表示还没有包括
				ArrayList<String> list = new ArrayList<>();
				list.add(str);
				map.put(orderStr, list);
			}
		}
        // 遍历map
		List<List<String>> result = new ArrayList<>();
		for(Map.Entry<String, ArrayList<String>> entry:map.entrySet()) {
			result.add(entry.getValue());
		}
		return result;
    }
}

2、151. 翻转字符串里的单词

 该题虽然是中等题,但是很简单。

以下为java代码:

class Solution {
    public String reverseWords(String s) {        
		// 翻转之后的字符串前后不能有空格
		String after = s.trim();  // 所有首先去除前后空格
		String[] strs = after.split(" ");
		String result = "";
		for(int i=strs.length-1;i>=0;i--) {
            if(strs[i].equals("")) {
				continue;
			}
			result+=strs[i];
			if(i!=0) {
				result+=" ";
			}
		}
		return result;
    }
}

还有一种思想:就是先翻转每个单词,再翻转整个字符串

 3、165. 比较版本号

以下为Java代码:

class Solution {
    public int compareVersion(String version1, String version2) {
        String[] vers1 = version1.split("");
		String[] vers2 = version2.split("");
		// 首先需要看看版本号中有没有"."
		if (version1.indexOf(".") != -1) {
			vers1 = version1.split("\\.");
		} else {
			vers1 = new String[] {version1};
		}
		if (version2.indexOf(".") != -1) {
			vers2 = version2.split("\\.");
		} else {
			vers2 = new String[] {version2};
		}
		int index1 = 0;
		int index2 = 0;
		int flag = 0;
		while (index1 < vers1.length || index2 < vers2.length) {
			String temp1 = "";
			String temp2 = "";
			if (index1 >= vers1.length) {
				temp1 = "0";
			} else {
				temp1 = vers1[index1];
			}
			if (index2 >= vers2.length) {
				temp2 = "0";
			} else {
				temp2 = vers2[index2];
			}
			// 都需要去除前导0再转为数字进行比较
			int i = 0;
			int j = 0;
			while (i < temp1.length() && temp1.charAt(i) == '0')
				i++;
			while (j < temp2.length() && temp2.charAt(j) == '0')
				j++;
			if (i == temp1.length()) {
				// 说明这部分全部为0
				temp1 = "0";
			} else {
				temp1 = temp1.substring(i);
			}

			if (j == temp2.length()) {
				temp2 = "0";
			} else {
				temp2 = temp2.substring(j);
			}

			if (Integer.parseInt(temp1) > Integer.parseInt(temp2)) {
				flag = 1;
				break;
			}
			if (Integer.parseInt(temp1) < Integer.parseInt(temp2)) {
				flag = -1;
				break;
			}
			index1++;
			index2++;
		}
		return flag;
    }
}

 4、929. 独特的电子邮件地址

简单题,以下为Java代码:

class Solution {
    public int numUniqueEmails(String[] emails) {
        List<String> list = new ArrayList<>();
		// 遍历处理每个邮箱的本地名称部分
		for(int i=0;i<emails.length;i++) {
			String email = emails[i];
			int index = email.indexOf("@");
			String name = email.substring(0,index);
			String dns = email.substring(index+1);
			// 把所有的.用""取代
            if(name.indexOf(".")!=-1)
			    name = name.replaceAll("\\.", "");
			if(name.indexOf("+")!=-1) {
				// 表示里面有+
				int index1 = name.indexOf("+");
				name = name.substring(0,index1);
			}
			String fEmail = name+"@"+dns;
			if(!list.contains(fEmail)) {
				list.add(fEmail);
			}
		}
		return list.size();
    }
}

 5、5. 最长回文子串

 思想:利用中心法,每个字母设置为回文串的中心,向左右两边扩散开,看看左右两边对应的 字符是否相等。

以下为Java代码:

class Solution {
    public String longestPalindrome(String s) {
        String result="";
		//可以使用中心法则
		for(int i=0;i<s.length();i++) {
			int left = 0;
			int right = 0;
			//当回文串为奇数的时候 比如:abcba
			for (left=i,right=i;left>=0&&right<s.length()&&s.charAt(left)==s.charAt(right);left--,right++) {
				if(result.length()<right-left+1) {
					result=s.substring(left,right+1);
				}
			}
			//当回文串为偶数的是偶  比如:abccba
			for(left=i,right=i+1;left>=0&&right<s.length()&&s.charAt(left)==s.charAt(right);left--,right++) {
				if(result.length()<right-left+1) {
					result=s.substring(left,right+1);
				}
			}
		}
		return result;
    }
}

6、6. Z 字形变换

以下为Java实现代码:

class Solution {
    public String convert(String s, int numRows) {
        // 需要特别判断  否则会进入死循环
        if(numRows==1){
            return s;
        }
		String result = "";
		for (int i = 0; i < numRows; i++) {
			if (i == 0 || i == numRows - 1) {
				// 表示其下标是首相为i,公差是2(numRows-1)的等差数列
				for (int j = i; j < s.length(); j += 2 * (numRows - 1)) {
					result += s.charAt(j);
				}
			} else {
				// 中间的部分是两个等差数列交错的情况
				for (int j = i, k = 2 * (numRows - 1) - i; j < s.length()
						|| k < s.length(); j += 2 * (numRows - 1), k += 2 * (numRows - 1)) {
					if (j < s.length()) {
						result += s.charAt(j);
					}
					if (k < s.length()) {
						result += s.charAt(k);
					}
				}
			}
		}
		return result;
    }
}

 7、3. 无重复字符的最长子串

 思想:双指针+滑动窗口

以下为Java代码:

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int left = 0;
		int right = 0;
		String windows = " ";
		int maxLen = 0;
		// 使用滑动窗口的解法
		while (right < s.length()) {
			right++;
			windows = s.substring(left, right);			
			while (right < s.length() && left < right && windows.contains(s.charAt(right) + "")) {
				// 表示已经包含了
				if (maxLen < windows.length()) {
					maxLen = right - left;
				}
				left++;
				windows = s.substring(left, right);
			}	
		}
        if (maxLen < windows.length()) {
				maxLen = right - left;
		}
		return maxLen;
    }
}

8、208. 实现 Trie (前缀树)

 这道题:前缀树,直接看官方题解吧:实现 Trie (前缀树) - 实现 Trie (前缀树) - 力扣(LeetCode) (leetcode-cn.com)

本人有一种简单但是时间很慢的方法,不过也可以通过leetcode,就是解法脱离了前缀树的概念。以下为Java代码:

import java.util.*;
class Trie {

    List<String> list;
    /** Initialize your data structure here. */
    public Trie() {
    	list = new ArrayList<>();
    }
    
    /** Inserts a word into the trie. */
    public void insert(String word) {
    	list.add(word);
    }
    
    /** Returns if the word is in the trie. */
    public boolean search(String word) {
    	if(list.contains(word)) {
    		return true;
    	} else {
    		return false;
    	}
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    public boolean startsWith(String prefix) {
    	for(int i=0;i<list.size();i++) {
    		if(list.get(i).startsWith(prefix)) {
    			return true;
    		}
    	}
    	return false;
    }
}

/**
 * Your Trie object will be instantiated and called as such:
 * Trie obj = new Trie();
 * obj.insert(word);
 * boolean param_2 = obj.search(word);
 * boolean param_3 = obj.startsWith(prefix);
 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值