leetcode (4)

Leetcode 4

  • [151. Reverse Words in a String](#151. Reverse Words in a String)
  • [152. Maximum Product Subarray](#152. Maximum Product Subarray)
  • [153. Find Minimum in Rotated Sorted Array](#153. Find Minimum in Rotated Sorted Array)
  • [155. Min Stack](#155. Min Stack)
  • [160. Intersection of Two Linked Lists](#160. Intersection of Two Linked Lists)
  • [161. One Edit Distance](#161. One Edit Distance)
  • [162. Find Peak Element](#162. Find Peak Element)
  • [165. Compare Version Numbers](#165. Compare Version Numbers)
  • [166. Fraction to Recurring Decimal](#166. Fraction to Recurring Decimal)
  • [167. Two Sum II - Input Array Is Sorted](#167. Two Sum II - Input Array Is Sorted)
  • [168. Excel Sheet Column Title](#168. Excel Sheet Column Title)
  • [169. Majority Element](#169. Majority Element)
  • [171. Excel Sheet Column Number](#171. Excel Sheet Column Number)
  • [172. Factorial Trailing Zeroes](#172. Factorial Trailing Zeroes)
  • [173. Binary Search Tree Iterator](#173. Binary Search Tree Iterator)
  • [179. Largest Number](#179. Largest Number)
      • [custom sort / compare](#custom sort / compare)
  • [187. Repeated DNA Sequences](#187. Repeated DNA Sequences)
  • [189. Rotate Array](#189. Rotate Array)
  • [190. Reverse Bits](#190. Reverse Bits)
  • [191. Number of 1 Bits](#191. Number of 1 Bits)
  • [198. House Robber](#198. House Robber)
  • [199. Binary Tree Right Side View](#199. Binary Tree Right Side View)
  • [200. Number of Islands](#200. Number of Islands)

151. Reverse Words in a String

151. Reverse Words in a String

Given an input string s, reverse the order of the words.

A word is defined as a sequence of non-space characters. The words in s will be separated by at least one space.

Return a string of the words in reverse order concatenated by a single space.

Note that s may contain leading or trailing spaces or multiple spaces between two words. The returned string should only have a single space separating the words. Do not include any extra spaces.
Input: s = "the sky is blue"

Output: "blue is sky the"

1. split the sentence into word, reverse the word order.

strList: [the, sky, is, blue]

Collections.reverse(strList);

strList: [blue, is, sky, the]

java 复制代码
class Solution {
    public String reverseWords(String s) {
        List<String> strList = new ArrayList<>();
        StringBuffer temp = new StringBuffer();
        for(int i = 0; i < s.length(); i++){
            if(s.charAt(i)==' '){
                if(temp.length()>0){
                    strList.add(new String(temp.toString()));
                    temp.delete(0,temp.length());
                }
            continue;
            }
            else{
                temp.append(s.charAt(i));
            }
        }
        if(temp.length()>0){
            strList.add(new String(temp.toString()));
        }
        Collections.reverse(strList);
        StringBuffer ans = new StringBuffer();
        for(String str:strList){
            ans.append(str);
            ans.append(" ");
        }
        ans.delete(ans.length()-1,ans.length());
        return ans.toString();
    }
}

6ms 91.02% 42.4MB 87.92%

Use trim() and split() to split the word

java 复制代码
    public String reverseWords(String s) {
        Stack<String> st = new Stack<String>();
        for (String a : s.trim().split(" ")) {
            if (!a.isEmpty())
                st.push(a);
        }  
        StringBuilder sb = new StringBuilder();
        while (!st.isEmpty()) {
            sb.append(st.pop());
            sb.append(" ");            
        }
        return sb.toString().trim();
    }

9 ms 79.91% 43.3 MB 68.57%

  • StringBuffer

    clear the string buffer using the delete() and setLength() method and creating a new StringBuffer object in Java.

    ** str.delete(0,str.length())**
    str.setLength(0)

  • Collections.reverse()

    Reversing an ArrayList, a LinkedList, an array

  • String split()

java 复制代码
for (String a : s.trim().split(" ")) {
    if (!a.isEmpty())
        st.push(a);
}  
  • String trim()
    The trim() method in java checks this Unicode value before and after the string, if it exists then removes the spaces and returns the omitted string.
    The trim() method doesn't eliminate middle spaces.
java 复制代码
String str = "GeeksforGeeks:A Computer Science Portal";
String[] arrOfStr = str.split(":");

GeeksforGeeks

A Computer Science Portal

java 复制代码
String str = "GeeksforGeeksforStudents";
String[] arrOfStr = str.split("for");

Geeks

Geeks

Students

2. Reverse twice. Reverse the whole sentence + Reverse the word.

the sky is blue

-> eulb si yks eht

-> blue is sky the

java 复制代码
public class Solution {
  
  public String reverseWords(String s) {
    if (s == null) return null;
    
    char[] a = s.toCharArray();
    int n = a.length;
    
    // step 1. reverse the whole string
    reverse(a, 0, n - 1);
    // step 2. reverse each word
    reverseWords(a, n);
    // step 3. clean up spaces
    return cleanSpaces(a, n);
  }
  
  void reverseWords(char[] a, int n) {
    int i = 0, j = 0;
      
    while (i < n) {
      while (i < j || i < n && a[i] == ' ') i++; // skip spaces
      while (j < i || j < n && a[j] != ' ') j++; // skip non spaces
      reverse(a, i, j - 1);                      // reverse the word
    }
  }
  
  // trim leading, trailing and multiple spaces
  String cleanSpaces(char[] a, int n) {
    int i = 0, j = 0;
      
    while (j < n) {
      while (j < n && a[j] == ' ') j++;             // skip spaces
      while (j < n && a[j] != ' ') a[i++] = a[j++]; // keep non spaces
      while (j < n && a[j] == ' ') j++;             // skip spaces
      if (j < n) a[i++] = ' ';                      // keep only one space
    }
  
    return new String(a).substring(0, i);
  }
  
  // reverse a[] from a[i] to a[j]
  private void reverse(char[] a, int i, int j) {
    while (i < j) {
      char t = a[i];
      a[i++] = a[j];
      a[j--] = t;
    }
  }
  
}

152. Maximum Product Subarray

152. Maximum Product Subarray

Given an integer array nums, find a subarray that has the largest product, and return the product.

The test cases are generated so that the answer will fit in a 32-bit integer.
Example 1:

Input: nums = [2,3,-2,4]

Output: 6

Explanation: [2,3] has the largest product 6.

Example 2:

Input: nums = [-2,0,-1]

Output: 0

Explanation: The result cannot be 2, because [-2,-1] is not a subarray.

  • Case1 :All the elements are positive : Then your answer will be product of all the elements in the array.
  • Case2 : Array have positive and negative elements both :
    If the number of negative elements is even then again your answer will be complete array.
    If the number of negative elements is odd then you have to remove just one negative element and for that u need to check your subarrays to get the max product.
  • Case3 : Array also contains 0 : Then there will be not much difference...its just that your array will be divided into subarray around that 0.

    -1, -2, -3

    -1,-2 \] : max: 1 min: -2 \[ -1, -2, -3 \] : max: (-2) \* (-3) = 6 min: 2 \* (-3) = -6 \[ -1, -2, -3, 4 \] : max: 4 \* 6 = 24 min: 4 \* (-6) = -24 \[ -1, -2, -3, -4 \] : max: (-4) \* (-6) = 24 min: (-4) \* (6) = -24

java 复制代码
class Solution {
    public int maxProduct(int[] nums) {
        
        int max = nums[0], min = nums[0], ans = nums[0];
        
        for (int i = 1; i < nums.length; i++) {
            
            int temp = max;  // store the max because before updating min your max will already be updated
            
            max = Math.max(Math.max(max * nums[i], min * nums[i]), nums[i]);
            min = Math.min(Math.min(temp * nums[i], min * nums[i]), nums[i]);
            
            if (max > ans) {
                ans = max;
            }
        }        
        return ans;
    }
}

153. Find Minimum in Rotated Sorted Array

153. Find Minimum in Rotated Sorted Array

Suppose an array of length n sorted in ascending order is rotated between 1 and n times. For example, the array nums = [0,1,2,4,5,6,7] might become:

4,5,6,7,0,1,2\] if it was rotated 4 times. \[0,1,2,4,5,6,7\] if it was rotated 7 times. Notice that rotating an array \[a\[0\], a\[1\], a\[2\], ..., a\[n-1\]\] 1 time results in the array \[a\[n-1\], a\[0\], a\[1\], a\[2\], ..., a\[n-2\]\]. Given the sorted rotated array nums of unique elements, return the minimum element of this array. You must write an algorithm that runs in O(log n) time. Example 1: Input: nums = \[3,4,5,1,2

Output: 1

Explanation: The original array was [1,2,3,4,5] rotated 3 times.

Example 2:

Input: nums = [4,5,6,7,0,1,2]

Output: 0

Explanation: The original array was [0,1,2,4,5,6,7] and it was rotated 4 times.

Example 3:

Input: nums = [11,13,15,17]

Output: 11

Explanation: The original array was [11,13,15,17] and it was rotated 4 times.
Constraints:

n == nums.length

1 <= n <= 5000

-5000 <= nums[i] <= 5000

All the integers of nums are unique.

nums is sorted and rotated between 1 and n times.

low mid high

if(low<high) min = low

if(low<mid) low mid min (mid > high)/ low min mid(mid<high)

Binary Search

java 复制代码
    public int findMin(int[] nums) {
        int low = 0;
        int high = nums.length-1;
        int mid;
        if(nums.length==1){
            return nums[0];
        }
        //A 递增 最小 递增 B A>B
        if(nums[low]<nums[high]){
        	//最小递增B
            return nums[low];
        }
        //low=high return low
        while(low<high){
            mid = low+(high-low)/2;
            //A 递增 最小 递增 B 递增时后一位都比前一位大 比前一位小的是第二个递增序列开始那一位 即最小
            if(mid>0 && nums[mid]<nums[mid-1]){
                return nums[mid];
            }
            //把mid==low包含其中 low high 当mid==low时 nums[mid]>nums[high] 即high为最小
            //if(nums[mid]>=nums[low] && nums[mid]>nums[high]){
            if(nums[mid]>nums[low] && nums[mid]>nums[high]){
                low = mid +1;
            }
            else if(nums[mid]==nums[low] && nums[mid]>nums[high]){
                return nums[high];
            }
            else{
                high = mid -1;
            }
            
        }
        return nums[low];
    }

155. Min Stack

155. Min Stack

Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.

Implement the MinStack class:

MinStack() initializes the stack object.

void push(int val) pushes the element val onto the stack.

void pop() removes the element on the top of the stack.

int top() gets the top element of the stack.

int getMin() retrieves the minimum element in the stack.

You must implement a solution with O(1) time complexity for each function.

Stack

two stack

java 复制代码
class MinStack {
    //设置最小值栈 每个结点存储当前深度内的最小值
    //Math.min(minStack.peek(),val)
    //5ms 81.21%
    Stack<Integer> minStack;
    Stack<Integer> stack;
    
    public MinStack() {
        stack = new Stack<>();
        minStack = new Stack<>();
    }
        
    public void push(int val) {
        if(minStack.isEmpty()){
            minStack.push(val);
        }
        else{
            minStack.push(Math.min(minStack.peek(),val));
        }
        stack.push(val);

    }
    
    public void pop() {
        stack.pop();
        minStack.pop();
    }
    
    public int top() {
        return stack.peek();
    }
    
    public int getMin() {
        return minStack.peek();
    }
}

one stack, push pre min into stack as along as current item

java 复制代码
class MinStack {
    //将最小值的更新存入同一个栈中
    Stack<Integer> stack=new Stack<>();
    int min=Integer.MAX_VALUE;
    
    public void push(int x) {
        //出现新的最小值时,存储上一任最小值进同样一个栈 方便出栈更新最小值
        if(x<=min) {
            stack.push(min); 
            min=x;
        }
        stack.push(x);
    }
    public void pop() {
        if(stack.peek()==min){
            stack.pop(); 
            min=stack.pop(); //上一任最小值存储在当前最小值的下一个结点
        }
        else stack.pop();
    }
    public int top() {
        return stack.peek();
    }
    public int getMin() {
        return min;
    }
}

Custom Structure

java 复制代码
class MinStack {

    //不使用栈 自定义了一个链式结构
    //设置一个参数记录每次新进的结点和原最小值之间的最小值
    // 3ms 99.66%
    class Node{
        int val;
        int min;
        Node next;
        
        public Node(int val , int min , Node next){
            this.val = val;
            this.min = min;
            this.next = next;
        }
    }
    
    private Node head;
    
    public MinStack() {
        head = null;
    }
    
    //栈 先进后出 进去的结点的next指向之前的结点 更新head指向最新进去的结点
    /* head / top
        |
        V
       new node
        |
        V
       old node
    */
        
    public void push(int val) {
        if(head == null)
            head = new Node(val ,val ,null);
        else
            head = new Node(val , Math.min(val ,head.min), head);
    }
    
    public void pop() {
        head = head.next;
    }
    
    public int top() {
        return head.val;
    }
    
    public int getMin() {
        return head.min;
    }
}

160. Intersection of Two Linked Lists

160. Intersection of Two Linked Lists

Given the heads of two singly linked-lists headA and headB, return the node at which the two lists intersect. If the two linked lists have no intersection at all, return null.

For example, the following two linked lists begin to intersect at node c1:

The test cases are generated such that there are no cycles anywhere in the entire linked structure.

遍历第一个链表到尾部,连接到第二个链表

  • 如果两个链表不相交,相连之后,还是一个单链表
  • 如果两个链表相交,相连之后会有环
  1. get the len of the A,B. Use two pointer F,S. F-S = | lenA-lenB |

    A.next == B.next

  2. len A+B = len B+A

    len a+c+b+c = b+c+a+c

    a + c + b = b + c + a 相遇点即为交点c开头

    a1->a2->c1->c2->c3 A链结束接B链 ->b1->b2->b3->c1->c2->c3

    b1->b2->b3->c1->c2->c3 B链结束接A链 ->a1->a2->c1->c2->c3

    ||

    intersection

java 复制代码
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    ListNode a = headA, b = headB;
    while (a != b) {
        a = a == null ? headB : a.next;
        b = b == null ? headA : b.next;
    }
    return a;
}

161. One Edit Distance

https://leetcode.com/problems/one-edit-distance/description/

The "One Edit Distance" problem requires determining whether two given strings are exactly one edit apart. An edit can be one of the following:

Insert a single character into one string.

Delete a single character from one string.

Replace a single character in one string with another character.

Compare with length, if difference is large than 1 false

if str1 and str2 are same length, check if there is only one char difference

If not, if str1 > str 2, need to delete one in str1

else need to add one in str1

for(char c: str.toCharArray()){

if match continue, if not match if(str1 > str 2) str1 index ++

else str2 index++

}

public String substring(int begIndex);

java 复制代码
public class Solution {
    public boolean isOneEditDistance(String s, String t) {
        int m = s.length();
        int t = t.length();

        // If length difference is more than 1, return false
        if (Math.abs(m - t) > 1) {
            return false;
        }

        // Iterate through both strings
        for (int i = 0; i < Math.min(m, t); i++) {
            if (s.charAt(i) != t.charAt(i)) {
                // If strings are of same length, check for replace
                if (m == t) {
                    return s.substring(i + 1).equals(t.substring(i + 1));
                }
                // If s is longer, check for delete in s
                else if (m > t) {
                    return s.substring(i + 1).equals(t.substring(i));
                }
                // If t is longer, check for delete in t
                else {
                    return s.substring(i).equals(t.substring(i + 1));
                }
            }
        }

        // If no mismatch was found, the strings are one edit apart
        // if their lengths differ by exactly 1
        return Math.abs(m - t) == 1;
    }
}

162. Find Peak Element

162. Find Peak Element

A peak element is an element that is strictly greater than its neighbors.

Given a 0-indexed integer array nums, find a peak element, and return its index. If the array contains multiple peaks, return the index to any of the peaks.

You may imagine that nums[-1] = nums[n] = -∞. In other words, an element is always considered to be strictly greater than a neighbor that is outside the array.

You must write an algorithm that runs in O(log n) time.

Binary Search

  • nums[mid] > nums[mid-1] && nums[mid] > nums[mid+1] : mid is the peak; return mid;
  • nums[mid] < nums[mid-1]: end = mid -1
  • nums[mid] > nums[mid-1]: -> nums[mid] > nums[mid+1] start = mid + 1
java 复制代码
class Solution {
    public int findPeakElement(int[] nums) {
		if(nums.length == 1) return 0; // single element
        
        int n = nums.length;
        
		// check if 0th/n-1th index is the peak element
        if(nums[0] > nums[1]) return 0;
        if(nums[n-1] > nums[n-2]) return n-1;
		
		// search in the remaining array
        int start = 1;
        int end = n-2;
        
        while(start <= end) {
            int mid = start + (end - start)/2;
            if(nums[mid] > nums[mid-1] && nums[mid] > nums[mid+1]) return mid;
            else if(nums[mid] < nums[mid-1]) end = mid - 1;
            else if(nums[mid] < nums[mid+1]) start = mid + 1;
        }
        return -1; // dummy return statement
    }
}

165. Compare Version Numbers

165. Compare Version Numbers

Given two version numbers, version1 and version2, compare them.

Version numbers consist of one or more revisions joined by a dot '.'. Each revision consists of digits and may contain leading zeros. Every revision contains at least one character. Revisions are 0-indexed from left to right, with the leftmost revision being revision 0, the next revision being revision 1, and so on. For example 2.5.33 and 0.1 are valid version numbers.

To compare version numbers, compare their revisions in left-to-right order. Revisions are compared using their integer value ignoring any leading zeros. This means that revisions 1 and 001 are considered equal. If a version number does not specify a revision at an index, then treat the revision as 0. For example, version 1.0 is less than version 1.1 because their revision 0s are the same, but their revision 1s are 0 and 1 respectively, and 0 < 1.

Return the following:

If version1 < version2, return -1.

If version1 > version2, return 1.

Otherwise, return 0.

Compare two String/list

java 复制代码
while (i < a.length() && j < b.length()){ i++; j++; }
while(i < a.length()){ i++; }
while(j < b.length()){ j++; }
java 复制代码
class Solution {
    public int compareVersion(String version1, String version2) {
        int i = 0,j = 0;
        while(i < version1.length() && j < version2.length()){
            int a = 0,b = 0;
            while(i < version1.length() && version1.charAt(i)!='.'){
                a *= 10;
                a = a + version1.charAt(i) - '0';
                i++;
            }
            while(j < version2.length() && version2.charAt(j)!='.'){
                b *= 10;
                b = b + version2.charAt(j) - '0';
                j++;
            }
            if(a<b){
                return -1;
            } else if(a>b){
                return 1;
            }
            i++;
            j++;
        }
        while(i < version1.length()){
            if(version1.charAt(i)-'0'>0){
                return 1;
            }
            i++;
        }
        while(j < version2.length()){
            if(version2.charAt(j)-'0'>0){
                return -1;
            }
            j++;
        }
        return 0;
    }
}

166. Fraction to Recurring Decimal

166. Fraction to Recurring Decimal

Given two integers representing the numerator and denominator of a fraction, return the fraction in string format.

If the fractional part is repeating, enclose the repeating part in parentheses.

If multiple answers are possible, return any of them.

It is guaranteed that the length of the answer string is less than 104 for all the given inputs.

167. Two Sum II - Input Array Is Sorted

167. Two Sum II - Input Array Is Sorted

Given a 1-indexed array of integers numbers that is already sorted in non-decreasing order, find two numbers such that they add up to a specific target number. Let these two numbers be numbers[index1] and numbers[index2] where 1 <= index1 < index2 <= numbers.length.

Return the indices of the two numbers, index1 and index2, added by one as an integer array [index1, index2] of length 2.

The tests are generated such that there is exactly one solution. You may not use the same element twice.

Your solution must use only constant extra space.

binary search/ two pointer/ begin , end
binary search:

  1. Array
  2. Number
  3. Sorted/ Order/ Partly order
  4. Find one number
java 复制代码
class Solution {
	  public int[] twoSum(int[] numbers, int target) {
		int i=0,j=numbers.length-1;
		while(i < j){
			if(numbers[i] + numbers[j] == target) 
	            return new int[]{i+1,j+1};  
	        else if
	            (numbers[i] + numbers[j] < target)i++;
	        else 
	            j--;
	        
		}        
		return new int[]{};
	}
}

return new int[]{a,b};

168. Excel Sheet Column Title

168. Excel Sheet Column Title

Given an integer columnNumber, return its corresponding column title as it appears in an Excel sheet.

For example:

A -> 1

B -> 2

C -> 3

...

Z -> 26

AA -> 27

AB -> 28

...

Input: columnNumber = 1

Output: "A"

System of numeration: 10 decimal system, 2 binary system, 8 octal system, 16 hexadecimal system

java 复制代码
while(num>0){
	remainder = num % s;
	num = num / s; //s = 26
} 
java 复制代码
class Solution {
    public String convertToTitle(int columnNumber) {
        StringBuffer ans = new StringBuffer();
        int temp;
        while(columnNumber>0){
            //1-26 remainder
            columnNumber--;
            temp = columnNumber%26;
            ans.append((char)(temp+'A'));
            columnNumber /=26;
        }
        return ans.reverse().toString();
    }
}

169. Majority Element

169. Majority Element

Given an array nums of size n, return the majority element.

The majority element is the element that appears more than ⌊n / 2⌋ times. You may assume that the majority element always exists in the array.
Follow-up: Could you solve the problem in linear time and in O(1) space?

Sorting

java 复制代码
class Solution {
    public int majorityElement(int[] nums) {
        Arrays.sort(nums);
        int i;
        int count = 1;
        int n = nums.length/2;
        for(i = 0; i < nums.length-2; i++){
            while(nums[i]==nums[i+1] && i < nums.length-2){
                i++;
                count++;
                if(count>n) return nums[i];
            }
            if(nums[i]!=nums[i+1]){
                count=1;
            }
        }
        return nums[nums.length-1];
    }
}
java 复制代码
public int majorityElement1(int[] nums) {
    Arrays.sort(nums);
    return nums[nums.length/2];
}

171. Excel Sheet Column Number

171. Excel Sheet Column Number

Given a string columnTitle that represents the column title as appears in an Excel sheet, return its corresponding column number.

For example:

A -> 1

B -> 2

C -> 3

...

Z -> 26

AA -> 27

AB -> 28

...

Example 1:

Input: columnTitle = "A"

Output: 1

from left to right

java 复制代码
while(){
	a *= n; //26
	a += x; //1-26
	}
java 复制代码
class Solution {
    public int titleToNumber(String columnTitle) {
        int ans = 0;
        int i;
        for(i = 0; i < columnTitle.length(); i++){
            ans *= 26;
            ans = ans+columnTitle.charAt(i)-'A'+1; 
        }
        return ans;
    }
}

172. Factorial Trailing Zeroes

172. Factorial Trailing Zeroes

Given an integer n, return the number of trailing zeroes in n!.

Note that n! = n * (n - 1) * (n - 2) * ... * 3 * 2 * 1.

Count factor 2 and 5. Trailing zeros are produce by 2 * 5 only.

count2[n] : how many factor 2 n process.

java 复制代码
    public int trailingZeroes(int n) {
        //2*5 = 10
        if(n<=4){
            return 0;
        }
        int[] count2 = new int[n+1];
        int[] count5 = new int[n+1];
        int c2 = 0;
        int c5 = 0;
        count2[2] = 1;
        count5[5] = 1;
        for(int i = 1; i <= n; i++){
            if(i%2==0){
                count2[i] = 1 + (count2[i/2]);
                c2 += count2[i];
            }
            if(i%5==0){
                count5[i] = 1 + (count5[i/5]);
                c5 += count5[i];
            }
        }
        if(c2 > 0 && c5 > 0){
            return Math.min(c2,c5);
        }
        return 0;
        
    }
}

173. Binary Search Tree Iterator

Implement the BSTIterator class that represents an iterator over the in-order traversal of a binary search tree (BST):

BSTIterator(TreeNode root) Initializes an object of the BSTIterator class. The root of the BST is given as part of the constructor. The pointer should be initialized to a non-existent number smaller than any element in the BST.

boolean hasNext() Returns true if there exists a number in the traversal to the right of the pointer, otherwise returns false.

int next() Moves the pointer to the right, then returns the number at the pointer.

Notice that by initializing the pointer to a non-existent smallest number, the first call to next() will return the smallest element in the BST.

You may assume that next() calls will always be valid. That is, there will be at least a next number in the in-order traversal when next() is called.

179. Largest Number

179. Largest Number

Given a list of non-negative integers nums, arrange them such that they form the largest number and return it.

Since the result may be very large, so you need to return a string instead of an integer.
Constraints:

1 <= nums.length <= 100

0 <= nums[i] <= 109

Costom compare and sort the array.

The implementation of the compare() method should return

  • a negative integer, if the first argument is less than the second,
  • zero, if the first argument is equal to the second, and
  • a positive integer, if the first argument is greater than the second.

Greedy

3、4、30 : 43 > 34 > 30

Method 2:

Compare with the String. s1 = a + b, s2 = b + a;
Costom compare

java 复制代码
class Solution {
    public String largestNumber(int[] nums) {
        StringBuffer sb = new StringBuffer();
        String[] arr = new String[nums.length];
        for(int i = 0; i < nums.length; i++){
            arr[i] = nums[i] +"";
        }
        Arrays.sort(arr,(a,b)->{
            String s1 = a + b;
            String s2 = b + a;
            return s2.compareTo(s1);
        });
        for(String n:arr){
            sb.append(n);
        }
        if(sb.charAt(0)=='0'){
            return "0";
        }
        return sb.toString();
    }
}

5ms 99.03% 41.9% 89.78%

custom sort / compare

  • compareTo()

The compareTo() method compares two strings lexicographically .

The comparison is based on the Unicode value of each character in the strings.

Returns: An int value:

  • 0 if the string is equal to the other string.
  • < 0 if the string is lexicographically less than the other string
  • > 0 if the string is lexicographically greater than the other string (more characters)

override the comparator

Comparison with Lambda

java 复制代码
        Arrays.sort(arr,(a,b)->{
            String s1 = a + b;
            String s2 = b + a;
            return s2.compareTo(s1);
        });

Override the comparator classic

java 复制代码
        Arrays.sort(temp, new Comparator<String>(){
            @Override
            public int compare(String a, String b) {
            	String s1 = a + b;
            	String s2 = b + a;
                return s2.compareTo(s1);
            }
        });

Override the comparator

java 复制代码
		// Comparator to decide which string should come first in concatenation
		Comparator<String> comp = new Comparator<String>(){
		    @Override
		    public int compare(String str1, String str2){
		        String s1 = str1 + str2;
				String s2 = str2 + str1;
				return s2.compareTo(s1); // reverse order here, so we can do append() later
		    }
	     };
		
		Arrays.sort(s_num, comp);

As we know, there are basically two types of sorting technique in Java:

  • First is internal sorting i.e that uses predefined sorting method ascending order Arrays.sort() and Collections.sort() . Both methods sort the elements in ascending order.

  • The second technique is for sorting the elements is using the comparator or comparable interface in a class .

    Comparator Interface: Implement the comparator interface in the class and override compare() method or pass the new comparator as the second argument in the sorting methods and change the sorting order according to the requirements. Comparator only works for wrapper type arrays and for collections like vector, ArrayList, etc.

Comparable Interface: This interface implements a single sorting technique, and it affects the whole class. The comparable interface provides a compareTo() method to sort the elements. Overriding of the compareTo() Method.

Sort array in the descending order

java 复制代码
Arrays.sort(arr, Collections.reverseOrder());

187. Repeated DNA Sequences

187. Repeated DNA Sequences

The DNA sequence is composed of a series of nucleotides abbreviated as 'A', 'C', 'G', and 'T'.

For example, "ACGAATTCCG" is a DNA sequence.

When studying DNA, it is useful to identify repeated sequences within the DNA.

Given a string s that represents a DNA sequence, return all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule. You may return the answer in any order.
Example 1:

Input: s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"

Output: ["AAAAACCCCC","CCCCCAAAAA"]

Example 2:

Input: s = "AAAAAAAAAAAAA"

Output: ["AAAAAAAAAA"]
Constraints:

1 <= s.length <= 105

s[i] is either 'A', 'C', 'G', or 'T'.

Find a particular Sequence in String : Sliding window [ left, right ]

Check every 10-length substring. Add to the HashSet and check.
One Loop. O(n).

Check whether current subsequence is existed in the set.

If true, add it to the result. Else, add it to the set.

java 复制代码
class Solution {
    public List<String> findRepeatedDnaSequences(String s) {
        int right = 10,left = 0;
        List<String> ansList = new ArrayList<>();
        if(s.length() < 11){
            return ansList;
        }
        HashSet<String> set = new HashSet<>();
        set.add(s.substring(left,right));
        right++;
        left++;
        while(right <= s.length()){
            String ans = s.substring(left,right);
            if(set.contains(ans)){
                if(!ansList.contains(ans)){
                    //skip duplicate answer
                    ansList.add(ans);
                }
            }else{
                set.add(ans);
            }
            left++;
            right++;
        }
        return ansList;

    }
}

17ms 89.51% 50.9MB 86.25%

Time Limit Exceeded

For every 10-length sequence check whether is duplicate by followed substring. If true, add it to the set. Return the set convert to list.

Has a lot of repetition. Check with nested loop. O(n^2)

java 复制代码
class Solution {
    public List<String> findRepeatedDnaSequences(String s) {
        int right = 10,left = 0;
        List<String> ansList = new ArrayList<>();
        if(s.length() < 11){
            return ansList;
        }
        HashSet<String> set = new HashSet<>();
        while(right <= s.length()){
            int i = 1;
            while(right + i<= s.length()){
                if(s.substring(left,right).equals(s.substring(left+i,right+i))){
                    String ans = s.substring(left,right);
                    if(!set.contains(ans)){
                        ansList.add(ans);
                        set.add(ans);
                    }
                    break;
                }
                else{
                    i++;
                }
            }
            left++;
            right++;
        }
        return ansList;
    }
}

189. Rotate Array

189. Rotate Array

Given an array, rotate the array to the right by k steps, where k is non-negative.
Input: nums = [1,2,3,4,5,6,7], k = 3

Output: [5,6,7,1,2,3,4]

Explanation:

rotate 1 steps to the right: [7,1,2,3,4,5,6]

rotate 2 steps to the right: [6,7,1,2,3,4,5]

rotate 3 steps to the right: [5,6,7,1,2,3,4]
Try to come up with as many solutions as you can. There are at least three different ways to solve this problem.

Could you do it in-place with O(1) extra space?

Swap the array
WIth extra space: Move the element to it defined location. -> Build a k-size storage space Store before you move
WIthout extra space: Divide the array into two part, these two parts change their position as a whole.

-> Reverse

1 2 3 4 5 6 7

Reverse the front len-k element: 4 3 2 1 | 5 6 7 |

Reverse the back k element: 4 3 2 1 | 7 6 5

Reverse all: 5 6 7 1 2 3 4

java 复制代码
class Solution {
    public void rotate(int[] nums, int k) {
        //if(i+k<len) i->i+k else i->i+k-len

        if(nums.length==1){
            return;
        }
        if(k>nums.length){
            k = k % nums.length;
        }
        reverse(nums,0,nums.length-k-1);
        reverse(nums,nums.length-k,nums.length-1);
        reverse(nums,0,nums.length-1);
    }
    //i end-start-i
    private void reverse(int[] arr,int start,int end){
        int temp;
        int i = start,j = end; 
        while(i<j){
            temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
            i++;
            j--;
        }
    }
}

1ms 89.73% 58.2MB 85.97%

190. Reverse Bits

190. Reverse Bits

Reverse bits of a given 32 bits unsigned integer.
Example 1:

Input: n = 00000010100101000001111010011100

Output: 964176192 (00111001011110000010100101000000)

Explanation: The input binary string 00000010100101000001111010011100 represents the unsigned integer 43261596, so return 964176192 which its binary representation is 00111001011110000010100101000000.

Example 2:

Input: n = 11111111111111111111111111111101

Output: 3221225471 (10111111111111111111111111111111)

Explanation: The input binary string 11111111111111111111111111111101 represents the unsigned integer 4294967293, so return 3221225471 which its binary representation is 10111111111111111111111111111111.
Constraints:

The input must be a binary string of length 32

Bitwise operation

Integer.parseInt();

Integer.parseUnsignedInt();

java 复制代码
public class Solution {
    // you need treat n as an unsigned value
    public int reverseBits(int n) {
        StringBuilder sb = new StringBuilder();
        int count = 32;
        while(count > 0){
            sb.append((n&1));
            n >>= 1;
            count--;
        }
        return Integer.parseUnsignedInt(sb.toString(),2);
        
    }
}

1 ms 97.06% 42.1 MB 68.24%

StringBuilder is faster than StringBuffer but it is thread unsafe.

  • Integer.parseInt();

This method is used to get the primitive data type of a certain String. parseXxx() is a static method and can have one argument or two.

Syntax

  • static int parseInt(String s)
  • static int parseInt(String s, int radix)

Parameters

  • s − This is a string representation of decimal.
  • radix − This would be used to convert String s into integer. (10, 2, 8, or 16)

Return Value

parseInt(String s) − This returns an integer (decimal only).

parseInt(String s, int i) − This returns an integer, given a string representation of decimal, binary, octal, or hexadecimal (radix equals 10, 2, 8, or 16 respectively) numbers as input.

  • Integer.parseUnsignedInt();
  1. Java Integer parseUnsignedInt (String s) Method
  2. Java Integer parseUnsignedInt (String s, int radix) Method
  3. Java Integer parseUnsignedInt (CharSequence s, int beginText, int endText, int radix) Method
java 复制代码
//Notes
public class Solution {
    // you need treat n as an unsigned value
    /*
1. &按位与 两个为真才为真 1&1=1 , 1&0=0 , 0&1=0 , 0&0=0
2. | 按位或  一个为真即为真  1|0 = 1 , 1|1 = 1 , 0|0 = 0 , 0|1 = 1
3. ^ 异或运算符 1^0 = 1 , 1^1 = 0 , 0^1 = 1 , 0^0 = 0
4.  <<左移运算符
			5<<2的意思为5的二进制位往左挪两位,右边补0,5的二进制位是0000 0101 , 就是把有效值101往左挪两位就是0001 0100 ,正数左边第一位补0,负数补1,等于乘于2的n次方
 5. >>右移运算符
		 凡位运算符都是把值先转换成二进制再进行后续的处理,5的二进制位是0000 0101,右移两位就是把101左移后为0000 0001,正数左边第一位补0,负数补1,等于除于2的n次方,结果为1
6. 	~ 取反运算符 
		取反就是1为0,0为1,5的二进制位是0000 0101,取反后为1111 1010,值为-6
7. >>>无符号右移运算符 
*/
    public int reverseBits(int num) {
        int ans = 0;
        for(int i = 0; i < 32; i++){
            ans <<= 1;//左移让出一位新的空间,并且使先加进去的到最前面,实现翻转
            ans += (num>>i)&1; 
            //1只有一位所以的num的最右位与1与,通过>>i,随i增大,逐渐从右到左访问num的每一位
        }
        return ans;  
    }

1 ms 97.06% 41.5 MB 90.73%

191. Number of 1 Bits

191. Number of 1 Bits

Write a function that takes an unsigned integer and returns the number of '1' bits it has (also known as the Hamming weight).
Example 1:

Input: n = 00000000000000000000000000001011

Output: 3

Explanation: The input binary string 00000000000000000000000000001011 has a total of three '1' bits.

Example 2:

Input: n = 00000000000000000000000010000000

Output: 1

Explanation: The input binary string 00000000000000000000000010000000 has a total of one '1' bit.

Example 3:

Input: n = 11111111111111111111111111111101

Output: 31

Explanation: The input binary string 11111111111111111111111111111101 has a total of thirty one '1' bits.
Constraints:

The input must be a binary string of length 32.

Follow up: If this function is called many times, how would you optimize it?

bitwise & 1

Wrong. Can't use n > 0 as the loop condition, because the most signification bit is sign bit.

A positive integer starts with a 0, while a negative integer starts with a 1.

java 复制代码
public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
        int count = 0;
        while(n > 0){
            count += (n&1); 
            n >>= 1;
        }
        return count;
    }
}

Input 11111111111111111111111111111101

Output 0

Expected 31
Your input 10000000000000000000000000000000

Output 0

Expected 1

AC

Control 32 times >>

java 复制代码
public class Solution {
    // you need to treat n as an unsigned value
    //右移>>是指带符号右移,如果最高位的符号位为1,则右移时左侧补上的空位用1填充,否则用0填充
    //而无符号右移>>>,不管左侧最高位是1还是0,左侧补上的空位统统用0填充
    public int hammingWeight(int n) {
        int ans = 0;
        for(int i = 0; i < 32; i++){
            if(((n>>i)&1)==1){
                ans++;
            }
        }
        return ans;
    }
}
java 复制代码
public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
        int count = 0;
        int num = 32;
        while(num > 0){
            count += (n&1); 
            n >>= 1;
            num--;
        }
        return count;
    }
}
Name of operator Sign Description
Signed Right Shift >> The right shift operator moves all bits by a given number of bits to the right. Doesn't change the sign bit.
Signed Left Shift << The left shift operator moves all bits by a given number of bits to the left. Doesn't change the sign bit.
Unsigned Right Shift >>> It is the same as the signed right shift, but the vacant leftmost position is filled with 0 instead of the sign bit

198. House Robber

198. House Robber

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 systems connected and it will automatically contact the police if two adjacent houses were broken into on the same night.

Given an integer array nums representing the amount of money of each house, return the maximum amount of money you can rob tonight without alerting the police.
Example 1:

Input: nums = [1,2,3,1]

Output: 4

Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).

Total amount you can rob = 1 + 3 = 4.

Example 2:

Input: nums = [2,7,9,3,1]

Output: 12

Explanation: Rob house 1 (money = 2), rob house 3 (money = 9) and rob house 5 (money = 1).

Total amount you can rob = 2 + 9 + 1 = 12.
Constraints:

1 <= nums.length <= 100

0 <= nums[i] <= 400

DP

for the current house, there are two choices: rob or not

  • rob : dp[ i ] = nums[ i ] + dp[ i - 2 ]
  • not rob : dp[ i ] = dp[ i -1 ]
    dp[ i ] = max (nums[ i ] + dp[ i - 2 ] , dp[ i -1 ])
java 复制代码
class Solution {
    public int rob(int[] nums) {
        //can't rob adjacent house
        if(nums.length == 1) return nums[0];
        if(nums.length == 2) return Math.max(nums[0],nums[1]);
        
        int[] note = new int[nums.length];
        note[0] = nums[0];
        note[1] = Math.max(nums[0],nums[1]);
        //rob this house or rob former house
        for(int i = 2; i < nums.length; i++){
            note[i] = Math.max(note[i-2]+nums[i],note[i-1]);
        }
        return note[nums.length-1];
    }
}

0ms 100% 39.7MB 66.74%

199. Binary Tree Right Side View

199. Binary Tree Right Side View

Given the root of 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.
Example 1:

Input: root = [1,2,3,null,5,null,4]

Output: [1,3,4]

Example 2:

Input: root = [1,null,3]

Output: [1,3]

Example 3:

Input: root = []

Output: []
Constraints:

The number of nodes in the tree is in the range [0, 100].

-100 <= Node.val <= 100

BFS level travese + read the last node in each level

java 复制代码
class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        List<Integer> ans = new ArrayList<>();
        Queue<TreeNode> q = new LinkedList<>();
        TreeNode p = root;
        if(root == null){
            return ans;
        }
        q.offer(root);
        while(!q.isEmpty()){
            int size = q.size();
            for(int i = 0; i < size; i++){
                p = q.peek();
                q.poll();
                if(p.left!=null)
                    q.offer(p.left);
                if(p.right!=null)
                    q.offer(p.right);
            }
            ans.add(p.val);
            
        }
        return ans;
    }
}

1 ms 90.33% 41.1 MB 81.46%

Queue in Java

Interface Queue< E >

All Superinterfaces:

Collection< E >, Iterable< E >

All Known Implementing Classes:

AbstractQueue, ArrayBlockingQueue, ArrayDeque, ConcurrentLinkedDeque, ConcurrentLinkedQueue, DelayQueue, LinkedBlockingDeque, LinkedBlockingQueue, LinkedList, LinkedTransferQueue, PriorityBlockingQueue, PriorityQueue, SynchronousQueue

Summary of Queue methods

Throws exception Returns special value
Insert add(e) offer(e)
Remove remove() poll()
Examine element() peek()

The offer method inserts an element if possible, otherwise returning false. This differs from the Collection.add method, which can fail to add an element only by throwing an unchecked exception. The offer method is designed for use when failure is a normal, rather than exceptional occurrence, for example, in fixed-capacity (or "bounded") queues.

The remove() and poll() methods remove and return the head of the queue. Exactly which element is removed from the queue is a function of the queue's ordering policy, which differs from implementation to implementation. The remove() and poll() methods differ only in their behavior when the queue is empty: the remove() method throws an exception, while the poll() method returns null.

The element() and peek() methods return, but do not remove, the head of the queue.

200. Number of Islands

200. Number of Islands

Given an m x n 2D binary grid grid which represents a map of '1's (land) and '0's (water), return 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:

Input: grid = [

"1","1","1","1","0"\], \["1","1","0","1","0"\], \["1","1","0","0","0"\], \["0","0","0","0","0"

]

Output: 1

Example 2:

Input: grid = [

"1","1","0","0","0"\], \["1","1","0","0","0"\], \["0","0","1","0","0"\], \["0","0","0","1","1"

]

Output: 3
Constraints:

m == grid.length

n == grid[i].length

1 <= m, n <= 300

grid[i][j] is '0' or '1'.

DFS Traverse every node, if it is in a island. Traverse the island by search every four direction and mark after visiting. Traverse the whole grid and can get how many land are there.

visit land, count, change land into water

No need to use the extra visited array. Change the '1' into '0' in place. Use the given grid to mark the visited.

int[][] directions = {{0,1},{1,0},{0,-1},{-1,0}};

java 复制代码
class Solution {
    public int numIslands(char[][] grid) {
        //DFS See how many connected domains there are. Once you find a connected domain, set it as visited 
        int ans = 0;
        for(int i = 0; i < grid.length; i++){
            for(int j = 0; j < grid[0].length; j++){
                if(grid[i][j]=='1'){
                    dfs(grid,i,j);
                    ans++;
                }
            }
        }
        return ans;
    }
    private void dfs(char[][] grid,int x,int y){
        grid[x][y] = '0';
        // java Two-dimensional arrays {{},{}}
        int[][] turn = {{0,1},{1,0},{0,-1},{-1,0}};

        int dx,dy;
        for(int i = 0; i < 4; i++){
            dx = x + turn[i][0];
            dy = y + turn[i][1]; 
            if(dx >= 0 && dy >= 0 && dx < grid.length && dy < grid[0].length && grid[dx][dy]=='1'){
                dfs(grid,dx,dy);
                }
        }
    }
}

6 ms 62.81% 52.1 MB 71.29%

对于你的 DFS 解法,时间复杂度分析如下:

遍历网格:外层双重循环遍历了整个网格,每个元素只被访问一次,因此遍历网格的时间复杂度是 O(M×N),其中 M 和 N 分别是网格的行数和列数。

DFS 递归:在最坏情况下,每次 dfs 调用都可能遍历一个完整的岛屿区域,每个元素也只会被访问一次。因此 DFS 的每次调用最多也是 O(M×N),不过由于每个元素只访问一次,整体的时间复杂度仍然是 O(M×N)。

因此,DFS 解法的总体时间复杂度是 O(M×N)

Method Easy to remeber

java 复制代码
class Solution {
public int numIslands(char[][] grid) {
    int count=0;
    for(int i=0;i<grid.length;i++)
        for(int j=0;j<grid[0].length;j++){
            if(grid[i][j]=='1'){
                dfsFill(grid,i,j);
                count++;
            }
        }
    return count;
}
private void dfsFill(char[][] grid,int i, int j){
    if(i>=0 && j>=0 && i<grid.length && j<grid[0].length&&grid[i][j]=='1'){
        grid[i][j]='0';
        dfsFill(grid, i + 1, j);
        dfsFill(grid, i - 1, j);
        dfsFill(grid, i, j + 1);
        dfsFill(grid, i, j - 1);
    }
}
}

4 ms 80.84% 58 MB 17.83%

Method Easy to remeber

java 复制代码
class Solution {
    public int numIslands(char[][] grid) {
        int ans = 0;
        for(int i = 0; i < grid.length; i++){
            for(int j = 0; j < grid[0].length; j++){
                if(grid[i][j]=='1'){
                    dfs(grid,i,j);
                    ans++;
                }
            }
        }
        return ans;
    }
    private void dfs(char[][] grid,int x,int y){
        grid[x][y] = '0';
        if(x+1>=0 && x+1<grid.length &&grid[x+1][y]=='1'){
            dfs(grid,x+1,y);
        }
        if(x-1>=0 && x-1<grid.length &&grid[x-1][y]=='1'){
            dfs(grid,x-1,y);
        }
        if(y+1>=0 && y+1<grid[0].length &&grid[x][y+1]=='1'){
            dfs(grid,x,y+1);
        }
        if(y-1>=0 && y-1<grid[0].length &&grid[x][y-1]=='1'){
            dfs(grid,x,y-1);
        }
    }
}

4 ms 80.84% 57.8 MB 26.58%

Union Find

将网格中的每个陆地 1 看作是并查集中的一个节点,并且将相邻的陆地进行合并。在最终的并查集中,连通分量的数量就是岛屿的数量。

并查集解法的步骤

初始化并查集:为每个陆地 1 初始化一个独立的集合。

遍历网格:对于每一个陆地,如果其上下左右存在陆地,则将它们合并到同一个集合中。

统计岛屿数量:最终统计并查集中不同连通分量的数量,这个数量就是岛屿的数量。

相关推荐
永远有多远.3 小时前
【CCF-CSP】第39次CSP认证前三题
算法
墨染点香4 小时前
LeetCode 刷题【90. 子集 II】
算法·leetcode·职场和发展
Code_LT6 小时前
【算法】多榜单排序->综合排序问题
人工智能·算法
Tiny番茄6 小时前
146. LRU缓存
数据结构·leetcode·缓存
仟濹6 小时前
【力扣LeetCode】 1413_逐步求和得到正数的最小值
算法·leetcode·职场和发展
9毫米的幻想6 小时前
【Linux系统】—— 进程切换&&进程优先级&&进程调度
linux·运维·服务器·c++·学习·算法
YoungHong19928 小时前
面试经典150题[037]:矩阵置零(LeetCode 73)
leetcode·面试·矩阵
西阳未落9 小时前
数据结构初阶——哈希表的实现(C++)
算法·哈希算法·散列表
未知陨落9 小时前
LeetCode:46.二叉树展开为链表
算法·leetcode·链表