思路:定义一个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;
}
}
该题虽然是中等题,但是很简单。
以下为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;
}
}
还有一种思想:就是先翻转每个单词,再翻转整个字符串
以下为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;
}
}
简单题,以下为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();
}
}
思想:利用中心法,每个字母设置为回文串的中心,向左右两边扩散开,看看左右两边对应的 字符是否相等。
以下为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;
}
}
以下为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;
}
}
思想:双指针+滑动窗口
以下为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;
}
}
这道题:前缀树,直接看官方题解吧:实现 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);
*/