leetcode
1、加一
给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1:
输入: [1,2,3]
输出: [1,2,4]
解释: 输入数组表示数字 123。
示例 2:
输入: [4,3,2,1]
输出: [4,3,2,2]
解释: 输入数组表示数字 4321。
根据题意加一,没错就是加一这很重要,因为它是只加一的所以有可能的情况就只有两种:
除 999 之外的数字加一;
数字 999。
加一得十进一位个位数为 000 加法运算如不出现进位就运算结束了且进位只会是一。
所以只需要判断有没有进位并模拟出它的进位方式,如十位数加 111 个位数置为 000,如此循环直到判断没有再进位就退出循环返回结果。
然后还有一些特殊情况就是当出现 999999、999999999 之类的数字时,循环到最后也需要进位,出现这种情况时需要手动将它进一位。
class Solution {
public int[] plusOne(int[] digits) {
for(int i = digits.length -1;i >=0;i--){
digits[i]++;
digits[i] = digits[i] % 10;
if(digits[i] != 0)return digits;
}
digits = new int[digits.length + 1];
digits[0] = 1;
return digits;
}
}
2、反转数字
手写代码:给出一个int类型123,写一个函数,返回反转的值321
public class reverseNumber {
public static void main(String[] args) {
int num = 12367875;
int reverseNum = 0;
while(num != 0) {
reverseNum = reverseNum*10+num%10;
num/=10;
}
System.out.println(reverseNum);
}
}
3、求两个数的最大公约数
//求两个数的最大公约数
public class divisionTest {
public static void main(String[] args) {
division(8, 12);
System.out.println(res);
}
static int res;
public static void division(int n, int m) {
if (m == 0) {
res = n;
return;
}
else if (n < m)
division(m, n); // 交换m与n
else {
int temp = n;
n = m;
m = temp % n;
division(n, m); // 重复上述过程
}
}
}
4x的平方根
实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
public class Solution {
public int mySqrt(int x) {
// 注意:针对特殊测试用例,例如 2147395599
// 要把搜索的范围设置成长整型
// 为了照顾到 0 把左边界设置为 0
long left = 0;
// # 为了照顾到 1 把右边界设置为 x // 2 + 1
long right = x / 2 + 1;
while (left < right) {
// 注意:这里一定取右中位数,如果取左中位数,代码会进入死循环
// long mid = left + (right - left + 1) / 2;
long mid = (left + right + 1) >>> 1;
long square = mid * mid;
if (square > x) {
right = mid - 1;
} else {
left = mid;
}
}
// 因为一定存在,因此无需后处理
return (int) left;
}
}
写一个函数,求平方根,函数参数为目标数字和精度,测试案例 fn(4.1,0.001) fn(501.1,0.001) fn(0.045,0.001)
二分法:n为数字,e为精度
//float型是8位有效数字,占4个字节,double双精度类型,是17位有效数字,占8个字节
public static float fn(float n, float e){
float x = 0;
if (n > 0 && e > 0){
float low = 0;
float high = n;
while (low < high){
float mid = (low + high)/2;
if (mid * mid < n - e){
low = mid;
}else if(mid * mid > n + e){
high = mid;
}else {
x = mid;
break;
}
}
}
return x;
}
5最小覆盖子串
给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。
示例:
输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"
说明:
如果 S 中不存这样的子串,则返回空字符串 ""。
如果 S 中存在这样的子串,我们保证它是唯一的答案。
答:滑动窗口
import java.util.Map;
import java.util.HashMap;
class Solution {
public String minWindow(String s, String t) {
int left,right,count,minLen= Integer.MAX_VALUE;
int start=0,end=0;
//needs存储t的<字符,出现次数>,windows存储<s中与t中字符相同的字符,出现次数>
HashMap<Character,Integer> needs = new HashMap<>();
HashMap<Character,Integer> windows = new HashMap<>();
//初始化needs
for(int i=0;i<t.length();i++){
//needs.getOrDefault(t.charAt(i),0)+1 含义是:needs如果包含t.charAt(i),
//则取出值+1;不包含取0+1
needs.put(t.charAt(i),needs.getOrDefault(t.charAt(i),0)+1);
}
left=right=count=0;
while(right <s.length()){
//获取字符
char temp=s.charAt(right);
//如果是t中字符,在windows里添加,累计出现次数
if(needs.containsKey(temp)){
windows.put(temp,windows.getOrDefault(temp,0)+1);
//注意:Integer不能用==比较,要用compareTo
if(windows.get(temp).compareTo(needs.get(temp))==0 ){
//字符temp出现次数符合要求,count代表符合要求的字符个数
count++;
}
}
//优化到不满足情况,right继续前进找可行解
right++;
//符合要求的字符个数正好是t中所有字符,获得一个可行解
while(count==needs.size()){
//更新结果
if(right-left<minLen){
start=left;
end=right;
minLen=end-left;
}
//开始进行优化,即缩小区间,删除s[left],
char c=s.charAt(left);
//当前删除的字符包含于t,更新Windows中对应出现的次数,如果更新后的次数<t中出现的次数,符合要求的字符数减1,下次判断count==needs.size()时不满足情况,
if(needs.containsKey(c)){
windows.put(c,windows.getOrDefault(c,1)-1);
if(windows.get(c)<needs.get(c)){
count--;
}
}
left++;
}
}
//返回覆盖的最小串
return minLen==Integer.MAX_VALUE ? "":s.substring(start,end);
}
}