数学相关的问题

数学问题总结

主要是leetcode以及部分习题上的简单数学问题,因主要是回答考题,所以不太考虑时间复杂度以及空间复杂度。

1.回文数

回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
例如,121 是回文,而 123 不是

思路:
1.先处理特殊情况:最后一位为零(不包括本身是0)和负数一定不是
2.把每一位存入数组,然后当成回文串的问题去处理。

// An highlighted block
bool isPalindrome(int x){
    int a[20];
    int i=0,j;//i统计输入数的位数
    if(x<0||(x%10==0&&x!=0)){
        return false;
    }
    while(x>0){//取每一位存入数组
        a[i]=x%10;
        x=x/10;
        i++;
    }
    for(j=0;j<i/2;j++){//对称的数作比较
        if(a[j]!=a[i-1-j]){
            return false;
        }
    }
    return true;
}


2.罗马数组转整数

题目太长,直接复制。
在这里插入图片描述
思路:把字母做相应隐射,数组的小标是字母,值是字母对应的值。取字符串每个字符时,与上一个字符对应的值比较,如果大于上一个字符,则加;小于上一个,则减

// An highlighted block
int romanToInt(char* s) {
    int symbolValues[26];
    symbolValues['I' - 'A'] = 1;
    symbolValues['V' - 'A'] = 5;
    symbolValues['X' - 'A'] = 10;
    symbolValues['L' - 'A'] = 50;
    symbolValues['C' - 'A'] = 100;
    symbolValues['D' - 'A'] = 500;
    symbolValues['M' - 'A'] = 1000;
    int ans = 0;
    int n = strlen(s);
    for (int i = 0; i < n; ++i) {
        int value = symbolValues[s[i] - 'A'];
        if (i < n - 1 && value < symbolValues[s[i + 1] - 'A']) {
            ans -= value;
        } else {
            ans += value;
        }
    }
    return ans;
}

3.快乐数

在这里插入图片描述

思路:“快指针” 每次走两步,“慢指针” 每次走一步,当二者相等时,即为一个循环周期。此时,判断是不是因为 1 引起的循环,是的话就是快乐数,否则不是快乐数。

// An highlighted block
int count(int n){
    int res = 0;
    int a=0;
    while(n){
        a = n%10;
        n = n/10;
        res += a*a;
    }
    return res;
}


bool isHappy(int n){
    int fast = n,slow = n;
    do{
        slow = count(slow);
        fast = count(fast);
        fast = count(fast);
    }while(slow != fast);
    return (slow == 1);
}


4.各位相加

在这里插入图片描述
思路:循环判断是否>10(个位数判断),内层循环用来处理数字相加

// An highlighted block
int addDigits(int num){
    while (num >= 10) {
        int sum = 0;
        while (num > 0) {
            sum += num % 10;
            num /= 10;
        }
        num = sum;
    }
    return num;
}

5.丑数

在这里插入图片描述
思路:对 n 反复除以 2,3,5直到 n 不再包含质因数 2,3,5。若剩下的数等于1 ,则说明 n 不包含其他质因数,是丑数;否则,说明 n包含其他质因数,不是丑数。

// An highlighted block
bool isUgly(int n) {
    if (n <= 0) {
        return false;
    }
    int factors[] = {2, 3, 5};
    for (int i = 0; i < 3; i++) {
        while (n % factors[i] == 0) {
            n /= factors[i];
        }
    }
    return n == 1;
}

6.是否是a的幂

判断一个数是否是a的幂,如27=3^3

// An highlighted block
    int isPowerOfThree(int n,int a) {
        while (n && n % a == 0) {
            n /= a;
        }
        return n == 1;
    }


7.完美数

对于一个 正整数,如果它和除了它自身以外的所有 正因子 之和相等,我们称它为 「完美数」
例子:28 = 1 + 2 + 4 + 7 + 14
思路:枚举法,只需要枚举到a的开根,另一个=a/d

bool checkPerfectNumber(int num){
    if (num == 1) {
        return false;
    }

    int sum = 1;
    for (int d = 2; d * d <= num; ++d) {
        if (num % d == 0) {
            sum += d;
            if (d * d < num) {
                sum += num / d;
            }
        }
    }
    return sum == num;
}



8.自除数

自除数 是指可以被它包含的每一位数整除的数。
自除数 不允许包含 0 。
给定两个整数 left 和 right ,返回一个列表,列表的元素是范围 [left, right] 内所有的 自除数 。
例子:128 是一个 自除数 ,因为 128 % 1 == 0,128 % 2 == 0,128 % 8 == 0。

bool isSelfDividing(int num) {
    int temp = num;
    while (temp > 0) {
        int digit = temp % 10;
        if (digit == 0 || num % digit != 0) {
            return false;
        }
        temp /= 10;
    }
    return true;
}

int* selfDividingNumbers(int left, int right, int* returnSize){
    int * ans = (int *)malloc(sizeof(int) * (right - left + 1));
    int pos = 0;
    for (int i = left; i <= right; i++) {
        if (isSelfDividing(i)) {
            ans[pos++] = i;
        }
    }
    *returnSize = pos;
    return ans;
}



9.三角形最长周长

给定数组,判断里面数字所能组成的周长最长的三角形
贪心 + 排序:选择枚举三角形的最长边 c,而从贪心的角度考虑,我们一定是选「小于 ccc 的最大的两个数」作为边长 a和 b,此时最有可能满足 a+b>c,使得三条边能够组成一个三角形,且此时的三角形的周长是最大的。


int largestPerimeter(int *A, int ASize) {
    sort(A);//自己写排序
    for (int i = ASize - 1; i >= 2; --i) {
        if (A[i - 2] + A[i - 1] > A[i]) {
            return A[i - 2] + A[i - 1] + A[i];
        }
    }
    return 0;
}



10.一年中的第几天


int dayOfYear(char * date){
    int year = atoi(date);
    int month = atoi(date + 5);
    int day = atoi(date + 8);
    int amount[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
        ++amount[1];
    }
    int ans = 0;
    for (int i = 0; i < month - 1; ++i) {
        ans += amount[i];
    }
    return ans + day;
}

11.一周的第几天

输入的日期一定是在 1971 到 2100 年之间的有效日期,1970 年 12月 31 日是星期四
思路:计算出到1970 年 12月 31 日间隔天数days,(days+3)%7 因为数组从0开始
对于单位年要判断间隔中有几个闰年,对于单位月要判断是否是闰年2月



char * dayOfTheWeek(int day, int month, int year){
    char * week[7] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
    int monthDays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30};
    /* 输入年份之前的年份的天数贡献  每4年有一个366天。1969/4=1,是最近的新一轮开始*/
    int days = 365 * (year - 1971) + (year - 1969) / 4;
    /* 输入年份中,输入月份之前的月份的天数贡献 */
    for (int i = 0; i < month - 1; ++i) {
        days += monthDays[i];
    }
    if ((year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) && month >= 3) {
        days += 1;
    }
    /* 输入月份中的天数贡献 */
    days += day;
    return week[(days + 3) % 7];
}

12.下周的日期

思路:1.闰年判断。2.+7后是否超过当月,当月加1后是否超过当年

int monthDays[13] = {0,31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30};//第一位舍弃,让月份与下标对应

if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))  {
	monthDays[2]=29;
	
if(day+7>monthDays[month]){
	day=day+7-monthDays[month];
	if(month+1>12){year++;month=1;}
	else month++;
	
}



13.打印杨辉三角

思路:先对特殊位置:每行第一个元素a[i][0]和最后一个元素a[i][i],赋值1;其他位置遍历矩阵,核心语句,a[i][j]=a[i-1][j]+a[i][j-1];

int a[n][n];
int i=0,j=0;
for(i=0;i<n;i++)}{
	for(j=0;j<=i;j++){
		if(j=0||j==i) a[i][j]=1;
		else if(i>1) a[i][j]=a[i-1][j-1]+a[i-1][j];
		print("%d",a[i][j]);
		}
	}

14.两个数的最小公倍数和最大公约数

思路:最大公约数:辗转相除法。最小公倍数a*b/最大公约数

int temp=0
if(a<b){//对保证a一定大于b
	temp=a;
	a=b;
	b=temp;
}
while(b!=0){
	r=a%b;
	a=b;
	b=r;
}
return a;
//若是最小公倍数,开始时 int c=a*b;最后 return c/a;

15.三除数

给你一个整数 n 。如果 n 恰好有三个正除数 ,返回 true ;否则,返回 false 。
例子:4 有三个除数:1、2 和 4 。

bool isThree(int n) {
    int sum=0;
    for(int i=1;i*i<=n;i++)
    {
        if(n%i==0)
        {
                if (i != n / i){
                    // 此时 i 与 n / i 为不同整数
                    sum += 2;
                }
                else{
                    // 此时 i 与 n / i 相等
                    sum += 1;
                }
		}
    }
return (sum==3);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值