Question
Sort the letters in one word by the order they occur in another in linear time.
Solution
This
text
is
used
to
stop
you
from
looking
at
the
answer
immediately
The answer is counting sort.
Sort the letters in one word by the order they occur in another in linear time.
This
text
is
used
to
stop
you
from
looking
at
the
answer
immediately
The answer is counting sort.
Rotate an array of n elements to the right by k steps.
For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7]
is rotated to [5,6,7,1,2,3,4]
.
Note:
Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.
Related problem: Reverse Words in a String II
Credits:
Special thanks to @Freezen for adding this problem and creating all test cases.
This question is very standard “rotate 3 times” solution.
public class Solution {
public void rotate(int[] nums, int k) {
if (nums == null || nums.length == 0) {
return;
}
int len = nums.length;
k = k % len;
reverse(nums, 0, len - k - 1);
reverse(nums, len - k, len - 1);
reverse(nums, 0, len - 1);
}
void reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start++;
end--;
}
}
}
Reverse bits of a given 32 bits unsigned integer.
For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), return 964176192 (represented in binary as 00111001011110000010100101000000).
Follow up:
If this function is called many times, how would you optimize it?
Related problem: Reverse Integer
Credits:
Special thanks to @ts for adding this problem and creating all test cases.
This question is standard bit manipulation. We essentially get bits one by one from n, and append it to the result.
However, the question ask how to optimize it, to improve its performance. Em, that’s interesting.
First code is the standard solution.
I found another interesting solution from programcreek, which uses “swap bits” method. I’ve never seen this before, so I posted his solution below.
But is it really a faster solution?
Finally, I found something in 书影 博客, quoted as below:
以4位为单位执行反转,将0x0至0xF的反转结果预存在一个长度为16的数组中,反转时直接查询即可。
Thus this is the best solution for performance.
My code
public class Solution {
// you need treat n as an unsigned value
public int reverseBits(int n) {
int result = 0;
for (int i = 0; i < 32; i++) {
int last = n & 1;
n >>= 1;
result <<= 1;
result = result | last;
}
return result;
}
}
“swap bits”
public int reverseBits(int n) {
for (int i = 0; i < 16; i++) {
n = swapBits(n, i, 32 - i - 1);
}
return n;
}
public int swapBits(int n, int i, int j) {
int a = (n >> i) & 1;
int b = (n >> j) & 1;
if ((a ^ b) != 0) {
return n ^= (1 << i) | (1 << j);
}
return n;
}
Best solution:
char tb[16] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
uint32_t reverseBits(uint32_t n) {
int curr = 0;
uint32_t ret = 0;
uint32_t msk = 0xF;
for(int i = 0; i < 8; i++) {
ret = ret << 4;
curr = msk&n;
ret |= tb[curr];
n = n >> 4;
}
return ret;
}
Given a 2d grid map of '1'
s (land) and '0'
s (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.
Example 1:
11110
11010
11000
00000
Answer: 1
Example 2:
11000
11000
00100
00011
Answer: 3
Credits:
Special thanks to @mithmatt for adding this problem and creating all test cases.
At every ‘1’ position, do DFS.
I post my code below. Note that we do not actually have to have the method “findLand” - we can simply read through the grid and mark all ‘1’s in one run.
You might want to come up with your own code. Mine is just for reference. This is not an very interesting question, I assume.
public class Solution {
public int numIslands(char[][] grid) {
if (grid == null || grid.length == 0 || grid[0].length == 0) {
return 0;
}
int m = grid.length;
int n = grid[0].length;
int count = 0;
Pair firstPiece = findLand(grid, m, n);
while (firstPiece != null) {
// mark all neighbors, and count increment
mark(grid, m, n, firstPiece);
firstPiece = findLand(grid, m, n);
count++;
}
return count;
}
void mark(char[][] grid, int m, int n, Pair p) {
if (p.x < 0 || p.x == m || p.y < 0 || p.y == n) {
return;
} else if (grid[p.x][p.y] != '1') {
return;
}
// mark current and then dfs
grid[p.x][p.y] = '2';
mark(grid, m, n, new Pair(p.x - 1, p.y));
mark(grid, m, n, new Pair(p.x + 1, p.y));
mark(grid, m, n, new Pair(p.x, p.y - 1));
mark(grid, m, n, new Pair(p.x, p.y + 1));
}
Pair findLand(char[][] grid, int m, int n) {
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == '1') {
return new Pair(i, j);
}
}
}
return null;
}
class Pair {
int x;
int y;
public Pair(int a, int b) {
x = a;
y = b;
}
}
}
Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also known as the Hamming weight).
For example, the 32-bit integer ’11' has binary representation 00000000000000000000000000001011
, so the function should return 3.
Credits:
Special thanks to @ts for adding this problem and creating all test cases.
In order to remove the last ‘1’ bit, we use this operation:
n = n & (n - 1);
Just remove all the ‘1’ bits.
public class Solution {
public int hammingWeight(int n) {
int count = 0;
while (n != 0) {
n = n & (n - 1);
count++;
}
return count;
}
}
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.
Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.
Credits:
Special thanks to @ifanchu for adding this problem and creating all test cases. Also thanks to @ts for adding additional test cases.
DP question. Be careful what the initial values of dp(1) is. You should work this out without a problem!
public class Solution {
public int rob(int[] num) {
if (num == null || num.length == 0) {
return 0;
} else if (num.length == 1) {
return num[0];
}
int len = num.length;
int[] dp = new int[len];
dp[0] = num[0];
dp[1] = Math.max(num[0], num[1]);
int max = Math.max(num[0], num[1]);
for (int i = 2; i < len; i++) {
dp[i] = Math.max(dp[i - 1], dp[i - 2] + num[i]);
max = Math.max(max, dp[i]);
}
return max;
}
}
Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers in this range, inclusive.
For example, given the range [5, 7], you should return 4.
Credits:
Special thanks to @amrsaqr for adding this problem and creating all test cases.
This is a pretty interesting mathematics question. Now we take 2 numbers as example:
Num1: 110010
Num2: 110111
Result: 110000
And:
Num1: 0110
Num2: 1100
Result: 0
Note that:
if the first ‘1’ bit of the 2 numbers are at different position, the answer should simply be 0.
if have same position, then the result would be the continous sequence of 1s, followed by all 0s.
The 2 best solutions is very well presented by Grandyang using bit shifting and masking. Please refer to code 1 and code 2 below.
I found a third solution at programcreek, which makes use of the fact that m is smaller than n.
code 1
class Solution {
public:
int rangeBitwiseAnd(int m, int n) {
int d = INT_MAX;
while ((m & d) != (n & d)) {
d <<= 1;
}
return m & d;
}
};
code 2
class Solution {
public:
int rangeBitwiseAnd(int m, int n) {
int i = 0;
while (m != n) {
m >>= 1;
n >>= 1;
++i;
}
return (m << i);
}
};
code 3
public int rangeBitwiseAnd(int m, int n) {
while (n > m) {
n = n & n - 1;
}
return m & n;
}
Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom.
For example:
Given the following binary tree,
1 <--- / \ 2 3 <--- \ \ 5 4 <---
You should return [1, 3, 4]
.
Credits:
Special thanks to @amrsaqr for adding this problem and creating all test cases.
This question basically is binary tree traversal. During the process, we keep a list and update the elements in it.
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
traverse(result, root, 1);
return result;
}
void traverse(List<Integer> result, TreeNode node, int level) {
if (node == null) return;
if (level > result.size()) {
result.add(node.val);
}
traverse(result, node.right, level + 1);
traverse(result, node.left, level + 1);
}
}
All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACGAATTCCG". When studying DNA, it is sometimes useful to identify repeated sequences within the DNA.
Write a function to find all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule.
For example,
Given s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT", Return: ["AAAAACCCCC", "CCCCCAAAAA"].Hash Table Bit Manipulation
This question is straight-forward: just iterate thru all the 10-letter long subsequences, and then add into hashmap.
However, if you simply use String as hash key, it will exceed OJ run time.
Convert string to int is the right approach. To get the best performance, we use 2 bits to represent each DNA nucleotide. Integer is 32-bit long so, no problem with that.
Node that Integer.Max = 2,147,483,647. There’s total of 10 digitals, so using 1 digit to represent 1 letter is not feasible. Ref: BUPT-哲人善思
The code is pretty difficult to write.
public class Solution {
public List<String> findRepeatedDnaSequences(String s) {
List<String> res = new ArrayList<String>();
if (s == null || s.length() < 10) {
return res;
}
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
// map<> stores int-to-int: first int is "ACGT" -> 1234
// second int is the init position of the pattern in s
int num = 0;
int mask = 0xFFFFFFFF;
mask >>>= (32 - 18);
for (int i = 0; i < s.length(); i++) {
num = mask & num;
// get the last 18 binary digits of num
num = (num << 2) | convertChatToInt(s.charAt(i));
// append num with the number representing charAt(i)
if (i >= 9) {
// insert or search num in the map
if (!map.containsKey(num)) {
map.put(num, (i - 9));
// (i - 9) is the start position of
// the 10-letter-long sequence
} else if (map.get(num) != -1) {
res.add(s.substring(map.get(num), map.get(num) + 10));
map.put(num, -1);
// after the sequence has been added, mark it in the map
} else {
// do nothing
}
}
}
return res;
}
int convertChatToInt(char ch) {
if (ch == 'A') {
return 1;
} else if (ch == 'C') {
return 2;
} else if (ch == 'G') {
return 3;
}
return 0;
}
}
Given a list of non negative integers, arrange them such that they form the largest number.
For example, given [3, 30, 34, 5, 9]
, the largest formed number is 9534330
.
Note: The result may be very large, so you need to return a string instead of an integer.
Credits:
Special thanks to @ts for adding this problem and creating all test cases.
Please refer to [[ItInt5] Numbers Concatenation Max (Largest Number)(/blog/2014/08/17/Numbers-Concatenation-Max/).
Note that we can not override Comparator(Integer). So we must first convert int to string then sort.
public class Solution {
// this code should pass
public String largestNumber(int[] num) {
if (num == null || num.length == 0) {
return "0";
}
String[] strs = new String[num.length];
for (int i = 0; i < num.length; i++) {
strs[i] = String.valueOf(num[i]);
}
Arrays.sort(strs, new LargerComparator());
String res = "";
for (String str : strs) {
res = res + str;
}
return res;
}
class LargerComparator implements Comparator<String> {
public int compare(String a, String b) {
String first = a + b;
String second = b + a;
return second.compareTo(first);
}
}
}