LeetCode 2679. Sum in Matrix

2679. Sum in Matrix

You are given a two-dimensional integer array nums with index starting from 0. At the beginning your score is 0. You need to do the following until the matrix becomes empty:

Select the largest number for each row in the matrix and delete it. If there are multiple largest numbers in a row, select any one and delete it.
Find the largest number among all the numbers removed in step 1 and add it to your score.
Please return your final score.

Example 1:
Input: nums = [[7,2,1],[6,4,2],[6,5,3],[3,2,1]]
Output: 15
Explanation: In the first step , we remove 7, 6, 6 and 3, increasing the score by 7. In the next operation, delete 2 , 4 , 5 and 2 and increase the score by 5 . Finally remove 1, 2, 3 and 1 to increase the score by 3. So the total score is 7 + 5 + 3 = 15.

class Solution {
    
    
    // 2、建堆 优先级队列
    public int matrixSum(int[][] nums) {
    
    
        int n = nums.length;
        int m = nums[0].length;
        PriorityQueue<Integer>[] priorityQueue  = new PriorityQueue[n];
        for (int i = 0; i < n; i++) {
    
    
            priorityQueue[i] = new PriorityQueue<Integer>((a, b) -> b - a);
            for (int j = 0; j < m; j++) {
    
    
                priorityQueue[i].offer(nums[i][j]);
            }
        }
        int score = 0;
        for (int j = 0; j < m; j++) {
    
    
            int max = 0;
            for (int i = 0; i < n; i++) {
    
     // 删除每一行的最大值即堆顶元素
                max = Math.max(max, priorityQueue[i].poll());
            }
            score += max;
        }
        return score;
    }

    // 1、每一行排序,添加比较的每一列最大值
    public int matrixSum1(int[][] nums) {
    
    
        int n = nums.length;
        int m = nums[0].length;
        for (int i = 0; i < n; i++) {
    
    
            Arrays.sort(nums[i]);
        }
        int score = 0;
        for (int j = 0; j < m; j++) {
    
     // 列
            int max = 0;
            for (int i = 0; i < n; i++) {
    
    
                max = Math.max(max, nums[i][j]);
            }
            score += max;
        }
        return score;
    }
}

2600. Maximum sum of K items

The bag contains items, each marked with a number 1, 0, or -1.

You are given four non-negative integers numOnes, numZeros, numNegOnes and k.

The bag initially contains:

numOnes items marked 1.
numZeroes items marked as 0.
numNegOnes items marked -1.
The plan is to select exactly k items from these items. Returns the maximum value of the sum of the numbers marked on the item among all possible solutions.

Example 1:
Input: numOnes = 3, numZeros = 2, numNegOnes = 0, k = 2
Output: 2
Explanation: The items in the bag are labeled {1, 1, 1, 0, 0} respectively. Taking 2 items marked 1, the sum of the resulting numbers is 2.
It can be proved that 2 is the maximum value among all feasible schemes.

public int kItemsWithMaximumSum(int numOnes, int numZeros, int numNegOnes, int k) {
    
    
        // 1 可全取
        // 取全部 1 和 部分 0
        // 取全部 1, 0 和部分 -1
        if (k <= numOnes) {
    
    
            return k;
        } else if (k <= numOnes + numZeros) {
    
     // numOnes < k && k < numOnes + numZeros
            return numOnes;
        } else {
    
    
            return numOnes - (k - numOnes - numZeros);
        }
    }

445. Adding Two Numbers II

You are given two non-empty linked lists representing two non-negative integers. The highest digit of the number is at the beginning of the linked list. Each of their nodes stores only a single digit. Adding these numbers returns a new linked list.

You can assume that neither number starts with a zero other than the number 0.

insert image description here

Example 1:
Input: l1 = [7,2,4,3], l2 = [5,6,4]
Output: [7,8,0,7]

class Solution {
    
    
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    
    
        Stack<Integer> stack1 = new Stack<>();
        Stack<Integer> stack2 = new Stack<>();
        while (l1 != null) {
    
    
            stack1.add(l1.val);
            l1 = l1.next;
        }
        while (l2 != null) {
    
    
            stack2.add(l2.val);
            l2 = l2.next;
        }
        int carry = 0; // 记得进位
        ListNode ans = null;
        while (!stack1.isEmpty() || !stack2.isEmpty() || carry != 0) {
    
    
            int val1 = stack1.isEmpty() ? 0: stack1.pop();
            int val2 = stack2.isEmpty() ? 0 : stack2.pop();
            int sum = val1 + val2 + carry;
            int nextVal = sum % 10;
            carry = sum / 10;
            ListNode nextCur = new ListNode(nextVal); // 下一个节点
            nextCur.next = ans;
            ans = nextCur; // 新的 head
        }
        return ans;
    }
}

3. The longest substring without repeating characters

Add link description
Given a string s, please find the length of the longest substring that does not contain repeated characters.

Example 1:
Input: s = "abcabcbb"
Output: 3
Explanation: Since the longest substring without repeating characters is "abc", its length is 3.

class Solution {
    
    
    // 滑动窗口
    //  key 值为字符,value 值为字符位置 +1,加 1 表示从字符位置后一个才开始不重复
    public int lengthOfLongestSubstring(String s) {
    
    
        int n = s.length();
        int ans = 0;
        Map<Character, Integer> map = new HashMap<>();
        for (int end = 0, start = 0; end < n; end++) {
    
    
            if (map.containsKey(s.charAt(end))) {
    
    
                start = Math.max(start, map.get(s.charAt(end)));
            }
            ans = Math.max(ans, end - start + 1);
            map.put(s.charAt(end), end + 1); // 下次 start 更新的位置
        }
        return ans;
    }
}

1017. Negative Binary Conversion

Add Link Description
Given you an integer n, return the negative binary (base -2) representation of that integer as a binary string.

Note that the returned string cannot contain leading zeros unless the string is exactly "0".

Example 1:
Input: n = 2
Output: "110"
Explanation: (-2)2 + (-2)1 = 2

class Solution {
    
    
    // 基数为 -2,负二进制的余数可能有0,1,-1,要保证余数为正
    public String baseNeg2(int n) {
    
    
        if (n == 0) {
    
    
            return "0";
        }
        StringBuilder ans = new StringBuilder();
        while (n != 0) {
    
    
            int remain = Math.abs(n % (-2));
            ans.append(remain == 0 ? "0" : "1");
            n = (n - remain) / (-2);
        }
        return ans.reverse().toString();
    }
}

2404. Most Frequently Occurring Even Elements

Add link description
Given you an integer array nums, return the most frequently occurring even elements.

If there are multiple elements that meet the condition, only the smallest one needs to be returned. Returns -1 if no such element exists.

Example 1:
Input: nums = [0,1,2,2,4,4,1]
Output: 2
Explanation:
The even elements in the array are 0, 2, and 4, and among these elements, 2 and 4 occur most frequently .
Return the smallest one, which is 2.

class Solution {
    
    
    public static int mostFrequentEven(int[] nums) {
    
    
        int max = 0; // 最频繁次数
        int ans = -1;
        Map<Integer, Integer> map = new HashMap<>();
        for (int num : nums) {
    
    
            if (num % 2 == 0) {
    
    
                map.put(num, map.getOrDefault(num, 0) + 1);
                if (max < map.get(num)) {
    
    
                    max = map.get(num); // 更新出现最频繁 次数 
                    ans = num; // 更新出现最频繁 元素 
                } else if (max == map.get(num)) {
    
     // 次数相同时 结果为最小的元素
                    ans = Math.min(ans, num);
                }
            }
        }
        return ans;
    }
}

831. Concealment of personal information

Add link description
Give you a personal information string s, which may represent an email address or a string of phone numbers. Return the result after hiding personal information according to the following rules:

email address:

An email address consists of the following parts:

A name consisting of uppercase and lowercase English letters, followed by
a '@' character, followed by
a domain name, consisting of uppercase and lowercase English letters and a '.' character in the middle. '.' will not be the first or last character of the domain name.
To hide personal information from an email address:

Uppercase English letters in the name and domain name parts should be converted to lowercase English letters. Letters in the middle of the name (ie, except the first and last letters) must be replaced
with 5 . telephone number:"*****"

A phone number should be formed in the following format:

The phone number can be composed of 10-13 digits, the last
10 digits constitute the local number , and the remaining 0-3 digits constitute the country code. Use these separator characters to separate the above digits in some form to hide the personal information in the phone number :

{'+', '-', '(', ')', ' '}

Remove all delimiting characters
Phone numbers after hiding personal information should follow this format:
"***-***-XXXX"If the country code is 0 digits
"+*-***-***-XXXX"If the country code is 1 digit
"+**-***-***-XXXX"If the country code is 2 digits
"+***-***-***-XXXX"If the country code is 3 digits
"XXXX" Yes Last 4 digits of local number

Example 1:
Input: s = "[email protected]"
Output: "l*****[email protected]"
Explanation: s is an email address.
Both the name and the domain name are converted to lowercase, and the middle of the name is replaced with 5 *.

class Solution {
    
    
    // 2、
    static String[] country = {
    
    "", "+*-", "+**-", "+***-"};

    public String maskPII(String s) {
    
    
        int atIndex = s.indexOf("@");
        StringBuilder stringBuilder = new StringBuilder();
        if (atIndex > 0) {
    
     // 电子邮件地址
            stringBuilder.append(s.charAt(0) + "*****" + s.substring(atIndex - 1));
            return stringBuilder.toString().toLowerCase();
        } else {
    
     // 电话号码
            s = s.replaceAll("[^0-9]", "");
            stringBuilder.append(country[s.length() - 10] + "***-***-" + s.substring(s.length() - 4));
            return stringBuilder.toString();
        }
    }

    // 1、
    public static String maskPII1(String s) {
    
    
        int n = s.length();
        // 1、分析是邮件地址还是电话号码
        boolean flg = false;
        for (int i = n - 1; i >= 0; i--) {
    
    
            if (s.charAt(i) == '.') {
    
    
                flg = true;
                break;
            }
        }
        StringBuilder stringBuilder = new StringBuilder();
        // 2、电子邮件地址
        if (flg) {
    
    
            int index = s.indexOf("@"); // 获取 @ 下标,拼接首尾字母,@ 到结尾
            stringBuilder.append(s.charAt(0) + "*****" + s.charAt(index - 1) + s.substring(index));
            return stringBuilder.toString().toLowerCase();
        }
        // 3、电话号码
        int cnt = 0;
        for (int i = 0; i < n; i++) {
    
     // 统计电话号码位数
            if (Character.isDigit(s.charAt(i))) {
    
    
                cnt++;
            }
        }
        if (cnt == 10) {
    
     // 国家代码 0 位
            stringBuilder.append("***-***-");
        } else if (cnt == 11) {
    
     // 国家代码 1 位
            stringBuilder.append("+*-***-***-");
        } else if (cnt == 12) {
    
     // 国家代码 2 位
            stringBuilder.append("+**-***-***-");
        } else if (cnt == 13) {
    
     // 国家代码 3 位
            stringBuilder.append("+***-***-***-");
        }
        StringBuilder sb = new StringBuilder(); // 后四位号码 可能有符号 '-'
        int digitCnt = 0;
        for (int i = n - 1; i >= 0; i--) {
    
    
            if (Character.isDigit(s.charAt(i))) {
    
    
                sb.append(s.charAt(i));
                digitCnt++;
                if (digitCnt == 4) {
    
    
                    break;
                }
            }
        }
        stringBuilder.append(sb.reverse());
        return stringBuilder.toString();
    }
}

2367. Number of Arithmetic Triplets

Add link description
You are given a 0-based, strictly increasing integer array nums and a positive integer diff. A triplet (i, j, k) is an arithmetic triplet if all of the following conditions are met:

i < j < k ,
nums[j] - nums[i] == diff and
nums[k] - nums[j] == diff
returns the number of distinct arithmetic triplets.

Example 1:
Input: nums = [0,1,4,6,7,10], diff = 3
Output: 2
Explanation:
(1, 2, 4) is an arithmetic triple: 7 - 4 == 3 and 4 - 1 == 3 .
(2, 4, 5) is an arithmetic triplet: 10 - 7 == 3 and 7 - 4 == 3 .

class Solution {
    
    
    // 2、三指针 O(N)  下标只增不减
    public int arithmeticTriplets(int[] nums, int diff) {
    
    
        int cnt = 0;
        int n = nums.length;
        for (int i = 0, j = 1, k = 2; i < n - 2 && j < n - 1 && k < n; i++) {
    
    
            j = Math.max(j, i + 1);
            while (j < n - 1 && nums[j] - nums[i] < diff) {
    
     // 对于当前 x,找 x + diff
                j++;
            }
            if (j >= n - 1 || nums[j] - nums[i] > diff) {
    
     // 当前 x,没有满足的三元组
                continue;
            }
            k = Math.max(k, j + 1);
            while (k < n && nums[k] - nums[j] < diff) {
    
    
                k++;
            }
            if (k < n && nums[k] - nums[j] == diff) {
    
     // 满足的三元组加一
                cnt++;
            }
        }
        return cnt;
    }

    // 2、哈希 O(N)  数组严格递增,没有重复
    // 等差数列 ->  x,  x+diff,  x+2*diff
    public int arithmeticTriplets2(int[] nums, int diff) {
    
    
        Set<Integer> set = new HashSet<>();
        for (int num : nums) {
    
    
            set.add(num);
        }
        int cnt = 0;
        for (int x : nums) {
    
    
            if (set.contains(x + diff) && set.contains(x + 2 * diff)) {
    
    
                cnt++;
            }
        }
        return cnt;
    }

    // 1、暴力枚举
    public int arithmeticTriplets1(int[] nums, int diff) {
    
    
        int cnt = 0;
        int n = nums.length;
        for (int i = 0; i < n; i++) {
    
    
            for (int j = i + 1; j < n; j++) {
    
    
                if (nums[j] - nums[i] != diff) {
    
    
                    continue;
                }
                for (int k = j + 1; k < n; k++) {
    
    
                    if (nums[k] - nums[j] == diff) {
    
    
                        cnt++;
                    }
                }
            }
        }
        return cnt;
    }
}

1637. The widest vertical area between two points that does not contain any points

Add link description
Given you n points on a two-dimensional plane, where points[i] = [xi, yi], please return the width of the widest vertical area between two points that does not contain any points inside.

A vertical area is defined as an area of ​​fixed width that extends infinitely on the y-axis (that is, the height is infinite). The widest vertical area is a vertical area with the largest width.

Note that points on the edge of the vertical region are not inside the region.

Example 1:
​Input : points = [[8,7],[9,9],[7,4],[9,7]]
Output: 1
Explanation: Both the red area and the blue area are optimal areas.

class Solution {
    
    
    // 按横坐标排序,依次求出所有相邻点的横坐标距离,返回最大值 (与 y 轴无关)
    public int maxWidthOfVerticalArea(int[][] points) {
    
    
        Arrays.sort(points, (a, b) -> a[0] - b[0]);
        int max = 0;
        for (int i = 1; i < points.length; i++) {
    
    
            max = Math.max(max, points[i][0] - points[i - 1][0]);
        }
        return max;
    }
}

1641. Count the number of lexicographical vowel strings

Add link description
Given an integer n, please return the number of strings of length n consisting only of vowels (a, e, i, o, u) in lexicographical order.

The string s is lexicographically ordered such that, for all valid i, s[i] is always at the same position in the alphabet as s[i+1] or before s[i+1].

Example 1:
Input: n = 1
Output: 5
Explanation: 5 lexicographic strings consisting only of vowels are ["a", "e", "i", "o", "u"] Example 2
:

Input: n = 2
Output: 15
Explanation: 15 lexicographic strings consisting of only vowels are
["aa", "ae", "ai", "ao", "au", "ee", "ei ", "eo", "eu", "ii", "io", "iu", "oo", "ou", "uu"] Note that "ea" is not a string that meets the meaning of the question, because '
e ' is later in the alphabet than 'a'

class Solution {
    
    
    // 2、C(n+4,4)
    public int countVowelStrings(int n) {
    
    
        return (n + 4) * (n + 3) * (n + 2) * (n + 1) / 24;
    }

    // 1、动态规划
    public int countVowelStrings3(int n) {
    
    
        int[] dp = new int[5];
        Arrays.fill(dp, 1);
        for (int i = 1; i < n; i++) {
    
    
            for (int j = 1; j < 5; j++) {
    
    
                dp[j] += dp[j - 1];
            }
        }
        // n = 5 ——> [1, 5, 15, 35, 70]
        return Arrays.stream(dp).sum();
    }

    // dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
    // [1, 1, 1, 1, 1]
    // [1, 2, 3, 4, 5]
    // [1, 3, 6, 10, 15]
    // [1, 4, 10, 20, 35]
    // [1, 5, 15, 35, 60]
    public int countVowelStrings2(int n) {
    
    
        int[][] dp = new int[n][5];
        for (int i = 0; i < 5; i++) {
    
    
            dp[0][i] = 1;
        }
        for (int i = 1; i < n; i++) {
    
    
            // dp[i][0] = dp[i - 1][0];
            dp[i][0] = 1;
            for (int j = 1; j < 5; j++) {
    
    
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
        }
        return Arrays.stream(dp[n - 1]).sum();
    }
    
    public int countVowelStrings1(int n) {
    
    
        int a = 1, e = 1, i = 1, o = 1, u = 1;
        for (int k = 1; k < n; k++) {
    
    
            a = a + e + i + o + u;
            e = e + i + o + u;
            i = i + o + u;
            o = o + u;
            u = u;
        }
        return a + e + i + o + u;
    }
}

2395. Sum Equal Subarrays

Add link description
Given you an integer array nums whose subscript starts from 0, determine whether there are two subarrays with length 2 and their sums are equal. Note that the subscripts of the starting positions of the two subarrays must be different.

Return true if such a subarray exists, false otherwise.

A subarray is a sequence of consecutive non-empty elements in an array.

Example 1:
Input: nums = [4,2,4]
Output: true
Explanation: Subarrays with elements [4,2] and [2,4] have the same sum 6.

class Solution {
    
    
    public boolean findSubarrays(int[] nums) {
    
    
        Set<Integer> set = new HashSet<>();
        for (int i = 1; i < nums.length; i++) {
    
    
            int sum = nums[i - 1] + nums[i];
            if (set.contains(sum)) {
    
    
                return true;
            }
            set.add(sum);
        }
        return false;
    }
}

1574. Delete the shortest subarray to make the remaining array sorted

Given an integer array arr, please delete a sub-array (can be empty), so that the remaining elements in arr are non-decreasing.

A subarray refers to a contiguous subsequence of the original array.

Please return the length of the shortest subarray that meets the requirements of the question.

Example 1:
Input: arr = [1,2,3,10,4,2,3,5]
Output: 3
Explanation: The shortest subarray we need to delete is [10,4,2] with length 3. The remaining elements form the non-decreasing array [1,2,3,3,5].
Another correct solution is to delete the subarray [3,10,4].

class Solution {
    
    
    // 双指针  枚举左端点,移动右端点
    public int findLengthOfShortestSubarray(int[] arr) {
    
    
        int n = arr.length;
        int r = n - 1;
        // 从右端点开始,arr[r] 最大,r 到达非递减的位置
        while (r > 0 && arr[r - 1] <= arr[r]) {
    
    
            r--;
        }
        // arr 为非递减数组,不需要删除
        if (r == 0) {
    
    
            return 0;
        }
        // 需要删除的是 [0-r) 之间,最多 [0-r) 都需要删除
        int ans = r;
        for (int l = 0; l == 0 || arr[l - 1] <= arr[l]; l++) {
    
     // 当前 l 与左边非递减,判断是否与 arr[r] 非递减
            while (r < n && arr[l] > arr[r]) {
    
    
                r++;
            }
            // 需要删除的是 [l-r) 之间
            ans = Math.min(ans, r - l - 1);
        }
        return ans;
    }
}

Guess you like

Origin blog.csdn.net/qq_56884023/article/details/129773315