[leetcode] 数字游戏

时间:2022-04-28 20:59:20

169. Majority Element

Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.

You may assume that the array is non-empty and the majority element always exist in the array.

Credits:
Special thanks to @ts for adding this problem and creating all test cases.

public class Solution {
public int majorityElement(int[] nums) {
int candidate = 0;
int count = 0;
for (int num : nums) {
if (count == 0) {
candidate = num;
count = 1;
} else if (candidate == num) {
count++;
} else {
count--;
}
}
return candidate;
}
}

229. Majority Element II

Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorithm should run in linear time and in O(1) space.

Hint:

  1. How many majority elements could it possibly have?

Do you have a better hint? Suggest it!

public class Solution {
public List<Integer> majorityElement(int[] nums) {
int candidate1 = 0, candidate2 = 0;
int count1 = 0, count2 = 0;
for (int num : nums) {
if (candidate1 == num) {
count1++;
} else if (candidate2 == num) {
count2++;
} else if (count1 == 0) {
candidate1 = num;
count1 = 1;
} else if (count2 == 0) {
candidate2 = num;
count2 = 1;
} else {
count1--;
count2--;
}
}
List<Integer> result = new ArrayList<Integer>();
int length = nums.length;
/*
if (count1 == 0 && count2 == 0) {
return result;
} else if (count1 > 0 && count2 == 0) {
result.add(candidate1);
return result;
} else if (count2 > 0 && count1 == 0) {
result.add(candidate2);
return result;
}*/
count1 = 0;
count2 = 0;
for (int num : nums) {
if (num == candidate1) {
count1++;
} else if (num == candidate2) {
count2++;
}
}
if (count1 > length / 3) {
result.add(candidate1);
}
if (count2 > length / 3) {
result.add(candidate2);
}
return result;
}
}

254. Factor Combinations

Numbers can be regarded as product of its factors. For example,

8 = 2 x 2 x 2;
= 2 x 4.

Write a function that takes an integer n and return all possible combinations of its factors.

Note:

  1. You may assume that n is always positive.
  2. Factors should be greater than 1 and less than n.

Examples: 
input: 1
output:

[]

input: 37
output:

[]

input: 12
output:

[
[2, 6],
[2, 2, 3],
[3, 4]
]

input: 32
output:

[
[2, 16],
[2, 2, 8],
[2, 2, 2, 4],
[2, 2, 2, 2, 2],
[2, 4, 4],
[4, 8]
]
public class Solution {
public List<List<Integer>> getFactors(int n) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
List<Integer> rList = new ArrayList<Integer>();
if (n < 2) {
return result;
}
helper(n, 2, rList, result);
//System.out.println(result.toString());
return result;
}
private void helper(int n, int start, List<Integer> rList, List<List<Integer>> result) {
int size = rList.size();
int limit = (int)(Math.floor(Math.sqrt(n)));
boolean flag = false;
for (int i = start; i <= limit; i++) {
if (n % i == 0) {
flag = true;
rList.add(i);
helper(n / i, i, rList, result);
rList.remove(size);
}
}
List<Integer> newList = new ArrayList<Integer>(rList);
if (!rList.isEmpty()) {
newList.add(n);
result.add(newList);
}
}
}

258. Add Digits

Given a non-negative integer num, repeatedly add all its digits until the result has only one digit.

For example:

Given num = 38, the process is like: 3 + 8 = 111 + 1 = 2. Since 2 has only one digit, return it.

Follow up:
Could you do it without any loop/recursion in O(1) runtime?

Hint:

    1. A naive implementation of the above process is trivial. Could you come up with other methods?
    2. What are all the possible results?
    3. How do they occur, periodically or randomly?
    4. You may find this Wikipedia article useful.
public class Solution {
public int addDigits(int num) {
if (num == 0) {
return 0;
}
return num - 9 * ((num - 1) / 9);
}
}

264. Ugly Number II

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.

Hint:

  1. The naive approach is to call isUgly for every number until you reach the nth one. Most numbers are not ugly. Try to focus your effort on generating only the ugly ones.
  2. An ugly number must be multiplied by either 2, 3, or 5 from a smaller ugly number.
  3. The key is how to maintain the order of the ugly numbers. Try a similar approach of merging from three sorted lists: L1, L2, and L3.
  4. Assume you have Uk, the kth ugly number. Then Uk+1 must be Min(L1 * 2, L2 * 3, L3 * 5).
public class Solution {
public int nthUglyNumber(int n) {
int[] result = new int[n];
int c1 = 0, c2 = 0, c3 = 0;
result[0] = 1;
for (int i = 1; i < n; i++) {
int x1 = result[c1] * 2;
int x2 = result[c2] * 3;
int x3 = result[c3] * 5;
int x = Math.min(x1, x2);
x = Math.min(x, x3);
result[i] = x;
if (x == x1) c1++;
if (x == x2) c2++;
if (x == x3) c3++;
}
return result[n - 1];
}
}

277. Find the Celebrity

Suppose you are at a party with n people (labeled from 0 to n - 1) and among them, there may exist one celebrity. The definition of a celebrity is that all the other n - 1 people know him/her but he/she does not know any of them.

Now you want to find out who the celebrity is or verify that there is not one. The only thing you are allowed to do is to ask questions like: "Hi, A. Do you know B?" to get information of whether A knows B. You need to find out the celebrity (or verify there is not one) by asking as few questions as possible (in the asymptotic sense).

You are given a helper function bool knows(a, b) which tells you whether A knows B. Implement a function int findCelebrity(n), your function should minimize the number of calls to knows.

Note: There will be exactly one celebrity if he/she is in the party. Return the celebrity's label if there is a celebrity in the party. If there is no celebrity, return -1.

/* The knows API is defined in the parent class Relation.
boolean knows(int a, int b); */ public class Solution extends Relation {
public int findCelebrity(int n) {
int start = 0;
int end = n - 1;
while (start < end) {
if (knows(start, end)) {
start++;
} else {
end--;
}
}
for (int i = 0; i < start; i++) {
if (!knows(i, start) || knows(start, i)) {
return -1;
}
}
for (int i = start + 1; i < n; i++) {
if (!knows(i, start) || knows(start, i)) {
return -1;
}
}
return start;
}
}

279. Perfect Squares

Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...) which sum to n.

For example, given n = 12, return 3 because 12 = 4 + 4 + 4; given n = 13, return 2 because 13 = 4 + 9.

public class Solution {
public int numSquares(int n) {
while(n % 4 == 0){
n = n / 4;
}
if(n % 8 == 7){
return 4;
}
int limit = (int)Math.floor(Math.sqrt(n));
int tmp = n - limit * limit;
if(tmp == 0){
return 1;
}
for(int i = 1; i <= limit; i++){
int remain = n - i * i;
int y = (int)Math.floor(Math.sqrt(remain));
if(remain == y * y){
return 2;
}
}
return 3;
}
}
public class Solution {
public int numSquares(int n) {
int[] store = new int[n + 1];
int limit = (int)Math.floor(Math.sqrt(n));
for(int i = 1; i <= limit; i++){
store[i * i] = 1;
}
for(int i = 0; i <= n; i++){
store[i] = Integer.MAX_VALUE;
}
store[0] = 0;
for(int i = 0; i <= n; i++){
for(int j = 1; i + j * j <= n; j++){
int tmp = i + j * j;
int x = store[i] + 1;
int y = store[tmp];
store[tmp] = x < y ? x : y;
}
}
return store[n];
}
}

292. Nim Game

You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will be the winner. You will take the first turn to remove the stones.

Both of you are very clever and have optimal strategies for the game. Write a function to determine whether you can win the game given the number of stones in the heap.

For example, if there are 4 stones in the heap, then you will never win the game: no matter 1, 2, or 3 stones you remove, the last stone will always be removed by your friend.

Hint:

  1. If there are 5 stones in the heap, could you figure out a way to remove the stones such that you will always be the winner?

311. Sparse Matrix Multiplication

Given two sparse matrices A and B, return the result of AB.

You may assume that A's column number is equal to B's row number.

Example:

A = [
[ 1, 0, 0],
[-1, 0, 3]
] B = [
[ 7, 0, 0 ],
[ 0, 0, 0 ],
[ 0, 0, 1 ]
] | 1 0 0 | | 7 0 0 | | 7 0 0 |
AB = | -1 0 3 | x | 0 0 0 | = | -7 0 3 |
| 0 0 1 |
public class Solution {
public int[][] multiply(int[][] A, int[][] B) {
int m1 = A.length;
int n1 = A[0].length;
int m2 = B.length;
int n2 = B[0].length;
int[][] result = new int[m1][n2];
for (int i = 0; i < m1; i++) {
for (int j = 0; j < n1; j++) {
if (A[i][j] != 0) {
for (int k = 0; k < n2; k++) {
result[i][k] += A[i][j] * B[j][k];
}
}
}
}
return result;
}
}

334. Increasing Triplet Subsequence

Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the array.

Formally the function should:

Return true if there exists i, j, k 
such that arr[i] < arr[j] < arr[k] given 0 ≤ i < j < k ≤ n-1 else return false.

Your algorithm should run in O(n) time complexity and O(1) space complexity.

Examples:
Given [1, 2, 3, 4, 5],
return true.

Given [5, 4, 3, 2, 1],
return false.

public class Solution {
public boolean increasingTriplet(int[] nums) {
int min1 = Integer.MAX_VALUE;
int min2 = Integer.MAX_VALUE;
for (int num : nums) {
if (num <= min1) {
min1 = num;
} else if (num <= min2) {
min2 = num;
} else {
return true;
}
}
return false;
}
}

386. Lexicographical Numbers

Given an integer n, return 1 - n in lexicographical order.

For example, given 13, return: [1,10,11,12,13,2,3,4,5,6,7,8,9].

Please optimize your algorithm to use less time and space. The input size may be as large as 5,000,000.

public class Solution {
public List<Integer> lexicalOrder(int n) {
List<Integer> result = new ArrayList<Integer>(n);
int x = 1;
for (int i = 0; i < n; i++) {
result.add(x);
if (x * 10 <= n) {
x = x * 10;
} else {
if (x == n) {
x /= 10;
}
x++;
while (x % 10 == 0) {
x /= 10;
}
}
}
return result;
}
}