数学计算

数学计算

计算小于n的素数个数

# Ruby
# @param {Integer} n
# @return {Integer}
def count_primes(n)
    return 0 if n <= 2
    return 1 if n == 3
    mark = [false] * n
    t = Math.sqrt(n).to_i
    counter = n - 2
    for i in 2..t
        next if mark[i]
        (i * i).step n-1, i do |j|
            next if mark[j]
            mark[j] = true
            counter -= 1
        end
    end
    counter
end

Count Primes


求总面积

这里写图片描述
显然此题的关键是求相交部分的面积,可是两矩形的位置大小是任意的,相交与否,怎么相交,情况有多种,要考虑各种情况,感觉处理起来会比较费神。下面的解法唯一的特点就是逻辑极其简单:保持逻辑上的图形与题中例子的图片一致。
只需要保持长或宽方向上一致就行了: 求相交矩形的长的时候,保证h>d; 求相交矩形宽的时候,保证d>b。这么一来就把一个二维问题转化成了两个一维问题。思考起来就极简单。

# Ruby
def compute_area(a, b, c, d, e, f, g, h)
    a, b, c, d, e, f, g, h = e, f, g, h, a, b, c, d if c > g
    x = 0 if e >= c 
    x = c - e if e > a
    x = c - a if e <= a
    a, b, c, d, e, f, g, h = e, f, g, h, a, b, c, d if h > d
    y = 0 if b >= h  
    y = h - b if b > f
    y = h - f if b >= f
    (c - a) * (d - b) + (g - e) * (h - f) - x * y
end

大神的解法:

// Java
public int computeArea(int A, int B, int C, int D, int E, int F, int G, int H) {
        int together;
        if (C <= E || A >= G || B >= H || D <= F) {
            together = 0;
        } else {
            int x = Math.min(C, G) - Math.max(A, E);
            int y = Math.min(D, H) - Math.max(B, F);
            together = x * y;
        }
        return (C - A) * (D - B) + (G - E) * (H - F) - together;
    }

Rectangle Area


统计数字的范围

For example, given [0,1,2,4,5,7], return [“0->2”,”4->5”,”7”].

# Ruby
# @param {Integer[]} nums
# @return {String[]}
def summary_ranges(nums)
    result = []
    temp = []
    nums.each do |num|
        if temp.empty?
            temp << num
        else
            if num - temp.last == 1
                temp << num
            else
                if temp.count == 1
                    result << temp.pop.to_s
                else
                    result << sprintf("%d->%d", temp.first, temp.last)
                    temp.clear
                end
                redo
            end
        end
    end
    result << temp.pop.to_s if temp.count == 1
    result << sprintf("%d->%d", temp.first, temp.last) if temp.count > 1
    result
end

牛人解法:

//C++
 vector<string> summaryRanges(vector<int>& nums) {
    int i = 0, size = nums.size();
    vector<string> result; 
    while(i < size){
        int j = 1; 
        while(i + j < size && nums[i + j] - nums[i] == j) ++j;
        result.push_back(j <= 1 ? to_string(nums[i]) : to_string(nums[i]) + "->" + to_string(nums[i + j - 1]));
        i += j; 
    }
    return result; 
}

Summary Ranges


判断是否是快乐数

Example: 如果n是快乐数, 那么用n各个数字的平方和代替n, 不断重复能使n=1。如果n不是快乐数,将是个无尽的循环。
如19是一个快乐数:
12+92=82
82+22=68
62+82=100
12+02+02=1
Given : n是正整数
return:true 或 false
思路:判断是快乐数很简单,关键是判断不是快乐数并跳出循环。既然是循环,那应当会出现重复的n, 一旦新求得的n曾经出现过,便跳出循环。会不会出现n不重复且求不尽的情况呢?这个证明难住我了,留给别人去证明吧~

# Ruby
def is_happy(n)
    array = []
    until array.include? n
        array << n
        sum = 0
        n.to_s.split('').each do |s| sum += s.to_i ** 2 end
        return true if sum == 1
        n = sum
    end
    false
end

其实还可以用哈希表(散列),若19是快乐数,那么82,68,100必然也是快乐数,若某数不是快乐数,那么那些计算过程中的中间值也必然不是快乐数,有点像求素数的方法。
Happy Number


有几个0尾巴

Given an integer n, return the number of trailing zeroes in n!.
即求整数n的阶乘的结尾有几个0。这种题最关键是弄清题意:
显然是问n!中因数10的个数,又n的因数2的个数肯定比因数5的个数多,只要有因数5就一定能找到因数2与其搭配成为10,那么因数10的个数就等于因数5的个数。接下来只需要注意时间复杂度就行了。

/* C */
int trailingZeroes(int n) {
    int res = 0;
    while(n){res += n /= 5;}
    return res;
}

Factorial Trailing Zeroes


Excel列标题

For example:

1 -> A
2 -> B
3 -> C
...
26 -> Z
27 -> AA
28 -> AB 
/* C */
char* convertToTitle(int n) {
    char *res = (char *)calloc(8, sizeof(char));
    int i = 6;
    while(n){
        res[i--] = (char)((n-1) % 26) + 'A';
        n = (n - 1) / 26;
    }
    return res+i+1;
}

挺像进制转换,但又不是直接转成26进制,有点像1-9,11-19,21-29…少了个位为0的数。就依这个例子简化问题,用n = (n - 1) / 9,恰能保持9进制,又能使9的倍数不进位。
Excel Sheet Column Title


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值