leetcode数学相关

166分数到小数

给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数。如果小数部分为循环小数,则将循环的部分括在括号内。

输入: numerator = 2, denominator = 3
输出: "0.(6)"

思路:

  • 分母、分子为0的情况
  • 新建StringBuilder
  • 结果是否为负数,是则加上负号
  • 分子分母取绝对值
  • 处理整数部分,并判断是否可以整除,是的话返回结果。注意转为long,且用long rem = (num % den) * ,10;来判断是否可以整除,之后会不断用到。
  • 不能整除,那么加上小数点,新建map,用来存储余数及当前结果的长度
  • 只要余数不为0,那么进入循环。
    • 检查map中,当前余数是否已经出现过,如果是,取值,substring处理循环部分
    • 更新map、res和rem
  • 返回res.toString()
// 分母、分子为0的情况
if (denominator == 0) return "";
if (numerator == 0) return "0";

StringBuilder res = new StringBuilder();
// 结果是否为负数
if ((numerator < 0) ^ (denominator < 0)) res.append("-");

// 取绝对值,方便处理
long num = numerator, den = denominator;
num = Math.abs(num);
den = Math.abs(den);

// 整数部分
res.append(num / den);
long rem = (num % den) * 10;
if (rem == 0) return res.toString();

// 负数部分
res.append(".");
HashMap<Long, Integer> map = new HashMap<Long, Integer>();

while (rem != 0) {
    if (map.containsKey(rem)) {
        Integer loc = map.get(rem);
        String p1 = res.substring(0, loc);
        String p2 = res.substring(loc);
        res = new StringBuilder(p1 + "(" + p2 + ")");
        return res.toString();
    }
    map.put(rem, res.length());
    res.append(rem / den);
    rem = (rem % den) * 10;
}
return res.toString();

169/229求众数

169次数大于一半才是众数

思路:

  • 设置maj和cnt变量
  • 遍历
    • 如果cnt==0,那么maj更新为当前num,cnt++,即初始化为1,否则如果重复,cnt++,不重复cnt--
int maj = 0, cnt = 0;

// 遍历
for (int num : nums){
    if (num == maj){
        cnt++;
    }
    else if (cnt == 0) {
        maj = num;
        cnt++;
    }
    else cnt--;
}

229超过n/3属于众数

思路

  • 和上面类似,但设置两个候选众数。而且要对这两个候选变量进行验证,即是否真的超过n/3
int m = 0, n = 0, cm = 0, cn = 0;
for (auto &a : nums) {
    if (a == m) ++cm;
    else if (a ==n) ++cn;
    else if (cm == 0) m = a, cm = 1;
    else if (cn == 0) n = a, cn = 1;
    else --cm, --cn;
}
cm = cn = 0;
for (auto &a : nums) {
    if (a == m) ++cm;
    else if (a == n) ++cn;
}
if (cm > nums.size() / 3) res.push_back(m);
if (cn > nums.size() / 3) res.push_back(n);
return res;

238除自身以外数组的乘积

输入: [1,2,3,4]
输出: [24,12,8,6]

思路:题目不能用除法

  • 新建数组记录每个数字左边的累积,然后乘上右边的累乘。右边的累乘用一个变量表示,不断作用于存储了左边累积的数组
  • 注意边界问题:左边界初始化为1,右边界记录的是[0, n-2]的累积,所以不需要nums[n-1]

注意边界初始化record[0] = 1和right = 1,再根据例子列出左累乘[1,1,2,6]就可已解出

int n = nums.length;
int[] record = new int[n];
record[0] = 1;
for (int i = 1; i < n; i++){
    record[i] = record[i-1] * nums[i-1];
}

int right = 1;
for (int i = n - 1; i >=0; i--){
    record[i] *= right;
    right *= nums[i]; 
}

return record;

69Sqrt(x) 求平方根

if (x == 0) return 0;
double res = (double) x;
double last = 0.0;
while (res != last) {
    last = res;
    res = res - x / (2 * res); // 求解看下面
}
return (int) res;

f(x) = x2 - n

(f(x) - f(xi))/ (x - xi) = f'(xi)

求出xi+1 = g(x)即可,x表示上面res,f(x)表示上面的参数x

231Power of Two

n > 0 && (n & (n-1)) == 0

posted @ 2018-12-11 01:44  justcodeit  阅读(198)  评论(0编辑  收藏  举报