53. Maximum Subarray
Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.
Example:
Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.
Follow up:
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
My Solution
public int maxSubArray(int[] nums) {
int max = nums[0];
int sum = max;
for(int i = 1; i < nums.length; i++) {
sum += nums[i];
if(sum < nums[i]) {
sum = nums[i];
}
if(sum > max) {
max = sum;
}
}
return max;
}
Runtime: 0 ms, faster than 100.00% of Java online submissions for Maximum Subarray.
Memory Usage: 37.4 MB, less than 99.45% of Java online submissions for Maximum Subarray.
I think the solution is pretty good. It’s clear and easy problem but I still spent half hour. I hope I can do better.
Other Solution
public int maxSubArray(int[] nums) {
int cur = nums[0];
int max = cur;
for(int i = 1; i < nums.length; i++){
cur = Math.max(nums[i], cur+nums[i]);
if(max < cur) max = cur;
}
return max;
}
same algorithm but better code
58. Length of Last Word
Given a string s consists of upper/lower-case alphabets and empty space characters ’ ', return the length of last word in the string.
If the last word does not exist, return 0.
Note: A word is defined as a character sequence consists of non-space characters only.
Example:
Input: "Hello World"
Output: 5
My Solution
public int lengthOfLastWord(String s) {
if(s == null) return 0;
String[] a = s.split(" ");
if(a.length == 0) return 0;
int b = a[a.length - 1].length();
return b;
}
Runtime: 1 ms, faster than 46.70% of Java online submissions for Length of Last Word.
Memory Usage: 35.6 MB, less than 100.00% of Java online submissions for Length of Last Word.
Other Solution
public int lengthOfLastWord(String s) {
if (s == null || s.length() == 0) return 0;
int i = s.length() - 1, count = 0;
while (i >= 0 && s.charAt(i) == ' ')
i--;
for (; i >= 0 && s.charAt(i) != ' '; i--, count++);
return count;
}
Runtime: 0 ms, faster than 100.00% of Java online submissions for Length of Last Word.
Memory Usage: 35.5 MB, less than 100.00% of Java online submissions for Length of Last Word.
66. Plus One
Given a non-empty array of digits representing a non-negative integer, plus one to the integer.
The digits are stored such that the most significant digit is at the head of the list, and each element in the array contain a single digit.
You may assume the integer does not contain any leading zero, except the number 0 itself.
Example 1:
Input: [1,2,3]
Output: [1,2,4]
Explanation: The array represents the integer 123.
Example 2:
Input: [4,3,2,1]
Output: [4,3,2,2]
Explanation: The array represents the integer 4321.
My Solution
public int[] plusOne(int[] digits) {
int a = digits.length;
if(digits[a-1] != 9) {
digits[a-1] += 1;
return digits;
}
digits[a-1] = 0;
for(int i = a-2; i >= 0; i--) {
if(digits[i] + 1 == 10) {
digits[i] = 0;
} else {
digits[i] += 1;
break;
}
}
if(digits[0] == 0) {
int[] newdigits = new int[digits.length+1];
newdigits[0] = 1;
for(int j = 0; j < digits.length; j++) {
newdigits[j+1] = digits[j];
}
digits = newdigits;
}
return digits;
}
Runtime: 0 ms, faster than 100.00% of Java online submissions for Plus One.
Memory Usage: 35.3 MB, less than 99.00% of Java online submissions for Plus One.
Other Solution
public int[] plusOne(int[] digits) {
int len = digits.length;
digits[len - 1] += 1;
for (int i = len - 1; i >= 1; i--) {
if (digits[i] == 10) {
digits[i-1] += 1;
digits[i] = 0;
} else {
return digits;
}
}
if (digits[0] == 10) {
int[] res = new int[len + 1];
res[0] = 1;
res[1] = 0;
for (int i = 1; i < len; i++) {
res[i+1] = digits[i];
}
return res;
}
return digits;
}
Runtime: 0 ms, faster than 100.00% of Java online submissions for Plus One.
Memory Usage: 35 MB, less than 99.07% of Java online submissions for Plus One.
same algorithm but with better code.
67. Add Binary
Given two binary strings, return their sum (also a binary string).
The input strings are both non-empty and contains only characters 1 or 0.
Example 1:
Input: a = "11", b = "1"
Output: "100"
Example 2:
Input: a = "1010", b = "1011"
Output: "10101"
My Solution
public String addBinary(String a, String b) {
String res = "";
int len = Math.max(a.length(), b.length());
if(a.length() > b.length()) {
int k = a.length()-b.length();
for(int j = 0; j < k; j++) {
b = 0 + b;
}
} else {
int k = b.length()-a.length();
for(int j = 0; j < k; j++) {
a = 0 + a;
}
}
int c = 0;
for (int i = 1; i <= len; i++) {
if(a.substring(a.length()-i,a.length()-i+1).equals("1") && b.substring(b.length()-i,b.length()-i+1).equals("1")) {
res = c + res;
c = 1;
} else if(a.substring(a.length()-i,a.length()-i+1).equals("0") && b.substring(b.length()-i,b.length()-i+1).equals("0")) {
res = c + res;
c = 0;
} else {
if(c == 0) res = 1 + res;
else if(c == 1) res = 0 + res;
}
}
if (c == 1) return 1+res;
return res;
}
Runtime: 3 ms, faster than 13.65% of Java online submissions for Add Binary.
Memory Usage: 36.1 MB, less than 100.00% of Java online submissions for Add Binary.
It’s kind of time-consumed. But luckily it has the smallest memory usage. The algorithm is Fill in zero before the shorter string and set the carry parameter c. Followed by the addition and carry calculation of the same position.
Other Solution 1
import java.math.*;
class Solution {
public String addBinary(String a, String b) {
BigInteger i = new BigInteger(a,2);
BigInteger j = new BigInteger(b,2);
return i.add(j).toString(2);
}
}
Runtime: 5 ms, faster than 6.29% of Java online submissions for Add Binary.
Memory Usage: 36.1 MB, less than 100.00% of Java online submissions for Add Binary.
java.math.BigInteger can theoretically represent an infinite integer and it can transfer binary to Integer easily. Here are some methods of BigInteger.
https://www.cnblogs.com/cangqinglang/p/8992312.html
Other Solution 2
public String addBinary(String a, String b) {
int lenA = a.length(), lenB = b.length();
int carry = 0;
int numOfOne = 0;
StringBuilder res = new StringBuilder();
while(true){
if(lenA >= 1 && a.charAt(lenA - 1) == '1') numOfOne++;
if(lenB >= 1 && b.charAt(lenB - 1) == '1') numOfOne++;
if(carry == 1 ) numOfOne++;
switch(numOfOne){
case 0: res.insert(0, '0'); carry = 0; break;
case 1: res.insert(0, '1'); carry = 0; break;
case 2: res.insert(0, '0'); carry = 1; break;
case 3: res.insert(0, '1'); carry = 1; break;
}
lenA--;
lenB--;
if(lenA <= 0 && lenB <= 0){
if(carry == 1) { res.insert(0, 1); break; }
else break;
}
numOfOne = 0;
}
return res.toString();
}
Runtime: 2 ms, faster than 65.74% of Java online submissions for Add Binary.
Memory Usage: 36 MB, less than 100.00% of Java online submissions for Add Binary.
69. Sqrt(x)
Implement int sqrt(int x)
.
Compute and return the square root of x, where x is guaranteed to be a non-negative integer.
Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned.
Example 1:
Input: 4
Output: 2
Example 2:
Input: 8
Output: 2
Explanation: The square root of 8 is 2.82842..., and since
the decimal part is truncated, 2 is returned.
My Solution 1
public int mySqrt(int x) {
return (int) Math.sqrt(x);
}
Runtime: 1 ms, faster than 100.00% of Java online submissions for Sqrt(x).
Memory Usage: 33.5 MB, less than 5.07% of Java online submissions for Sqrt(x).
Can I did like this? …
Other Solution 1
public int mySqrt(int x) {
int lo = 1, hi = x;
while(lo < hi) {
int mid = lo + (hi - lo) / 2 + 1;
if(mid > x / mid) {
hi = mid - 1;
} else {
lo = mid;
}
}
return hi;
}
Runtime: 1 ms, faster than 100.00% of Java online submissions for Sqrt(x).
Memory Usage: 33.6 MB, less than 5.07% of Java online submissions for Sqrt(x).
Other Solution 2
public int mySqrt(int x) {
if (x < 0) {
return -1;
}
// e.g. 0, 1
if (x <= 1) {
return x;
}
// result < x / 2
int start = 1, end = x / 2;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
// Noting that we cannot use mid*mid since it will be probably be too large
if (mid == x / mid) {
return mid;
}
else if (mid < x / mid) {
start = mid;
}
else {
end = mid;
}
}
// only start and end left
if (end > x / end) {
return start;
}
else {
return end;
}
}
I tried many times but I can’t find a solution with less memory usage…
70. Climbing Stairs
You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
Note: Given n will be a positive integer.
Example 1:
Input: 2
Output: 2
Explanation: There are two ways to climb to the top.
1. 1 step + 1 step
2. 2 steps
Example 2:
Input: 3
Output: 3
Explanation: There are three ways to climb to the top.
1. 1 step + 1 step + 1 step
2. 1 step + 2 steps
3. 2 steps + 1 step
My Solution 1
int count = 0;
public int climbStairs(int n) {
climb(n);
return count;
}
public void climb(int sum) {
if (sum < 0) {
return;
}
if (sum == 0) {
count += 1;
}
climb(sum-2);
climb(sum-1);
}
Time Limit Exceeded. Last executed input: 44.
I tried to use recursion to solve it but the report is time limit exceeded … (I used my eclipse to run the code and get the input 1134903170).
So the solution is right but it’s not a good one.
My Solution 2
public int climbStairs(int n) {
int[] list = new int[n+1];
list[0] = 1;
list[1] = 2;
int i = 2;
while(i < n) {
list[i] = list[i-1] + list[i-2];
i++;
}
return list[n-1];
}
Runtime: 0 ms, faster than 100.00% of Java online submissions for Climbing Stairs.
Memory Usage: 32.8 MB, less than 5.29% of Java online submissions for Climbing Stairs.
Official Solution
LeetCode gives a series of very great solution and their explainations. Strongly recommend you to view their solution.
https://leetcode.com/problems/climbing-stairs/solution/
(It is really helpful to understand recursion)
83. Remove Duplicates from Sorted List
Given a sorted linked list, delete all duplicates such that each element appear only once.
Example 1:
Input: 1->1->2
Output: 1->2
Example 2:
Input: 1->1->2->3->3
Output: 1->2->3
My Solution
public ListNode deleteDuplicates(ListNode head) {
if (head == null) return head;
ListNode current = head;
ListNode previous = head;
int judge = 0;
while(current.next != null) {
current = current.next;
while(current.val == previous.val) {
if(current.next != null) current = current.next;
else {
previous.next = null;
return head;
}
judge = 1;
}
if(judge == 0){
previous = previous.next;
} else {
previous.next = current;
previous = previous.next;
judge = 0;
}
}
return head;
}
Runtime: 0 ms, faster than 100.00% of Java online submissions for Remove Duplicates from Sorted List.
Memory Usage: 36.2 MB, less than 99.95% of Java online submissions for Remove Duplicates from Sorted List.
This solution has less memory usage because I modified the node on the basis of the original. In the code I add a “judge” to determine which step should be executed.
Official Solution
public ListNode deleteDuplicates(ListNode head) {
ListNode current = head;
while (current != null && current.next != null) {
if (current.next.val == current.val) {
current.next = current.next.next;
} else {
current = current.next;
}
}
return head;
}
Runtime: 0 ms, faster than 100.00% of Java online submissions for Remove Duplicates from Sorted List.
Memory Usage: 36.9 MB, less than 99.85% of Java online submissions for Remove Duplicates from Sorted List.
Wonderful solution with easy algorithm.
88. Merge Sorted Array
Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.
Note:
- The number of elements initialized in nums1 and nums2 are m and n
respectively. - You may assume that nums1 has enough space (size that is greater or
equal to m + n) to hold additional elements from nums2.
Example:
Input:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
Output: [1,2,2,3,5,6]
My Solution
public void merge(int[] nums1, int m, int[] nums2, int n) {
int[] nums3 = new int[m];
for(int i = 0; i < nums3.length; i++) {
nums3[i] = nums1[i];
}
int i = 0; int j = 0; int k = 0;
while(i < nums3.length && j < nums2.length) {
if(nums3[i] <= nums2[j]) {
nums1[k] = nums3[i];
i++;
} else{
nums1[k] = nums2[j];
j++;
}
k++;
}
while(i < nums3.length) {
nums1[k] = nums3[i];
i++; k++;
}
while(j < nums2.length) {
nums1[k] = nums2[j];
j++; k++;
}
}
Runtime: 0 ms, faster than 100.00% of Java online submissions for Merge Sorted Array.
Memory Usage: 36.4 MB, less than 100.00% of Java online submissions for Merge Sorted Array.
Luckily, I learned Merge sort yesterday … So it would be very easy when you used the algorithm of Merge sort.
Other Solution
public void merge(int[] nums1, int m, int[] nums2, int n) {
for(int i = 0; i < n; i++){
nums1[m+i] = nums2[i];
}
Arrays.sort(nums1);
}
Runtime: 0 ms, faster than 100.00% of Java online submissions for Merge Sorted Array.
Memory Usage: 36.4 MB, less than 100.00% of Java online submissions for Merge Sorted Array.
Can I say it’s cheating to use “Array.sort()” here ?
100. Same Tree
Given two binary trees, write a function to check if they are the same or not.
Two binary trees are considered the same if they are structurally identical and the nodes have the same value.
Example 1:
Input: 1 1
/ \ / \
2 3 2 3
[1,2,3], [1,2,3]
Output: true
Example 2:
Input: 1 1
/ \
2 2
[1,2], [1,null,2]
Output: false
Example 3:
Input: 1 1
/ \ / \
2 1 1 2
[1,2,1], [1,1,2]
Output: false
My Solution
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) return true;
if (p == null || q == null) return false;
if (p.val != q.val) return false;
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
Runtime: 0 ms, faster than 100.00% of Java online submissions for Same Tree.
Memory Usage: 34.1 MB, less than 100.00% of Java online submissions for Same Tree.
Official Solution
class Solution {
public boolean check(TreeNode p, TreeNode q) {
// p and q are null
if (p == null && q == null) return true;
// one of p and q is null
if (q == null || p == null) return false;
if (p.val != q.val) return false;
return true;
}
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) return true;
if (!check(p, q)) return false;
// init deques
ArrayDeque<TreeNode> deqP = new ArrayDeque<TreeNode>();
ArrayDeque<TreeNode> deqQ = new ArrayDeque<TreeNode>();
deqP.addLast(p);
deqQ.addLast(q);
while (!deqP.isEmpty()) {
p = deqP.removeFirst();
q = deqQ.removeFirst();
if (!check(p, q)) return false;
if (p != null) {
// in Java nulls are not allowed in Deque
if (!check(p.left, q.left)) return false;
if (p.left != null) {
deqP.addLast(p.left);
deqQ.addLast(q.left);
}
if (!check(p.right, q.right)) return false;
if (p.right != null) {
deqP.addLast(p.right);
deqQ.addLast(q.right);
}
}
}
return true;
}
}
One of official solution is same with my solution. This is the second one with using iteration.