题目1——字符串变形
对于一个长度为n的字符串,我们要做的是把这个字符串中由空格隔开的单词反序,同时反转每个字符的大小写。
要求:空间复杂度 O(n) , 时间复杂度 O(n)。
示例
输入:“This is a sample”,16
输出:“SAMPLE A IS tHIS”
解题思路
一种思路是利用栈的先入后出的特性,以空格为分隔符,读取单词的时候同时进行大小写转换,然后将单词加入到栈中;在全部单词读取完毕后,逐个弹出单词,就是答案。
两次逆转,首先遍历字符串,并转换大小写,接着对遍历后的字符串进行反转,此时单词逆序了,但是每个单词中的字符也是逆序的,所以需要再次遍历字符串,将每个单词进行反转。
代码实现—利用栈
import java.util.*;
public class Solution {
public String trans(String s, int n) {
if(n==0)
return s;
StringBuffer res;
StringBuffer tmp=new StringBuffer();
//声明一个栈
Stack<String> st = new Stack<String>();
for(int i=0;i<n;i++){
if(s.charAt(i)>='A' && s.charAt(i)<='Z')
tmp.append((char)(s.charAt(i) - 'A'+'a'));
else if(s.charAt(i)>='a' && s.charAt(i)<='z')
tmp.append((char)(s.charAt(i)-'a'+'A'));
else
tmp.append(s.charAt(i));
}
for(int i=0;i<n;i++){
int j=i;
while(j<n && tmp.charAt(j)!=' ')
j++;
st.push((String)tmp.substring(i,j));
i = j;
}
if(s.charAt(n-1) == ' ')
res = new StringBuffer(" ");
else
res = new StringBuffer();
while(!st.empty()){
res.append(st.pop());
if(!st.empty())
res.append(" ");
}
return res.toString();
}
}
代码实现—两次逆转
import java.util.*;
public class Solution {
public String trans(String s, int n) {
if(n==0)
return s;
StringBuffer res = new StringBuffer();
for(int i=0;i<n;i++){
if(s.charAt(i)<='Z' && s.charAt(i) >= 'A')
res.append((char)(s.charAt(i)-'A'+'a'));
else if(s.charAt(i)<='z' && s.charAt(i) >= 'a')
res.append((char)(s.charAt(i)-'a'+'A'));
else
res.append((char)(s.charAt(i)));
}
res = res.reverse();
for(int i=0;i<n;i++){
int j=i;
while(j<n && res.charAt(j)!=' ')
j++;
String temp = res.substring(i,j);
StringBuffer buffer = new StringBuffer(temp);
res.replace(i,j,buffer.reverse().toString());
i = j;
}
return res.toString();
}
}
题目2——最长公共前缀
给你一个大小为n的字符串数组strs,其中包含n个字符串,编写一个函数来查找字符串数组中的最长公共前缀,返回这个公共前缀。
要求:空间复杂度 O(n) , 时间复杂度 O(n)。
示例
输入:[“abca”,“abc”,“abca”,“abc”,“abcc”]
输出:“abc”
代码实现
将字符串数组看作一个二维空间,逐层扫描每一列,一直到遇到不同的字符为止。
import java.util.*;
public class Solution {
public String longestCommonPrefix (String[] strs) {
if(strs.length==0 || strs==null)
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(strs[j].length()==i || strs[j].charAt(i)!=c)
return strs[0].substring(0,i);
}
}
return strs[0];
}
}
题目3——验证IP地址
编写一个函数来验证输入的字符串是否是有效的IPv4或IPv6地址。IPv4 地址由十进制数和点来表示,每个地址包含4个十进制数,其范围为 0 - 255,例如 172.16.254.1。IPv6 地址由8组16进制的数字来表示,例如 2001:0db8:85a3:0000:0000:8a2e:0370:7334。
要求:空间复杂度 O(n) , 时间复杂度 O(n)。
示例
输入:“172.16.254.1”
输出:“IPv4”
输入:“2001:0db8:85a3:0:0:8A2E:0370:7334”
输出:“IPv6”
代码实现
可以对字符串进行分割,然后依次验证是否为合法的IP地址。
IP地址是有规律的,可以用正则表达式来表示。
#对字符串进行分割
class Solution:
def solve(self , IP: str) -> str:
if IP.count(".")>0:
nums = IP.split(".")
for num in nums:
for c in num:
if c<'0' or c>'9':
return "Neither"
if int(num)<0 or int(num)>255 or num[0] == '0':
return "Neither"
return "IPv4"
else:
if IP.count("::")>0:
return "Neither"
nums = IP.split(":")
if len(nums) != 8:
return "Neither"
for num in nums:
if len(num)==0 or len(num)>4:
return "Neither"
for c in num:
if (c>='0' and c<='9') or c in ['a','A','b','B','c','C','d','D','e','E','f','F']:
continue
else:
return "Neither"
return "IPv6"
import java.util.regex.Pattern;
public class Solution {
/**
* 验证IP地址
* @param IP string字符串 一个IP地址字符串
* @return string字符串
*/
public String solve (String IP) {
//正则表达式限制255,四组
String ipv4 = "(([0-9]|[1-9][0-9]|1[0-9][0-9]|[2][0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|[2][0-4][0-9]|25[0-5])";
Pattern ipv4_p = Pattern.compile(ipv4);
//ipv6有8组,个数是1-4个
String ipv6 = "([0-9a-fA-F]{1,4}\\:){7}[0-9a-fA-F]{1,4}";
Pattern ipv6_p = Pattern.compile(ipv6);
if(ipv4_p.matcher(IP).matches())
return "IPv4";
else if(ipv6_p.matcher(IP).matches())
return "IPv6";
else return "Neither";
}
}