字符串/双指针
BM22 比较版本号
import java.util.*;
public class Solution {
public int compare (String v1, String v2) {
int m=v1.length(),n=v2.length();
int i=0,j=0;
while(i<m || j<n){
int a=0;
while(i<m && v1.charAt(i)!='.'){
a=a*10+v1.charAt(i)-'0';
i++;
}
int b=0;
while(j<n && v2.charAt(j)!='.'){
b=b*10+v2.charAt(j)-'0';
j++;
}
if(a!=b) return a>b?1:-1;
i++;
j++;
}
return 0;
}
}
BM83 字符串变形
import java.util.*;
public class Solution {
public String trans(String s, int n) {
String[] sa = s.split(" ", -1);//spilt的第二个参数imit设为-1可以让字符串最后的空格不被省略。
StringBuilder sb = new StringBuilder();
for (int i = sa.length - 1; i >= 0; i--) {
sb.append(handle(sa[i])).append(" ");
}
return sb.substring(0,sb.length() - 1);
}
private String handle(String s){
StringBuilder sb= new StringBuilder();
for(char c:s.toCharArray()){
if(Character.isLowerCase(c)) sb.append(Character.toUpperCase(c));
else if(Character.isUpperCase(c)) sb.append(Character.toLowerCase(c));
}
return sb.toString();
}
}
BM84 最长公共前缀
import java.util.*;
public class Solution {
public String longestCommonPrefix (String[] strs) {
if(strs.length==0) return "";
String res=strs[0];
for(String s:strs){
while(!s.startsWith(res)){
if(res.length()==0) return "";
res=res.substring(0,res.length()-1);
}
}
return res;
}
}
BM85 验证IP地址
import java.util.*;
public class Solution {
public String solve(String IP) {
if(IP.indexOf(':') == -1){
return validateIPv4(IP);
}
else if(IP.indexOf('.') == -1){
return validateIPv6(IP);
}
else return "Neither";
}
/*
split() 方法根据匹配给定的正则表达式来拆分字符串。
注意: . 和 $和 | 和 * 等转义字符,必须得加 \\。
注意:多个分隔符,可以用 | 作为连字符。
*/
//IPv4 地址由4组10进制数来表示,其范围为 0 - 255,每组长度1-3, 用(".")分割。比如,172.16.254.1
//同时,IPv4 地址内的数不会以 0 开头。比如,地址 172.16.254.01 是不合法的。
public String validateIPv4(String IP) {
String[] nums = IP.split("\\.",-1);
if(nums.length!=4) return "Neither";
for (String x : nums) {
if (x.length() == 0 || x.length() > 3) return "Neither";
if (x.charAt(0) == '0' && x.length() != 1) return "Neither";
for (char c : x.toCharArray()){
if (c < '0' || c > '9') return "Neither";
}
if (Integer.parseInt(x) > 255) return "Neither";
}
return "IPv4";
}
//IPv6 地址由8组16进制的数字来表示,每组表示 16 比特,每组长度1-4。这些组数字通过 (":")分割
//不能出现 (::) 、(:0000:0000:)的情况。(:0:0:)是对的
public String validateIPv6(String IP) {
String[] nums = IP.split(":",-1);
if(nums.length!=8) return "Neither";
String hexdigits = "0123456789abcdefABCDEF";
for (String x : nums) {
if (x.length() == 0 || x.length() > 4) return "Neither";
for (Character c : x.toCharArray()) {
if (hexdigits.indexOf(c) == -1) return "Neither";
}
}
return "IPv6";
}
}
BM86 大数加法
import java.util.*;
public class Solution {
public String solve(String num1, String num2) {
StringBuilder res = new StringBuilder();
int i = num1.length() - 1, j = num2.length() - 1, carry = 0;
while(i >= 0 || j >= 0 || carry != 0){
int n1 = i >= 0 ? num1.charAt(i) - '0' : 0;
int n2 = j >= 0 ? num2.charAt(j) - '0' : 0;
int tmp = n1 + n2 + carry;
carry = tmp / 10;
res.append(tmp % 10);
i--;
j--;
}
return res.reverse().toString();
}
}
/*
import java.math.BigInteger;
public class Solution {
public String solveByJava(String s, String t){
BigInteger num1 = new BigInteger(s);
BigInteger num2 = new BigInteger(t);
return num1.add(num2).toString();
}
}
*/
BM49 表达式求值
import java.util.*;
public class Solution {
public int solve (String s) {
Stack<Integer> stack = new Stack<>();//初始化栈
int num= 0;//默认数字
char sign = '+';//默认的第一个数字前的运算符为 +
char[] arr = s.toCharArray();//字符串转化字符数组
for(int i = 0;i<s.length();i++){//对字符数组每个元素遍历
char c = arr[i];
if (c == ' ') continue;
if(c == '('){//是否为左括号
int j = i + 1;
int counterPar = 1;//默认是1对括号
while(counterPar > 0){//统计是否存在括号嵌套的情况
if(arr[j] == '(') counterPar++;
else if(arr[j] == ')')counterPar--;
//向后直到找到右括号
j++;
}
//遇到左括号递归求这个括号里面表达式的值
//就是求左括号 到 右括号 之间 表达式的 值,返回值为 number,下面接着进栈
num = solve(s.substring(i + 1,j - 1));
//下一次就要从 j 开始,因为后面还有一个 i ++;
i = j - 1;
}
if(c >= '0' && c <= '9') num = num * 10 + c - '0';
//if(Character.isDigit(c)) num = num * 10 + c - '0';//是否为数字,是数字就求完整的数字值,每次循环都进这个分支,直到出现运算符
//if( ! Character.isDigit(c) || i == s.length() - 1){
if (c < '0' || c > '9'|| i == s.length() - 1){//不是数字 或者 为最后一个字符
if(sign == '+') stack.push(num);//是 + 先把 数字 压栈,等会全部数字出栈之和即为所求
else if(sign == '-') stack.push( -1 * num);//是 - 压栈该数字的相反数
else if(sign == '*') stack.push(stack.pop() * num);//是 * ,弹栈算出结果,在压栈
else if(sign == '/') stack.push(stack.pop() / num);//是 / ,弹栈算出结果,在压栈
num = 0; //每次结束,数字恢复默认值
// 遇到运算符时或者到表达式末尾时,就去计算上一个运算符并把计算结果push进栈,然后保存新的运算符
//运算符为 当前压栈数字 前面近邻的那个
sign = c;
//如果是负数 在 表达式的最前面 ,会先压栈 +0,然后在记录当前 负号,开始接下来的数字
}
}
int sum = 0; //结果
while(!stack.isEmpty()){
sum += stack.pop();
}
return sum;
}
}
BM88 判断是否为回文字符串
import java.util.*;
public class Solution {
public boolean judge (String str) {
int i=0,j=str.length()-1;
while(i<=j){
if(str.charAt(i)!=str.charAt(j)) return false;
i++;
j--;
}
return true;
}
}
BM91 反转字符串
import java.util.*;
public class Solution {
public String solve (String str) {
char[] arr=str.toCharArray();
int i=0,j=arr.length-1;
while(i<j){
char tmp=arr[i];
arr[i]=arr[j];
arr[j]=tmp;
i++;
j--;
}
return new String(arr);
}
}
BM90 最小覆盖子串
import java.util.*;
public class Solution {
public String minWindow(String s, String t) {
if (s == null || s.length() == 0 || t == null || t.length() == 0) return "";
int[] need = new int[128];
for (int i = 0; i < t.length(); i++) need[t.charAt(i)]++;
int l = 0, r = 0, res = Integer.MAX_VALUE, count = t.length(), start = 0;
while (r < s.length()) {
if (need[s.charAt(r)] > 0) count--;
need[s.charAt(r)]--;
if (count == 0) {
while (l < r && need[s.charAt(l)] < 0) {
need[s.charAt(l)]++;
l++;
}
if (r - l + 1 < res) {
res = r - l + 1;
start = l;
}
need[s.charAt(l)]++;
l++;
count++;
}
r++;
}
return res == Integer.MAX_VALUE ? "" : s.substring(start, start + res);
}
}
BM87 合并两个有序的数组
import java.util.*;
public class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
int i = m - 1, j = n - 1, k = m + n - 1;
while (j >= 0) {
if (i < 0 || nums2[j] > nums1[i]) nums1[k--] = nums2[j--];
else nums1[k--] = nums1[i--];
}
}
}
BM89 合并区间
import java.util.*;
/**
* Definition for a{n interval.
* public class Interval {
* int start;
* int end;
* Interval() { start = 0; end = 0; }
* Interval(int s, int e) { start = s; end = e; }
* }
*/
public class Solution {
ArrayList<Interval> res = new ArrayList<Interval>();
public ArrayList<Interval> merge(ArrayList<Interval> intervals) {
Collections.sort(intervals, (v1,v2) ->v1.start - v2.start);
int i = -1;
for(Interval interval :intervals){
if(i == - 1 ||interval.start >res.get(i).end){
res.add(interval);
i++;
}else res.get(i).end = Math.max(interval.end, res.get(i).end);
}
return res;
}
/*
int[][] res=new int[intervals.length][2];
public int[][] merge(int[][] intervals) {
Arrays.sort(intervals,(v1,v2)->v1[0]-v2[0]);
int i=-1;
for(int[] interval:intervals){
if(i==-1||interval[0]>res[i][1]) res[++i]=interval;
else res[i][1]=Math.max(res[i][1],interval[1]);
}
return Arrays.copyOf(res,i+1);
}
*/
}
BM92 最长无重复子数组(子数组是连续的)
import java.util.*;
public class Solution {
public int maxLength (int[] arr) {
Map<Integer, Integer> map = new HashMap<>();
int i = -1, res = 0;
for(int j = 0; j < arr.length; j++) {
if(map.containsKey(arr[j]))
i = Math.max(i, map.get(arr[j])); // 更新左指针 i
map.put(arr[j], j); // 哈希表记录
res = Math.max(res, j - i); // 更新结果
}
return res;
}
}
BM93 盛水最多的容器
import java.util.*;
public class Solution {
public int maxArea(int[] height) {
int i=0,j=height.length-1;
int res=0;
while(i<j){
if(height[i]<height[j]){
res=Math.max(res,(j-i)*height[i]);//值小的指针向内移动
i++;
}
else{
res=Math.max(res,(j-i)*height[j]);//值小的指针向内移动
j--;
}
/*
res=height[i]<height[j]?
Math.max(res,(j-i)*height[i++]):
Math.max(res,(j-i)*height[j--]);
*/
}
return res;
}
}
BM94 接雨水问题
import java.util.*;
public class Solution {
public long maxWater(int[] height) {
int n=height.length;
long sum = 0;
int[] max_left = new int[n];
int[] max_right = new int[n];
for (int i = 1; i <= n-2; i++) {
max_left[i] = Math.max(max_left[i - 1], height[i - 1]);//第 i 列左边最高的墙,不包括自身的
}
for (int i = n-2; i >= 1; i--) {
max_right[i] = Math.max(max_right[i + 1], height[i + 1]);//第 i 列右边最高的墙,不包括自身的
}
for (int i = 1; i <= n-2; i++) {
int min = Math.min(max_left[i], max_right[i]);
if (min > height[i]) sum = sum + (min - height[i]);
//求第 i 列左右两边最高的墙。找出较矮的一端,减去当前列的高度
}
return sum;
}
}