本博客文章(学习笔记)导航 (点击这里访问)
描述
以字符串的形式读入两个数字,编写一个函数计算它们的和,以字符串形式返回。
数据范围:len(s),len(t),len(s),len(t)≤100000,字符串仅由'0'~‘9’构成
要求:时间复杂度 O(n)
示例1
输入:"1","99"
返回值:"100"
说明:1+99=100
示例2
输入:"114514",""
返回值:"114514"
思路:
合并数组
import java.util. ;
public class Solution {
/
代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
计算两个数之和
@param s string字符串 表示第一个整数
@param t string字符串 表示第二个整数
@return string字符串
/
public String solve (String s, String t) {
// write code here
int sLength=s.length();
int tLength=t.length();
int minLength=Math.min(sLength,tLength);
s=reverse(s);
t=reverse(t);
StringBuilder sb=new StringBuilder();
int addNum=0;
for(int i=0;i<minLength;i++){
int sNum=(int)(s.charAt(i)-'0');
int tNum=(int)(t.charAt(i)-'0');
int nummy=sNum+tNum+addNum;
addNum=(int)(nummy/10);
sb.append(nummy%10+"");
}
if(sLength>minLength){
for(int i=minLength;i<sLength;i++){
int sNum=(int)(s.charAt(i)-'0');
int nummy=sNum+addNum;
addNum=(int)(nummy/10);
sb.append(nummy%10+"");
}
}
if(tLength>minLength){
for(int i=minLength;i<tLength;i++){
int sNum=(int)(t.charAt(i)-'0');
int nummy=sNum+addNum;
addNum=(int)(nummy/10);
sb.append(nummy%10+"");
}
}
if(addNum!=0) sb.append(addNum+"");
sb=sb.reverse();
String res=sb.toString();
for(int i=0;i<res.length();i++){
if(res.charAt(i)!='0') return res.substring(i,res.length());
}
return res;
}
public String reverse(String str){
return new StringBuilder(str).reverse().toString();
}
}
描述
以字符串的形式读入两个数字,编写一个函数计算它们的乘积,以字符串形式返回。
数据范围: 读入的数字大小满足0≤n≤10^1000
要求:空间复杂度 O(n),时间复杂度 O(n^2)
示例1 输入:"11","99" 返回值:"1089" 说明:11 99=1089
示例2 输入:"1","0" 返回值:"0"
import java.util. ;
public class Solution {
public String solve (String s, String t) {
String res="0";
for(int i=0;i<t.length();i++){
char c=t.charAt(i);
int n=t.length()-1-i;
String temp=twoNummultiply(s,c,n);
res=twoNumsum(res,temp);
}
return res;
}
public String twoNummultiply(String s,char c,int n){
if(c=='0') return "0";
int mulNum=(int)(c-'0');
StringBuilder sb=new StringBuilder();
int addNum=0;
for(int i=s.length()-1;i>=0;i--){
int sNum=(int)(s.charAt(i)-'0');
int temp=sNum mulNum+addNum;
addNum=(int)(temp/10);
sb.append(temp%10);
}
if(addNum!=0) sb.append(addNum);
sb=sb.reverse();
while(n>0){
sb.append("0");
n--;
}
return sb.toString();
}
public String twoNumsum(String s,String t){
int sLength=s.length();
int tLength=t.length();
int minLength=Math.min(sLength,tLength);
s=reverse(s);
t=reverse(t);
StringBuilder sb=new StringBuilder();
int addNum=0;
for(int i=0;i<minLength;i++){
int sNum=(int)(s.charAt(i)-'0');
int tNum=(int)(t.charAt(i)-'0');
int nummy=sNum+tNum+addNum;
addNum=(int)(nummy/10);
sb.append(nummy%10+"");
}
if(sLength>minLength){
for(int i=minLength;i<sLength;i++){
int sNum=(int)(s.charAt(i)-'0');
int nummy=sNum+addNum;
addNum=(int)(nummy/10);
sb.append(nummy%10+"");
}
}
if(tLength>minLength){
for(int i=minLength;i<tLength;i++){
int sNum=(int)(t.charAt(i)-'0');
int nummy=sNum+addNum;
addNum=(int)(nummy/10);
sb.append(nummy%10+"");
}
}
if(addNum!=0) sb.append(addNum+"");
sb=sb.reverse();
String res=sb.toString();
for(int i=0;i<res.length();i++){
if(res.charAt(i)!='0') return res.substring(i,res.length());
}
return res;
}
public String reverse(String str){
return new StringBuilder(str).reverse().toString();
}
}
描述
对于长度为n的一个字符串A(仅包含数字,大小写英文字母),请设计一个高效算法,计算其中最长回文子串的长度。
数据范围:1≤n≤1000
要求:空间复杂度 O(1),时间复杂度 O(n^2)
进阶: 空间复杂度 O(n),时间复杂度 O(n)
示例1 输入:"ababc" 返回值:3
说明:最长的回文子串为"aba"与"bab",长度都为3
示例2 输入:"abbba" 返回值:5
示例3 输入:"b" 返回值:1
思路1:
两层for循环,依次判断i和j之间是不是回文
思路2:
中心扩散法(奇数和偶数)
import java.util. ;
public class Solution {
public int getLongestPalindrome(String A) {
// write code here
char[] chars=A.toCharArray();
int maxlength=0;
for(int i=0;i<chars.length;i++){
for(int j=i;j<chars.length;j++){
if(judge(i,j,chars)) maxlength=Math.max(maxlength,j-i+1);
}
}
return maxlength;
}
public boolean judge(int i,int j,char[] chars){
if(i==j) return true;
while(i<j){
if(chars[i]!=chars[j]) return false;
i++;
j--;
}
return true;
}
}
import java.util. ;
public class Solution {
public int getLongestPalindrome (String A) {
// write code here
if(A.length()==0||A.length()==1) return A.length();
int res=1;
for(int i=0;i<A.length();i++){
res=Math.max(res,Longest(i,A));
}
return res;
}
public int Longest(int i,String A){
//奇数
int left=i,right=i,res=1;
while(left>=0&&right<A.length()){
if(A.charAt(left)==A.charAt(right)){
res=Math.max(right-left+1,res);
left--;
right++;
}else{
break;
}
}
//偶数
if((i+1)<A.length() && A.charAt(i+1)==A.charAt(i)){
left=i-1;
right=i+2;
res=Math.max(2,res);
while(left>=0&&right<A.length()){
if(A.charAt(left)==A.charAt(right)){
res=Math.max(right-left+1,res);
left--;
right++;
}else{
break;
}
}
}
return res;
}
}
描述
现在有一个只包含数字的字符串,将该字符串转化成IP地址的形式,返回所有可能的情况。
例如:给出的字符串为"25525522135",
返回["255.255.22.135", "255.255.221.35"]. (顺序没有关系)
数据范围:字符串长度0≤n≤12
要求:空间复杂度 O(n!),时间复杂度 O(n!)
注意:ip地址是由四段数字组成的数字序列,格式如 "x.x.x.x",其中 x 的范围应当是 [0,255]。
示例1
输入:"25525522135"
返回值:["255.255.22.135","255.255.221.35"]
示例2
输入:"1111"
返回值:["1.1.1.1"]
示例3
输入:"000256"
返回值:"[]"
思路1:
暴力枚举,每一个位包含一到三位字符
如果四个位置相加为s.length
思路2:
递归回溯
import java.util. ;
public class Solution {
public ArrayList<String> restoreIpAddresses (String s) {
ArrayList<String> list = new ArrayList();
for(int a=1; a<4; a++){
for(int b=1; b<4; b++){
for(int c=1; c<4; c++){
for(int d=1; d<4; d++){
if(a+b+c+d==s.length()){
String s1 = s.substring(0, a);
String s2 = s.substring(a, a+b);
String s3 = s.substring(a+b, a+b+c);
String s4 = s.substring(a+b+c, a+b+c+d);
if(check(s1)&&check(s2)&&check(s3)&&check(s4)){
String ip = s1+"."+s2+"."+s3+"."+s4;
list.add(ip);
}
}
}
}
}
}
return list;
}
public boolean check(String s){
if(Integer.valueOf(s)<=255){
if(s.charAt(0)!='0' || s.charAt(0)=='0'&&s.length()==1)
return true;
}
return false;
}
}
思路2:
import java.util. ;
public class Solution {
public ArrayList<String> restoreIpAddresses (String s) {
if (s.length() > 12) {
return null;
}
StringBuilder sb = new StringBuilder(s);
doRestoreIpAddresses(sb, 1);
return ans;
}
ArrayList<String> ans = new ArrayList<>();
public void doRestoreIpAddresses(StringBuilder s, int m) { // 回溯暴力算法,还要很多地方没有剪枝
String[] nums = s.toString().split("\\.");
if (nums.length > 4) { // 剪枝
return;
}
if (validateIPv4(s.toString())) { // 结束条件
ans.add(String.copyValueOf(s.toString().toCharArray()));
return;
}
for (int i = m; i < s.length(); i++) { // 回溯
s.insert(i, ".");
doRestoreIpAddresses(s, i + 2);
s.replace(i, i + 1, "");
}
}
public boolean validateIPv4(String IP) {
String[] nums = IP.split("\\.");
if (nums.length != 4) {
return false;
}
for (String x : nums) {
// 0-255:
if (x.length() == 0 || x.length() > 3) return false;
// 0的情况
if (x.charAt(0) == '0' && x.length() != 1) return false;
// 大于255
if (Integer.parseInt(x) > 255) return false;
}
return true;
}
}
描述
对于一个长度为 n 字符串,我们需要对它做一些变形。
首先这个字符串中包含着一些空格,就像"Hello World"一样,然后我们要做的是把这个字符串中由空格隔开的单词反序,同时反转每个字符的大小写。
比如"Hello World"变形后就变成了"wORLD hELLO"。
数据范围: 1≤n≤10^6, 字符串中包括大写英文字母、小写英文字母、空格。
进阶:空间复杂度 O(n), 时间复杂度 O(n)
输入描述:给定一个字符串s以及它的长度n(1 ≤ n ≤ 10^6)
返回值描述:请返回变形后的字符串。题目保证给定的字符串均由大小写字母和空格构成。
示例1
输入:"This is a sample",16
返回值:"SAMPLE A IS tHIS"
示例2
输入:"nowcoder",8
返回值:"NOWCODER"
思路:
1 用StringBuilder和Stack来做
2 遇到空格就把 StringBuilder的东西入栈并清空StringBuilder
3 遇到其他字符就放在StringBuilder中
4 最后把栈里的元素弹出来,后面拼空格
5 再把最后一个空格删掉
import java.util. ;
public class Solution {
public String trans(String s, int n) {
// write code here
//使用栈的特性,输出为反向
Stack<String>stack=new Stack<>();
StringBuffer buffer=new StringBuffer();
for(int i=0;i<n;i++){
//遇到空格入栈
if(s.charAt(i)==' '){
stack.push(buffer.toString());
buffer.delete(0,buffer.length());
}else{
//小写字母-32转为大写
if(s.charAt(i)>='a'&&s.charAt(i)<='z'){
buffer.append((char)(s.charAt(i)-32));
}else{
//大写字母+32转为小写
buffer.append((char)(s.charAt(i)+32));
}
}
}
//最后一个单词入栈
stack.push(buffer.toString());
StringBuffer ans=new StringBuffer();
while(!stack.isEmpty()){
ans.append(stack.pop());
//每个单词后接空格
ans.append(' ');
}
//删除最后一个多余空格
ans.deleteCharAt(ans.length()-1);
return ans.toString();
}
}
描述
给你一个大小为 n 的字符串数组 strs ,其中包含n个字符串 , 编写一个函数来查找字符串数组中的最长公共前缀,返回这个公共前缀。数据范围:0≤n≤5000, 0≤len(strs i)≤5000
进阶:空间复杂度 O(n),时间复杂度 O(n)
示例1
输入:["abca","abc","abca","abc","abcc"]
返回值:"abc"
示例2
输入:["abc"]
返回值:"abc"
思路:
1 先按照字典序排序
2 比较第一个和最后一个的公共前缀
import java.util. ;
public class Solution {
public String longestCommonPrefix (String[] strs) {
if(strs==null||strs.length==0) return "";
Arrays.sort(strs);
StringBuilder sb=new StringBuilder();
for(int i=0;i<strs[0].length();i++){
if(strs[0].charAt(i)==strs[strs.length-1].charAt(i)){
sb.append(strs[0].charAt(i));
}else{
break;
}
}
return sb.toString();
}
}
描述
编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址
IPv4 地址由十进制数和点来表示,每个地址包含4个十进制数,其范围为 0 - 255, 用(".")分割。比如,172.16.254.1;
同时,IPv4 地址内的数不会以 0 开头。比如,地址 172.16.254.01 是不合法的。
IPv6 地址由8组16进制的数字来表示,每组表示 16 比特。这些组数字通过 (":")分割。比如, 2001:0db8:85a3:0000:0000:8a2e:0370:7334 是一个有效的地址。而且,我们可以加入一些以 0 开头的数字,字母可以使用大写,也可以是小写。所以, 2001:db8:85a3:0:0:8A2E:0370:7334 也是一个有效的 IPv6 address地址 (即,忽略 0 开头,忽略大小写)。
然而,我们不能因为某个组的值为 0,而使用一个空的组,以至于出现 (::) 的情况。 比如, 2001:0db8:85a3::8A2E:0370:7334 是无效的 IPv6 地址。
同时,在 IPv6 地址中,多余的 0 也是不被允许的。比如, 02001:0db8:85a3:0000:0000:8a2e:0370:7334 是无效的。
说明: 你可以认为给定的字符串里没有空格或者其他特殊字符。
数据范围:字符串长度满足5≤n≤50
进阶:空间复杂度 O(n),时间复杂度 O(n)
示例1
输入:"172.16.254.1"
返回值:"IPv4"
说明:这是一个有效的 IPv4 地址, 所以返回 "IPv4"
示例2
输入:"2001:0db8:85a3:0:0:8A2E:0370:7334"
返回值:"IPv6"
说明:这是一个有效的 IPv6 地址, 所以返回 "IPv6"
示例3
输入:"256.256.256.256"
返回值:"Neither"
说明:这个地址既不是 IPv4 也不是 IPv6 地址
注意事项
2 分割字符串时,使用limit = -1的split函数,使得字符串末尾或开头有一个'.'或':'也能分割出空的字符串
2 使用Integer.parseInt()函数检查异常
3 startsWith("0")方法判断以"0"为开头
import java.util. ;
public class Solution {
public String solve(String IP) {
return validIPv4(IP) ? "IPv4" : (validIPv6(IP) ? "IPv6" : "Neither");
}
private boolean validIPv4(String IP) {
String[] strs = IP.split("\\.", -1);
if (strs.length != 4) {
return false;
}
for (String str : strs) {
if (str.length() > 1 && str.startsWith("0")) {
return false;
}
try {
int val = Integer.parseInt(str);
if (!(val >= 0 && val <= 255)) {
return false;
}
} catch (NumberFormatException numberFormatException) {
return false;
}
}
return true;
}
private boolean validIPv6(String IP) {
String[] strs = IP.split(":", -1);
if (strs.length != 8) {
return false;
}
for (String str : strs) {
if (str.length() > 4 || str.length() == 0) {
return false;
}
try {
int val = Integer.parseInt(str, 16);
} catch (NumberFormatException numberFormatException) {
return false;
}
}
return true;
}
}
描述
以字符串的形式读入两个数字,编写一个函数计算它们的和,以字符串形式返回。数据范围:len(s),len(t)≤100000,字符串仅由'0'~‘9’构成
要求:时间复杂度 O(n)
示例1
输入:"1","99"
返回值:"100"
说明:1+99=100
示例2
输入:"114514",""
返回值:"114514"
思路:
合并链表的类似做法
1 反转两条字符串
2 合并字符串
3 反转结果
import java.util. ;
public class Solution {
public String solve (String s, String t) {
StringBuilder s0=new StringBuilder(s);
StringBuilder t0=new StringBuilder(t);
s=s0.reverse().toString();
t=t0.reverse().toString();
int add=0,i=0,j=0;
StringBuilder res=new StringBuilder();
while(i<s.length()&&j<t.length()){
int sum=(int)(s.charAt(i)-'0')+(int)(t.charAt(j)-'0')+add;
res.append(sum%10+"");
add=sum/10;
i++;
j++;
}
while(i<s.length()){
int sum=(int)(s.charAt(i)-'0')+add;
res.append(sum%10+"");
add=sum/10;
i++;
}
while(j<t.length()){
int sum=(int)(t.charAt(j)-'0')+add;
res.append(sum%10+"");
add=sum/10;
j++;
}
if(add!=0) res.append(add+"");
return res.reverse().toString();
}
}