leecode 解题总结:264. Ugly Number II

本文介绍了一种高效算法来找出第N个丑数。丑数是指只包含2、3和5这三个质因数的正整数。文章通过使用三个指针的方法避免了重复计算,并确保不会遗漏任何丑数。
#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
using namespace std;
/*
问题:
Write a program to find the n-th ugly number.

Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For example, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers.

Note that 1 is typically treated as an ugly number, and n does not exceed 1690.

分析:实际上是求第n个丑数,丑数从1开始。
我们假设当前丑数候选者为{2,3,5},如何从当前候选者中确定下一个丑数,
可以将候选丑数去乘以2,乘以3,乘以5,选择其中最小的
比如{2,3,5}都乘以2{4,6,10} 从这个里面选择一个最小的作为a
                 3{6,9,15}                             b
				 5{10,15,25}                           c
				 从{a,b,c}中选择最小的作为丑数,假设为a,更新每一个候选丑数,使得候选丑数>a,候选丑数变成{ , b,c}
				 更一般的情况当前丑数为{a,b,c},如何产生下一个丑数,

输出:
1
2
3
4
5

6
7
8
9
10

1690
输出:
1
2
3
4
5

6
8
9
10
12

关键:
1 丑数=三指针问题。需要设定一个指针不断指向已经生成的丑数序列,第一个指针指向的数字用于每次乘以3和
当前丑数比较;第二个指针指向的数字每次乘以5和当前丑数比较;第三个指针指向的数字乘以5和当前丑数
比较。避免丢失某些丑数
2每次选取3个候选丑数中的最小值,然后更新3个指针使其指向的数乘以对应的2或3或5
都大于当前丑数。候选丑数也是从3个指针分别乘以2,3,5来计算

3溢出错误
while(uglyNums.at(index2) * 2 <= cand)
{
	index2++;
}

vector<long long> uglyNums;//防止乘以2或3或5后溢出,所以用long long
*/

class Solution {
public:
	int minNum(int a, int b, int c)
	{
		return min( min(a,b) , min(b,c) );
	}

    int nthUglyNumber(int n) {
		//前5个丑数就是该数字本身
		if(n <= 0)
		{
			return 0;
		}
		vector<long long> uglyNums;//防止乘以2或3或5后溢出,所以用long long
		uglyNums.push_back(1);
		int index2 = 0;//用于乘以2的丑数指针
		int index3 = 0;
		int index5 = 0;
		int count = 0;
		while(count < n)
		{
			long long cand = minNum(uglyNums.at(index2) * 2 , uglyNums.at(index3) * 3 , uglyNums.at(index5) * 5 );
			//压入当前丑数
			uglyNums.push_back(cand);
			while(uglyNums.at(index2) * 2 <= cand)
			{
				index2++;
			}
			while(uglyNums.at(index3) * 3 <= cand)
			{
				index3++;
			}
			while(uglyNums.at(index5) * 5 <= cand)
			{
				index5++;
			}
			count++;
		}
		if(uglyNums.empty())
		{
			return 0;
		}
		else
		{
			return  uglyNums.at(n-1);
		}
    }
};

void print(vector<int>& result)
{
	if(result.empty())
	{
		cout << "no result" << endl;
		return;
	}
	int size = result.size();
	for(int i = 0 ; i < size ; i++)
	{
		cout << result.at(i) << " " ;
	}
	cout << endl;
}

void process()
{
	 int num;
	 Solution solution;
	 while(cin >> num )
	 {
		 int result = solution.nthUglyNumber(num);
		 cout << result << endl;
	 }
}

int main(int argc , char* argv[])
{
	process();
	getchar();
	return 0;
}


多源数据接入 支持校园各业务系统数据接入:包括教务系统(学生成绩、课程信息)、学工系统(奖惩记录、资助信息)、后勤系统(宿舍分配、能耗数据)、图书馆系统(借阅记录、馆藏信息)、一卡通系统(消费数据、门禁记录)等。 接入方式:提供数据库直连(MySQL、SQL Server)、文件导入(CSV、Excel、JSON)、API 接口调用等多种方式,支持实时同步与定时批量同步。 数据标准化与治理 建立校园数据标准体系:统一数据格式(如日期格式、学号编码规则)、定义核心数据元(如 “学生” 包含学号、姓名、专业等必选字段)、规范代码集(如性别代码 “1 - 男,2 - 女”)。 数据清洗:自动检测并处理缺失值、重复值、异常值(如成绩 > 100 分),通过规则引擎实现数据校验(如 “学生年龄需在 16-30 岁之间”)。 元数据管理:记录数据来源、格式、更新频率、负责人等信息,生成数据血缘图谱,追踪数据从产生到应用的全生命周期。 二、数据共享与交换核心功能 分布式数据存储 基于 Hadoop HDFS 实现海量数据存储:结构化数据(成绩、消费记录)存入 HBase,非结构化数据(文档、图片、视频)直接存储于 HDFS,日志类数据通过 Flume 采集至 HDFS。 支持数据分片与副本机制,确保数据高可用(默认 3 副本存储),满足校园 PB 级数据存储需求。 数据交换引擎 构建点对点数据交换通道:各部门系统可通过交换引擎向平台上传数据或申请获取授权数据,支持同步 / 异步交换模式。 交换流程管理:定义数据交换规则(如 “学工系统每日向平台同步新增学生信息”),记录交换日志(成功 / 失败状态、数据量),失败时自动重试。 数据脱敏:对敏感数据(如身份证号、银行卡号)在交换过程中进行脱敏处理(如显示 “110********5678”),兼顾共享与隐私保护。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值