svilme

svilme

Huawei Autumn Recruitment Sprint Question Review Notes

The link to the problem: https://blog.csdn.net/weixin_43731108/article/details/136383904

5. Longest Palindromic Substring#

class Solution {
    public String longestPalindrome(String s) {
        // Dynamic programming
        // dp[i][j] indicates that the substring [i, j] is a palindrome
        // char(i) == char(j) dp[i][j] = dp[i+1][j-1]
        boolean[][] dp = new boolean[s.length()][s.length()];
        for (int i = 0; i < s.length(); i++) {
            dp[i][i] = true;
        }
        int start = 0;
        int right = 0;
        for (int i = s.length() - 1; i >= 0; i--) {
            for (int j = i + 1; j < s.length(); j++) {
                if (j == i + 1) {
                    dp[i][j] = (s.charAt(i) == s.charAt(j));
                } else {
                    dp[i][j] = (s.charAt(i) == s.charAt(j)) && dp[i + 1][j - 1];
                }
                if (dp[i][j] == true && j - i + 1 > right - start + 1) {
                    start = i;
                    right = j;
                }
            }
        }
        return s.substring(start, right + 1);
    }
}
class Solution {
    public String longestPalindrome(String s) {
        // Expand from the center
        int maxLen = 0;
        int start = 0;
        int end = 0;
        for (int i = 0; i < s.length() - 1; i++) {
            int left = i - 1;
            int right = i + 1;
            int count = 1;
            // Centered on a single character
            while (left >= 0 && right <= s.length() - 1 && s.charAt(left) == s.charAt(right)) {
                count += 2;
                left--;
                right++;
            }
            if (count > maxLen) {
                start = left + 1;
                end = right - 1;
                maxLen = count;
            }
            // Centered on two characters
            if (i < s.length() - 1 && s.charAt(i) == s.charAt(i + 1)) {
                left = i - 1;
                right = i + 2;
                count = 2;
                while (left >= 0 && right <= s.length() - 1 && s.charAt(left) == s.charAt(right)) {
                    count += 2;
                    left--;
                    right++;
                }
                if (count > maxLen) {
                    start = left + 1;
                    end = right - 1;
                    maxLen = count;
                }
            }
        }
        return s.substring(start, end + 1);
    }
}

151. Reverse Words in a String#

class Solution {
    public String reverseWords(String s) {
        // Two pointers from the end to find words
        int left = s.length() - 1;
        int right = s.length() - 1;
        StringBuilder sb = new StringBuilder();
        while (left >= 0) {
            while (left >= 0 && s.charAt(left) == ' ') {
                left--;
            }
            right = left;
            while (left >= 0 && s.charAt(left) != ' ') {
                left--;
            }
            sb.append(s.substring(left + 1, right + 1)).append(" ");
        }
        return sb.toString().trim();
    }
}

You can also find words from front to back and insert them at the front (StringBuilder or deque).

186. Reverse Words in a String II 🔒#

Given a character array s, reverse the order of words in it.

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

You must design and implement an in-place solution to solve this problem, meaning no extra space should be allocated.

Example 1:

Input: s = ["t","h","e"," ","s","k","y"," ","i","s"," ","b","l","u","e"]
Output: ["b","l","u","e"," ","i","s"," ","s","k","y"," ","t","h","e"]

Example 2:

Input: s = ["a"]
Output: ["a"]

Constraints:

  • 1 <= s.length <= 105
  • s[i] can be an English letter (uppercase or lowercase), a digit, or a space ' '.
  • There is at least one word in s
  • s does not contain leading or trailing spaces
  • The problem guarantees that each word in s is separated by a single space
class Solution {
    public void reverseWords(char[] s) {
        int n = s.length;
        int left = 0, right = 0;
        reverse(s, 0, n-1);
        while (right < n) {
            while (right<n && s[right] != ' ') {
                right++;
            }
            reverse(s, left, right - 1);
            right++;
            left = right;
        }
    }

    private void reverse(char[] s, int i, int j) {
        while(i<j) {
            char t = s[i];
            s[i] = s[j];
            s[j] = t;
            i++;
            j--;
        }
    }
}

328. Odd Even Linked List#

/**
 * Definition for singly-linked list.
 * public class ListNode {
 * int val;
 * ListNode next;
 * ListNode() {}
 * ListNode(int val) { this.val = val; }
 * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode oddEvenList(ListNode head) {
        if (head == null || head.next == null || head.next.next == null) {
            return head;
        }
        // Separate odd and even linked lists
        ListNode odd = head; // Starting point of odd list
        ListNode even = head.next; // Starting point of even list
        ListNode evenHead = even; // Save the starting point of the even node list
        while (even != null && even.next != null) {
            odd.next = even.next;
            even.next = odd.next.next;
            odd = odd.next;
            even = even.next;
        }
        odd.next = evenHead;
        return head;
    }
}

205. Isomorphic Strings#

class Solution {
    public boolean isIsomorphic(String s, String t) {
        HashMap<Character, Character> reflection = new HashMap<>();
        HashSet<Character> ref_set = new HashSet<>();
        int len = s.length();
        for (int i = 0; i < len; i++) {
            char ch_s = s.charAt(i);
            char ch_t = t.charAt(i);
            if (reflection.containsKey(ch_s)) {
                if (reflection.get(ch_s) != ch_t) {
                    return false;
                }
            } else {
                if (ref_set.contains(ch_t)) {
                    return false; // Different characters mapped to the same character
                }
                reflection.put(ch_s, ch_t);
                ref_set.add(ch_t); // Add the character that has been mapped
            }
        }
        return true;
    }
}

206. Reverse Linked List#

/**
 * Definition for singly-linked list.
 * public class ListNode {
 * int val;
 * ListNode next;
 * ListNode() {}
 * ListNode(int val) { this.val = val; }
 * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode pre = null;
        ListNode cur = head;
        while (cur != null) {
            ListNode nxt = cur.next;
            cur.next = pre;
            pre = cur;
            cur = nxt;
        }
        return pre;
    }
}

15. 3Sum#

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums); // Sort
        for (int i = 0; i < nums.length; i++) { // First determine an i
            if (nums[i] > 0) {
                return res;
            }
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue; // Deduplicate i
            }
            int left = i + 1; // Two pointers
            int right = nums.length - 1;
            while (left < right) {
                int sum = nums[i] + nums[left] + nums[right];
                if (sum > 0) {
                    right--;
                } else if (sum < 0) {
                    left++;
                } else {
                    res.add(Arrays.asList(nums[i], nums[left], nums[right]));
                    while (left < right && nums[left] == nums[left + 1]) {
                        left++; // Deduplicate left
                    }
                    while (right > left && nums[right] == nums[right - 1]) {
                        right--; // Deduplicate right
                    }
                    left++;
                    right--;
                }
            }
        }
        return res;
    }
}

213. House Robber II#

class Solution {
    public int rob(int[] nums) {
        // situation1: do not rob the first house
        // situation2: do not rob the last house -> degenerates to the ordinary house robber
        if (nums.length == 0) {
            return 0;
        }
        if (nums.length == 1) {
            return nums[0];
        }
        return Math.max(robRange(nums, 0, nums.length - 2), robRange(nums, 1, nums.length - 1));

    }

    int robRange(int[] nums, int start, int end) {
        if (end == start) {
            return nums[start];
        }
        // dp[i]: the maximum amount that can be stolen considering the houses up to index i (including i)
        int[] dp = new int[nums.length];
        dp[start] = nums[start];
        dp[start + 1] = Math.max(nums[start], nums[start + 1]);
        for (int i = start + 2; i <= end; i++) {
            dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
        }
        return dp[end];
    }
}

71. Simplify Path#

class Solution {
    public String simplifyPath(String path) {
        String[] names = path.split("/");
        Deque<String> stack = new ArrayDeque<>(); // Stack or queue
        for (String name : names) {
            if ("..".equals(name)) { // Parent directory
                if (!stack.isEmpty()) {
                    stack.pollLast();
                }
            } else if (name.length() > 0 && !".".equals(name)) { // Ignore current directory
                stack.offerLast(name);
            }
        }
        StringBuilder sb = new StringBuilder();
        if (stack.isEmpty()) {
            sb.append("/");
        } else {
            while (!stack.isEmpty()) {
                sb.append("/");
                sb.append(stack.pollFirst());
            }
        }
        return sb.toString();
    }
}

1. Two Sum#

class Solution {
    public int[] twoSum(int[] nums, int target) {
        // Number, index
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            if (map.containsKey(target - nums[i])) {
                return new int[] { map.get(target - nums[i]), i };
            } else {
                map.put(nums[i], i);
            }
        }
        return new int[2];
    }
}

1239. Maximum Length of a Concatenated String with Unique Characters#

class Solution {
    int res = 0;

    public int maxLength(List<String> arr) {
        boolean[] charset = new boolean[26]; // Used to detect duplicate characters
        backtrack(arr, 0, charset, 0);
        return res;
    }

    void backtrack(List<String> arr, int start, boolean[] charset, int count) {
        res = Math.max(res, count); // Update the maximum value each time

        for (int i = start; i < arr.size(); i++) {
            char[] chars = arr.get(i).toCharArray();
            boolean[] charset_copy = charset.clone();
            boolean flag = false;
            for (int j = 0; j < chars.length; j++) {
                if (charset_copy[chars[j] - 'a'] == true) { // Duplicate character
                    flag = true;
                    break;
                } else {
                    charset_copy[chars[j] - 'a'] = true;
                }
            }
            if (flag == true) {
                continue;
            }
            backtrack(arr, i + 1, charset_copy, count + chars.length);
        }
    }
}

54. Spiral Matrix#

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> res = new ArrayList<>();
        // Define the four boundaries: up, down, left, right
        int up_bound = 0, down_bound = matrix.length - 1;
        int left_bound = 0, right_bound = matrix[0].length - 1;
        while (up_bound <= down_bound && left_bound <= right_bound) {
            if (up_bound <= down_bound) { // Up
                for (int i = left_bound; i <= right_bound; i++) {
                    res.add(matrix[up_bound][i]);
                }
                up_bound++;
            }
            if (left_bound <= right_bound) {// Right
                for (int i = up_bound; i <= down_bound; i++) {
                    res.add(matrix[i][right_bound]);
                }
                right_bound--;
            }
            if (up_bound <= down_bound) {// Down
                for (int i = right_bound; i >= left_bound; i--) {
                    res.add(matrix[down_bound][i]);
                }
                down_bound--;
            }
            if (left_bound <= right_bound) { // Left
                for (int i = down_bound; i >= up_bound; i--) {
                    res.add(matrix[i][left_bound]);
                }
                left_bound++;
            }

        }
        return res;
    }
}

1143. Longest Common Subsequence#

class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
        // Dynamic programming
        // dp[i][j] indicates the longest common subsequence value of the substring of text1 ending at index i-1 and the substring of text2 ending at index j-1
        // char_i == char_j dp[i][j] = dp[i-1][j-1] + 1
        // or dp[i][j] = max(dp[i-1][j], dp[i][j-1])
        // dp[0][j] = 0; dp[i][0] = 0;
        int[][] dp = new int[text1.length() + 1][text2.length() + 1];
        for (int i = 1; i <= text1.length(); i++) {
            for (int j = 1; j <= text2.length(); j++) {
                if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }
        return dp[text1.length()][text2.length()];
    }
}

415. Add Strings#

class Solution {
    public String addStrings(String num1, String num2) {
        int ptr1 = num1.length() - 1; // Two pointers
        int ptr2 = num2.length() - 1;
        int carry = 0; // Carry
        StringBuilder sb = new StringBuilder();
        while (ptr1 >= 0 && ptr2 >= 0) {
            int a = num1.charAt(ptr1) - '0';
            int b = num2.charAt(ptr2) - '0';
            sb.append((a + b + carry) % 10);
            carry = (a + b + carry) / 10;
            ptr1--;
            ptr2--;
        }
        while (ptr1 >= 0) {
            int a = num1.charAt(ptr1) - '0';
            sb.append((a + carry) % 10);
            carry = (a + carry) / 10;
            ptr1--;
        }
        while (ptr2 >= 0) {
            int b = num2.charAt(ptr2) - '0';
            sb.append((b + carry) % 10);
            carry = (b + carry) / 10;
            ptr2--;
        }
        if (carry != 0) {
            sb.append(carry);
        }
        return sb.reverse().toString();
    }
}

1006. Clumsy Factorial#

This problem can be simulated using a stack, and it doesn't need to be overly complicated.

class Solution {
    public int clumsy(int n) {
        Deque<Integer> stack = new ArrayDeque<>();
        stack.push(n); // First push n onto the stack
        n--;
        int index = 0; // Used to track the operator to be used

        while (n > 0) {
            if (index % 4 == 0) {
                // Multiplication
                stack.push(stack.pop() * n);
            } else if (index % 4 == 1) {
                // Division
                stack.push(stack.pop() / n);
            } else if (index % 4 == 2) {
                // Addition
                stack.push(n);
            } else {
                // Subtraction, need to push negative number onto the stack
                stack.push(-n);
            }
            n--;
            index++;
        }

        // Sum all numbers in the stack
        int result = 0;
        while (!stack.isEmpty()) {
            result += stack.pop();
        }

        return result;
    }
}

1090. Largest Values from Labels#

class Solution {
    public int largestValsFromLabels(int[] values, int[] labels, int numWanted, int useLimit) {
        // Greedy
        int n = values.length;
        Integer[] id = new Integer[n];
        for (int i = 0; i < n; i++) {
            id[i] = i; // Store indices
        }
        // Sort indices by value in descending order
        Arrays.sort(id, (a, b) -> values[b] - values[a]);
        // Label and usage count
        HashMap<Integer, Integer> map = new HashMap<>();
        int sum = 0;
        int count = 0;
        for (int i = 0; i < n; i++) {
            if (count == numWanted) {
                break;
            }
            if (map.getOrDefault(labels[id[i]], 0) == useLimit) {
                continue;
            }
            sum += values[id[i]];
            count++;
            map.put(labels[id[i]], map.getOrDefault(labels[id[i]], 0) + 1);
        }
        return sum;
    }
}

2. Add Two Numbers#

/**
 * Definition for singly-linked list.
 * public class ListNode {
 * int val;
 * ListNode next;
 * ListNode() {}
 * ListNode(int val) { this.val = val; }
 * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode();
        ListNode p = dummy;
        int carry = 0;
        while (l1 != null || l2 != null) {
            int val1 = l1 == null ? 0 : l1.val;
            int val2 = l2 == null ? 0 : l2.val;
            int sum = val1 + val2 + carry;
            ListNode node = new ListNode(sum % 10);
            carry = sum / 10;
            p.next = node;
            p = p.next;
            if (l1 != null) {
                l1 = l1.next;
            }
            if (l2 != null) {
                l2 = l2.next;
            }
        }
        if (carry != 0) {
            p.next = new ListNode(carry);
        }
        return dummy.next;
    }
}

445. Add Two Numbers II#

/**
 * Definition for singly-linked list.
 * public class ListNode {
 * int val;
 * ListNode next;
 * ListNode() {}
 * ListNode(int val) { this.val = val; }
 * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        Deque<ListNode> stack1 = new ArrayDeque<>();
        Deque<ListNode> stack2 = new ArrayDeque<>();
        ListNode ptr = l1;
        while (ptr != null) {
            stack1.push(ptr);
            ptr = ptr.next;
        }
        ptr = l2;
        while (ptr != null) {
            stack2.push(ptr);
            ptr = ptr.next;
        }
        ListNode dummy = new ListNode(-1, null);
        int carry = 0;
        while (!stack1.isEmpty() && !stack2.isEmpty()) {
            ListNode a = stack1.pop();
            ListNode b = stack2.pop();
            int c = (a.val + b.val + carry) % 10;
            carry = (a.val + b.val + carry) / 10;
            ListNode node = new ListNode(c);
            node.next = dummy.next;
            dummy.next = node;
        }
        while (!stack1.isEmpty()) { // Can also return 0 if empty
            ListNode a = stack1.pop();
            int c = (a.val + carry) % 10;
            carry = (a.val + carry) / 10;
            ListNode node = new ListNode(c);
            node.next = dummy.next;
            dummy.next = node;
        }
        while (!stack2.isEmpty()) {
            ListNode b = stack2.pop();
            int c = (b.val + carry) % 10;
            carry = (b.val + carry) / 10;
            ListNode node = new ListNode(c);
            node.next = dummy.next;
            dummy.next = node;
        }
        if (carry != 0) {
            ListNode node = new ListNode(carry);
            node.next = dummy.next;
            dummy.next = node;
        }
        return dummy.next;
    }
}

164. Maximum Gap#

class Solution {
    public int maximumGap(int[] nums) {
        if (nums.length < 2) {
            return 0;
        }
        Arrays.sort(nums); // O(nlogn) -> Change to use radix sort or bucket sort
        int res = 0;
        for (int i = 0; i < nums.length - 1; i++) {
            res = Math.max(res, nums[i + 1] - nums[i]);
        }
        return res;
    }
}

There is no time for the top ten sorts...

39. Combination Sum#

class Solution {
    List<List<Integer>> res;
    List<Integer> track;
    int sum;

    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        res = new ArrayList<>();
        track = new ArrayList<>();
        sum = 0;
        backtrack(candidates, target, 0);
        return res;
    }

    void backtrack(int[] candidates, int target, int startIndex) {
        if (sum > target) {
            return;
        }
        if (sum == target) {
            res.add(new ArrayList<>(track));
            return;
        }
        for (int i = startIndex; i < candidates.length; i++) {
            sum = sum + candidates[i];
            track.add(candidates[i]);
            backtrack(candidates, target, i);
            sum = sum - candidates[i]; // Backtrack
            track.removeLast();
        }
    }
}

394. Decode String#

class Solution {
    Deque<Integer> numStack = new ArrayDeque<>();
    Deque<StringBuilder> stack = new ArrayDeque<>();

    public String decodeString(String s) {
        int ptr = 0;
        stack.push(new StringBuilder());

        while (ptr < s.length()) {
            char currentChar = s.charAt(ptr);

            if (Character.isDigit(currentChar)) {
                int num = 0;
                while (Character.isDigit(s.charAt(ptr))) {
                    num = num * 10 + (s.charAt(ptr) - '0');
                    ptr++;
                }
                numStack.push(num);
                continue; // Skip '['
            } else if (currentChar == ']') {
                int repeatTimes = numStack.pop();
                StringBuilder decodedString = stack.pop();
                StringBuilder parent = stack.peek();

                for (int i = 0; i < repeatTimes; i++) {
                    parent.append(decodedString);
                }
            } else if (currentChar == '[') {
                stack.push(new StringBuilder());
            } else {
                stack.peek().append(currentChar);
            }
            ptr++;
        }
        return stack.pop().toString();
    }
}

19. Remove Nth Node From End of List#

/**
 * Definition for singly-linked list.
 * public class ListNode {
 * int val;
 * ListNode next;
 * ListNode() {}
 * ListNode(int val) { this.val = val; }
 * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(-1, head);
        ListNode slow = dummy, fast = dummy;
        for (int i = 0; i < n; i++) {
            fast = fast.next;
        }
        while (fast.next != null) {
            slow = slow.next;
            fast = fast.next;
        }
        slow.next = slow.next.next;
        return dummy.next;
    }
}
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.