细节实现题
7 Reverse Integer Easy
Given a 32-bit signed integer, reverse digits of an integer.
Example 1:
Input: 123
Output: 321
Example 2:
Input: -123
Output: -321
Example 3:
Input: 120
Output: 21
Note:
Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231, 231 − 1]. For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.
倒转数字:%与/
情况:
- 负数
- 特例-2147483648
- 倒转后在-2147483648~2147483647之外
class Solution {
public int reverse(int x) {
if(x == -2147483648) {
return 0;
}
long num = x>0 ? x : -x; // 绝对值
long temp = 0;
while(num!=0) {
temp *=10;
temp += num%10;
num /= 10;
}
if(x>0 && temp <= 2147483647) {
return (int)temp;
}
if(x<0 && temp <= 2147483648L) {
return (int)-temp;
}
return 0;
}
}
几何问题
836 Rectangle Overlap Easy
题意:判断两个矩形是否相交
思路:考虑不相交的情况:矩形2在矩形1的左边或右边,矩形2在矩形1的上边或下边。
class Solution {
public boolean isRectangleOverlap(int[] rec1, int[] rec2) {
if(rec2[2] <= rec1[0] || rec2[0] >= rec1[2]) {
// rec2在rec1左边或右边
return false;
}
if(rec2[1] >= rec1[3] || rec2[3] <= rec1[1]) {
// rec2在rec1上边或下边
return false;
}
return true;
}
}
223 Rectangle Area Medium
题意:两个矩形占据的总面积
思路:
两个矩形相交时,占据的总面积 = 矩形1面积+矩形1面积+相交的面积;
两个矩形不相交时,占据的总面积 = 矩形1面积+矩形1面积。
class Solution {
public int computeArea(int A, int B, int C, int D, int E, int F, int G, int H) {
int S1 = (C-A)*(D-B);
int S2 = (G-E)*(H-F);
if(S1 == 0) {
return S2;
}
if(S2 == 0) {
return S1;
}
int W,L;
if(E>=C || G<=A) {
// 横向不相交
W = 0;
} else {
W = Math.min(C,G) - Math.max(A,E);
}
if(B>=H || D<=F) {
// 纵向不相交
L = 0;
} else {
L = Math.min(D,H) - Math.max(B,F);
}
return S1+S2-W*L;
}
}
无分类
292 Nim Game(尼姆游戏) Easy
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.
关键:每个人都取不到4个
如果到最后留4个下来,对方取1个你就取3个,对方取2个你就取2个,对方取3个你就取1个,必赢。
第一步走时,把n除4的余数个石头拿走。
后面每一步走时,上一步对方取x个,你就取4-x个,保证每轮双方取得数量之和是4,这样就能确保最后各差一步时剩4个石头。
因此当一开始石头总数就是4的倍数时,你不能一开始取0个,对方使用上述相同策略,则你必输。
class Solution {
public:
bool canWinNim(int n) {
return n%4!=0;
}
};
371 Sum of Two Integers Easy
Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -. Example: Given a = 1 and b = 2, return 3.
关键:位运算
详解:www.tuicool.com/articles/am…
class Solution {
public:
int getSum(int a, int b) {
}
};
204 Count Primes Easy
Description: Count the number of prime numbers less than a non-negative number, n.
暴力法:逐个判断是否为素数,进行计数。时间复杂度。 但是,该方法会超时!
class Solution {
public int countPrimes(int n) {
int cnt = 0;
for(int i = 2; i<n; i++) {
if(isPrime(i)) {
cnt++;
}
}
return cnt;
}
public boolean isPrime(int n) {
for(int i = 2; i<n; i++) {
if(n%i == 0) {
return false;
}
}
return true;
}
}
埃氏筛 Sieve of Eratosthenes:用来找出一定范围内所有的素数 原理:从2开始,将每个素数的各个倍数,标记成合数(不需要判断素数的操作了~!)
class Solution {
public int countPrimes(int n) {
boolean[] isPrimes = new boolean[n];
Arrays.fill(isPrimes, true);
for(int i=2; i<=Math.sqrt(n); i++) {
if(isPrimes[i]) {
int mul = 2;
int num = i*mul;
while(num<n) {
isPrimes[num] = false;
num = i*(++mul);
}
}
}
int cnt = 0;
for(int i = 2; i<n; i++) {
if(isPrimes[i]) {
cnt++;
}
}
return cnt;
}
}
263 Ugly Number Easy
Write a program to check whether a given number is an ugly number. Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For example, 6, 8 are ugly while 14 is not ugly since it includes another prime factor 7. Note that 1 is typically treated as an ugly number.
题意:判断一个数是否为ugly number(质因数只有2 3 5的正数)
想法:顺着上一题,先找到比这个数小的所有质数,然后从7开始依次看这些质数能否整除这个数。 但是,会超时!
正确的方法:不停的除以2 3 5这些质数,如果可以整除到1就是ugly number。
class Solution {
public boolean isUgly(int num) {
if (num == 1) {
return true;
}
if (num <= 0) {
return false;
}
while(num>=2) {
if (num%2 == 0) {
num/=2;
} else if (num%3 == 0) {
num/=3;
} else if (num%5 == 0) {
num/=5;
} else {
return false;
}
}
return true;
}
}
264 Ugly Number II Medium
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个ugly number(质因数只有2 3 5的正数)
思路:
uglyNumbers:1 2 3 4 5 6 8 9 10 12 15 ……
L1:2*uglyNumber
L2:3*uglyNumber
L3:5*uglyNumber
每个L中的uglyNumber从1开始在uglyNumbers中遍历
uglyNumbers中的下一个数永远是L1 L2 L3当前数中最小的一个(注意:最小的可能不止一个,都需要做处理),然后对应的uglyNumber要改为下一个
例子:
(1) 1x2, 2x2, 2x2, 3x2, 3x2, 4x2, 5x2...
(2) 1x3, 1x3, 2x3, 2x3, 2x3, 3x3, 3x3...
(3) 1x5, 1x5, 1x5, 1x5, 2x5, 2x5, 2x5...
class Solution {
public int nthUglyNumber(int n) {
List<Integer> uglyNumbers = new ArrayList<>();
uglyNumbers.add(new Integer(1));
int index_L1 = 0;
int index_L2 = 0;
int index_L3 = 0;
int[] waitNums = new int[3];
waitNums[0] = 2 * (int)uglyNumbers.get(index_L1);
waitNums[1] = 3 * (int)uglyNumbers.get(index_L2);
waitNums[2] = 5 * (int)uglyNumbers.get(index_L3);
while (uglyNumbers.size() < n) {
int min = minInArray(waitNums);
if(waitNums[0] == min) {
if (min != (int)uglyNumbers.get(uglyNumbers.size()-1)) {
uglyNumbers.add(new Integer(min));
}
waitNums[0] = 2 * (int)uglyNumbers.get(++index_L1);
}
if(waitNums[1] == min) {
if (min != (int)uglyNumbers.get(uglyNumbers.size()-1)) {
uglyNumbers.add(new Integer(min));
}
waitNums[1] = 3 * (int)uglyNumbers.get(++index_L2);
}
if(waitNums[2] == min) {
if (min != (int)uglyNumbers.get(uglyNumbers.size()-1)) {
uglyNumbers.add(new Integer(min));
}
waitNums[2] = 5 * (int)uglyNumbers.get(++index_L3);
}
}
return (int)uglyNumbers.get(n-1);
}
public int minInArray(int[] nums) {
int[] temp = new int[3];
temp = Arrays.copyOf(nums,nums.length);
Arrays.sort(temp);
return temp[0];
}
}
202 Happy Number Easy
Write an algorithm to determine if a number is "happy".
A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers.
Example: 19 is a happy number
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
思路:
随便找一个数尝试计算一下,会发现,不是happy number的数,计算出的中间数会重复出现,所以说会loops endlessly in a cycle。
因此,算到1判断为happy number,算到出现先前出现过的数,判断为非happy number。
取每一位数的方法:% + /
集合类库:HashSet(最简单的集合,没有重复元素)
class Solution {
public boolean isHappy(int n) {
Set<Integer> set = new HashSet<>();
while (n!=1) {
int squareSum = 0;
while (n > 0) {
squareSum += Math.pow(n%10,2);
n /= 10;
}
if(set.contains(squareSum)){
return false;
} else {
set.add(squareSum);
n = squareSum;
}
}
return true;
}
}
238 Product of Array Except Self Medium
Given an array of n integers where n > 1, nums, return an array output such that output[i] is equal to the product of all the elements of nums except nums[i].
Solve it without division and in O(n).
For example, given [1,2,3,4], return [24,12,8,6].
Follow up:
Could you solve it with constant space complexity? (Note: The output array does not count as extra space for the purpose of space complexity analysis.)
思路:求所有数的乘积,然后除以当前数
注意:考虑有0的情况,其中分为只有一个0和有多个0的情况
class Solution {
public int[] productExceptSelf(int[] nums) {
int[] output = new int[nums.length];
int product = 1;
int zeroCount = 0;
boolean hasZero = false;
for(int i=0; i<nums.length; i++) {
if(nums[i] == 0) {
zeroCount++;
hasZero = true;
continue;
}
product *= nums[i];
}
if(hasZero) {
Arrays.fill(output, 0);
if(zeroCount == 1) {
for(int i=0; i<nums.length; i++) {
if(nums[i] == 0) {
output[i] = product;
break;
}
}
}
} else {
for(int i=0; i<nums.length; i++) {
output[i] = product/nums[i];
}
}
return output;
}
}
152 Maximum Product Subarray Medium
Find the contiguous subarray within an array (containing at least one number) which has the largest product.
For example, given the array [2,3,-2,4],
the contiguous subarray [2,3] has the largest product = 6.
思路:以一个数开头,遍历所有以它打头的连续子数组,记录最大的乘积,对应n个这样的数,求其中的最大值。
class Solution {
public int maxProduct(int[] nums) {
int[] product = new int[nums.length];
for(int i=0; i<nums.length; i++) {
// 不能用1来初始化
int max = Integer.MIN_VALUE;
int productNum = 1;
for(int j=i; j<nums.length; j++) {
productNum *= nums[j];
if(productNum > max) {
max = productNum;
}
}
product[i] = max;
}
Arrays.sort(product);
return product[product.length-1];
}
}
628 Maximum Product of Three Numbers Easy
Given an integer array, find three numbers whose product is maximum and output the maximum product.
Example 1:
Input: [1,2,3]
Output: 6
Example 2:
Input: [1,2,3,4]
Output: 24
Note:
The length of the given array will be in range [3,104] and all elements are in the range [-1000, 1000].
Multiplication of any three numbers in the input won't exceed the range of 32-bit signed integer.
思路:
- 如果最大的3个数都为正,那就是这三个数的乘积
- 否则,索性取最小的两个负数相乘,再乘上最大的正数
- 没有正数、负数少于两个、有0等自觉特殊的情况,举例验证,逃不出以上两种
class Solution {
public int maximumProduct(int[] nums) {
int n = nums.length;
Arrays.sort(nums);
int num1 = nums[n-1]*nums[n-2]*nums[n-3];
int num2 = nums[0]*nums[1]*nums[n-1];
return Math.max(num1,num2);
}
}
295 Find Median from Data Stream Hard
Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
For example,
[2,3,4], the median is 3
[2,3], the median is (2 + 3) / 2 = 2.5
Design a data structure that supports the following two operations:
void addNum(int num) - Add a integer number from the data stream to the data structure.
double findMedian() - Return the median of all elements so far.
Example:
addNum(1)
addNum(2)
findMedian() -> 1.5
addNum(3)
findMedian() -> 2
题意:求数据流中的中位数
思路:
左半边数:最大堆
右半边数:最小堆
class MedianFinder {
/** initialize your data structure here. */
PriorityQueue<Integer> maxHeap;
PriorityQueue<Integer> minHeap;
public MedianFinder() {
maxHeap = new PriorityQueue<>(Comparator.reverseOrder());
minHeap = new PriorityQueue<>();
}
public void addNum(int num) {
if(maxHeap.size() == minHeap.size()) {
// 左右堆大小一样
if(minHeap.peek()!=null && num>minHeap.peek()) {
minHeap.add(num);
} else {
// 默认放左堆
maxHeap.add(num);
}
} else if(maxHeap.size() > minHeap.size()) {
// 右堆数量少
if(num < maxHeap.peek()) {
maxHeap.add(num);
int temp = maxHeap.poll();
minHeap.add(temp);
} else {
// 默认放右堆
minHeap.add(num);
}
} else {
// 左堆数量少
if(num > minHeap.peek()) {
minHeap.add(num);
int temp = minHeap.poll();
maxHeap.add(temp);
} else {
// 默认放左堆
maxHeap.add(num);
}
}
}
public double findMedian() {
if(maxHeap.size() == minHeap.size()) {
return (double)(maxHeap.peek()+minHeap.peek())/2;
} else{
return maxHeap.size() > minHeap.size()?(double)maxHeap.peek():(double)minHeap.peek();
}
}
}
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/
169 Majority Element Easy
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.
Example 1:
Input: [3,2,3]
Output: 3
Example 2:
Input: [2,2,1,1,1,2,2]
Output: 2
题意:找到数组中出现次数超过一半的数字
我的方法:HashMap累计次数
方法1:基于Partition寻找中位数(得到数组第n/2大的数字)
方法2:遍历数组时记录一个数字、一个计数
class Solution {
public int majorityElement(int[] nums) {
int result = nums[0], count = 1;
for(int i=1; i<nums.length; i++) {
int num = nums[i];
if(count == 0) {
result = num;
count = 1;
} else if(num == result) {
count++;
} else {
count--;
}
}
return result;
}
}
287 Find the Duplicate Number Medium
Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.
Example 1:
Input: [1,3,4,2,2]
Output: 2
Example 2:
Input: [3,1,3,4,2]
Output: 3
Note:
You must not modify the array (assume the array is read only).
You must use only constant, O(1) extra space.
Your runtime complexity should be less than O(n2).
There is only one duplicate number in the array, but it could be repeated more than once.
题意:找到数组中重复的数字
题目特点:n+1个数字的数据范围是[1,n],如果没有重复数字,数字和自身的下标相等。利用这一点,依次遍历数组。
- 数字 == 下标,过
- 数字 != 下标,但是数字 == 以该数为下标的数字,就是重复数字
- 否则,交换两数,继续判断。
class Solution {
public int findDuplicate(int[] nums) {
if(nums == null || nums.length<2) {
return -1;
}
int i = 0;
while(i<nums.length) {
if(nums[i] == i) {
i++;
} else {
if(nums[i] == nums[nums[i]]) {
return nums[i];
}
int temp = nums[i];
nums[i] = nums[temp];
nums[temp] = temp;
}
}
return -1;
}
}