需要开通vip的题目暂时跳过
点击链接可跳转到所有刷题笔记的导航链接
编写一个程序判断给定的数是否为丑数。
丑数就是只包含质因数 2, 3, 5 的正整数。
解答
public boolean isUgly(int num) {
if(num <= 0)return false;
if(num == 1)return true;
if(num % 5 == 0)return isUgly(num/5);
if(num % 3 == 0)return isUgly(num/3);
if(num % 2 == 0)return isUgly(num/2);
return false;
}
分析
提交结果
编写一个程序,找出第 n
个丑数。
丑数就是质因数只包含 2, 3, 5
的正整数。
//方法一
public int nthUglyNumber(int n) {
long[] ugly = new long[1690];
PriorityQueue<Long> queue = new PriorityQueue<>();
HashSet<Long> set = new HashSet<>();
queue.add(1L);
set.add(1L);
int[] numbers = {
2,3,5};
for(int i = 0;i < 1690;i++){
long current = queue.poll();
ugly[i] = current;
for(int number : numbers){
if(!set.contains(current * number)){
set.add(current*number);
queue.add(current*number);
}
}
}
return (int)ugly[n-1];
}
//方法二
class Ugly {
public int[] nums = new int[1690];
Ugly() {
HashSet<Long> seen = new HashSet();
PriorityQueue<Long> heap = new PriorityQueue<Long>();
seen.add(1L);
heap.add(1L);
long currUgly, newUgly;
int[] primes = new int[]{
2, 3, 5};
for(int i = 0; i < 1690; ++i) {
currUgly = heap.poll();
nums[i] = (int)currUgly;
for(int j : primes) {
newUgly = currUgly * j;
if (!seen.contains(newUgly)) {
seen.add(newUgly);
heap.add(newUgly);
}
}
}
}
}
class Solution {
public static Ugly u = new Ugly();
public int nthUglyNumber(int n) {
return u.nums[n - 1];
}
}
//方法三
class Ugly{
int[] numbers = new int[1690];
Ugly(){
numbers[0] = 1;
int i2 = 0,i3 = 0,i5 = 0;
int ugly = 1;
for(int i = 1;i<1690;i++){
ugly = Math.min(Math.min(numbers[i2] * 2,numbers[i3] * 3),numbers[i5]*5);
numbers[i] = ugly;
if(ugly == numbers[i2]*2) ++i2;
if(ugly == numbers[i3]*3) ++i3;
if(ugly == numbers[i5]*5) ++i5;
}
}
}
class Solution {
public int nthUglyNumber(int n) {
Ugly ugly = new Ugly();
return ugly.numbers[n-1];
}
}
分析
提交结果
给定一个包含 0, 1, 2, ..., n
中 n 个数的序列,找出 0 … n 中没有出现在序列中的那个数。
解答
//方法一
public int missingNumber(int[] nums) {
Arrays.sort(nums);
int len = nums.length;
for(int i = 0;i<len;i++){
if(i != nums[i])return i;
}
return len;
}
// 方法二
public int missingNumber(int[] nums) {
int len = nums.length;
int numbers[] = new int[len + 1];
for(int i = 0;i<len;i++){
numbers[nums[i]] = 1;
}
for(int i = 0;i < len + 1;i++){
if(numbers[i] == 0)return i;
}
return -1;
}
//方法三
public int missingNumber(int[] nums) {
int len = nums.length;
int res = len;
for(int i = 0;i<len;i++){
res = res^i^nums[i];
}
return res;
}
分析
提交结果
方法一
方法二
方法三
将非负整数转换为其对应的英文表示。可以保证给定输入小于 231 - 1 。
public String one(int num) {
switch(num) {
case 1: return "One";
case 2: return "Two";
case 3: return "Three";
case 4: return "Four";
case 5: return "Five";
case 6: return "Six";
case 7: return "Seven";
case 8: return "Eight";
case 9: return "Nine";
}
return "";
}
public String twoLessThan20(int num) {
switch(num) {
case 10: return "Ten";
case 11: return "Eleven";
case 12: return "Twelve";
case 13: return "Thirteen";
case 14: return "Fourteen";
case 15: return "Fifteen";
case 16: return "Sixteen";
case 17: return "Seventeen";
case 18: return "Eighteen";
case 19: return "Nineteen";
}
return "";
}
public String ten(int num) {
switch(num) {
case 2: return "Twenty";
case 3: return "Thirty";
case 4: return "Forty";
case 5: return "Fifty";
case 6: return "Sixty";
case 7: return "Seventy";
case 8: return "Eighty";
case 9: return "Ninety";
}
return "";
}
public String two(int num) {
if (num == 0)
return "";
else if (num < 10)
return one(num);
else if (num < 20)
return twoLessThan20(num);
else {
int tenner = num / 10;
int rest = num - tenner * 10;//个位数
if (rest != 0)
return ten(tenner) + " " + one(rest);
else
return ten(tenner);
}
}
public String three(int num) {
int hundred = num / 100;//百位数
int rest = num - hundred * 100;//个位十位
String res = "";
if (hundred * rest != 0)
res = one(hundred) + " Hundred " + two(rest);
else if ((hundred == 0) && (rest != 0))
res = two(rest);
else if ((hundred != 0) && (rest == 0))
res = one(hundred) + " Hundred";
return res;
}
public String numberToWords(int num) {
if (num == 0)
return "Zero";
int billion = num / 1000000000;
int million = (num - billion * 1000000000) / 1000000;
int thousand = (num - billion * 1000000000 - million * 1000000) / 1000;
int rest = num - billion * 1000000000 - million * 1000000 - thousand * 1000;
String result = "";
if (billion != 0)
result = three(billion) + " Billion";
if (million != 0) {
if (! result.isEmpty())
result += " ";
result += three(million) + " Million";
}
if (thousand != 0) {
if (! result.isEmpty())
result += " ";
result += three(thousand) + " Thousand";
}
if (rest != 0) {
if (! result.isEmpty())
result += " ";
result += three(rest);
}
return result;
}
分析
提交结果
给定一位研究者论文被引用次数的数组(被引用次数是非负整数)。编写一个方法,计算出研究者的 h 指数。
h 指数的定义:h 代表“高引用次数”(high citations),一名科研人员的 h 指数是指他(她)的 (N 篇论文中)总共有 h 篇论文分别被引用了至少 h 次。(其余的 N - h 篇论文每篇被引用次数 不超过 h 次。)
例如:某人的 h 指数是 20,这表示他已发表的论文中,每篇被引用了至少 20 次的论文总共有 20 篇。
public int hIndex(int[] citations) {
Arrays.sort(citations);
int len = citations.length;
for(int i = 0;i < len;i++){
int number = Math.min(citations[i],len-i);
if(number == len-i)
return number;
}
return 0;
}
分析
给定一位研究者论文被引用次数的数组(被引用次数是非负整数),数组已经按照升序排列。编写一个方法,计算出研究者的 h 指数。
h 指数的定义: “h 代表“高引用次数”(high citations),一名科研人员的 h 指数是指他(她)的 (N 篇论文中)总共有 h 篇论文分别被引用了至少 h 次。(其余的 N - h 篇论文每篇被引用次数不多于 h 次。)"
public int hIndex(int[] citations) {
int len = citations.length;
if(len == 0) return 0;
int left = 0;
int right = len-1;
while(left <= right){
int mid = (left+right)/2;
if(citations[mid] == len - mid)return len - mid;
if(citations[mid] < len - mid)left = mid + 1;
else right = mid - 1;
}
return len - left;
}
分析
提交结果
你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。
假设你有 n 个版本 [1, 2, …, n],你想找出导致之后所有版本出错的第一个错误的版本。
你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
int left = 1;
int right = n;
while(left <= right){
int mid = left + (right-left)/2;
if(isBadVersion(mid))right = mid-1;
else left = mid + 1;
}
return left;
}
}
给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...
)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
public int numSquares(int n) {
if(n<=3)return n;
int[] dp = new int[n + 1];
for (int i = 0; i < n + 1; i++) {
dp[i] = Integer.MAX_VALUE;
}
dp[0] = 0;
dp[1] = 1;
dp[2] = 2;
dp[3] = 3;
int[] sqares = new int[(int) Math.sqrt(n)];
for (int i = 0; i < sqares.length; i++) {
sqares[i] = (int) Math.pow(i + 1, 2);
}
for (int i = 4; i <= n; i++) {
for (int j = 0; j < sqares.length; j++) {
if (i - sqares[j] >= 0)
dp[i] = Math.min(dp[i - sqares[j]] + 1, dp[i]);
}
}
return dp[n];
}
//方法二
Set<Integer> square_nums = new HashSet<Integer>();
protected boolean is_divided_by(int n, int count) {
if (count == 1) {
return square_nums.contains(n);
}
for (Integer square : square_nums) {
if (is_divided_by(n - square, count - 1)) {
return true;
}
}
return false;
}
public int numSquares(int n) {
square_nums.clear();
for (int i = 1; i * i <= n; ++i) {
square_nums.add(i * i);
}
int count = 1;
for (; count <= n; ++count) {
if (is_divided_by(n, count))
return count;
}
return count;
}
//方法三
public int numSquares(int n) {
Set<Integer> squares = new HashSet<>();
for(int i = 1; i*i <= n;i++){
squares.add(i*i);
}
Set<Integer> queue = new HashSet<>();
queue.add(n);
int res = 0;
while(!queue.isEmpty()){
res++;
Set<Integer> nextQueue = new HashSet<>();
for(Integer remain:queue){
for(Integer square:squares){
if(remain - square == 0)return res;
if(remain -square < 0)continue;
nextQueue.add(remain - square);
}
}
queue = nextQueue;
}
return res;
}