Technical dry goods (two): LeetCode21-40 detailed questions

Let’s look at LeetCode21-40 questions today

Technical dry goods (two): LeetCode21-40 detailed questions

 

21. Merge two ordered linked lists

Combine the two ascending linked lists into a new  ascending  linked list and return. The new linked list is composed by splicing all the nodes of the given two linked lists.

Example:

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4

Merge thought

    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);
        ListNode curr = dummy;        while(l1 != null && l2 != null){
            if(l1.val <= l2.val){
                curr.next = l1;                l1 = l1.next;            }else{
                curr.next = l2;                l2 = l2.next;            }            curr = curr.next;        }        curr.next = (l1 != null) ? l1 : l2;
        return dummy.next;
    }

Recursion

    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if(l1 == null) return l2;
        if(l2 == null) return l1;
        if(l1.val < l2.val){
            l1.next = mergeTwoLists(l1.next, l2);            return l1;
        }else{
            l2.next = mergeTwoLists(l1, l2.next);        	return l2; 
        }    }

22. Bracket generation

The number  n  represents the logarithm of generating brackets. Please design a function to generate all possible and  effective  bracket combinations.

Example:

输入:n = 3
输出:[       "((()))",
       "(()())",
       "(())()",
       "()(())",
       "()()()"
     ]

With String, a new object is created every time the state changes, and no state reset is required.

class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> res = new ArrayList<>();
        String sb = "";
        dfs(n, n, res, sb);        return res;
    }    void dfs(int l,int r, List<String> res, String sb){
        if(l == 0 && r == 0){
            res.add(sb);
            return;
        }		//保证一旦右括号先出现就停止
        if(l > r) return;
        if(l > 0) dfs(l - 1, r, res, sb + "(");
        if(r > 0) dfs(l, r - 1, res, sb + ")");
    }
}

To use StringBuilder, state reset is required.

class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> res = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        dfs(n, n, res, sb);        return res;
    }    void dfs(int l,int r, List<String> res, StringBuilder sb){
        if(l == 0 && r == 0){
            res.add(sb.toString());
            return;
        }        if(l > r) return;
        if(l > 0){
            sb.append("(");
            dfs(l - 1, r, res, sb);
            sb.deleteCharAt(sb.length() -1);
        }         if(r > 0) {
            sb.append(")");
            dfs(l, r - 1, res, sb);
            sb.deleteCharAt(sb.length() -1);
        }    }}

23. Merge K ascending linked lists

Give you an array of linked lists, each of which has been arranged in ascending order.

Please merge all linked lists into an ascending linked list and return the merged linked list.

Example 1:

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:[  1->4->5,
  1->3->4,
  2->6
]将它们合并到一个有序链表中得到。1->1->2->3->4->4->5->6

Example 2:

输入:lists = []
输出:[]

Example 3:

输入:lists = [[]]
输出:[]

prompt:

  • k == lists.length
  • 0 <= k <= 10^4
  • 0 <= lists[i].length <= 500
  • -10^4 <= lists[i][j] <= 10^4
  • lists[i] in  ascending  order
  • The sum of lists[i].length does not exceed 10^4

Divide and conquer + merge

class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists == null || lists.length == 0) return null;
        return merge(lists, 0 , lists.length - 1);
    }    ListNode merge(ListNode[] lists, int l, int r){        if(l == r) return lists[l];
        int mid = l + r >>> 1;
        ListNode l1 = merge(lists, l , mid);        ListNode l2 = merge(lists, mid + 1, r);
        return mergeTwoLists(l1, l2);
    }    ListNode mergeTwoLists(ListNode l1, ListNode l2){        if(l1 == null) return l2;
        if(l2 == null) return l1;
        if(l1.val < l2.val){
            l1.next = mergeTwoLists(l1.next, l2);            return l1;
        }else{
            l2.next = mergeTwoLists(l1,l2.next);            return l2;
        }    }}

Priority queue

class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        Queue<ListNode> pq = new PriorityQueue<>((v1, v2) -> v1.val - v2.val);
        for (ListNode node: lists) {
            if (node != null) {
                pq.offer(node);            }        }        ListNode dummyHead = new ListNode(0);
        ListNode tail = dummyHead;        while (!pq.isEmpty()) {
            ListNode minNode = pq.poll();            tail.next = minNode;            tail = minNode;            if (minNode.next != null) {
                pq.offer(minNode.next);            }        }        return dummyHead.next;
    }}

24. Pairwise exchange of nodes in the linked list

Given a linked list, exchange adjacent nodes in it in pairs, and return the exchanged linked list.

You can't just change the value inside the node , but need to actually exchange the node.

Example:

给定 1->2->3->4, 你应该返回 2->1->4->3.

 

Technical dry goods (two): LeetCode21-40 detailed questions

 

    public ListNode swapPairs(ListNode head) {
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        for(ListNode p = dummy; p.next != null && p.next.next != null; ){
            ListNode a = p.next,b = a.next;
            p.next = b;
            a.next = b.next;
            b.next = a;
            p = a;        }        return dummy.next;
    }

25. A set of K flip linked lists

Give you a linked list, each  group of  k nodes are flipped, please return to the flipped linked list.

k  is a positive integer, and its value is less than or equal to the length of the linked list.

If the total number of nodes is not   an integral multiple of k , please keep the last remaining nodes in the original order.

Example:

Give you this linked list: 1->2->3->4->5

When  k  = 2, it should return: 2->1->4->3->5

When  k  = 3, it should return: 3->2->1->4->5

Description:

  • Your algorithm can only use constant extra space.
  • You can't just change the value inside the node , but need to actually exchange the node.
    public ListNode reverseKGroup(ListNode head, int k) {
        if (head == null) return null;
        // 区间 [a, b) 包含 k 个待反转元素        ListNode a, b;        a = b = head;        for (int i = 0; i < k; i++) {
            // 不足 k 个,不需要反转,base case            if (b == null) return head;
            b = b.next;
        }        // 反转前 k 个元素, 返回的值就是反转之后的head        ListNode newHead = reverse(a, b);
        // 递归反转后续链表并连接起来        a.next = reverseKGroup(b, k);
        return newHead;
            }	//反转 [head, tail)    ListNode reverse(ListNode head ,ListNode tail){
        ListNode p = head, pre = null, next = null;
        while(p != tail){
            next = p.next;
            p.next = pre;
            pre = p;            p = next;
        }        return pre;
    }

26. Remove duplicates in sorted array

Given a sorted array, you need to  delete the repeated elements in  place , so that each element only appears once, and return the new length of the removed array.

Don't use extra array space, you must modify the input array in-  situ  and complete with O(1) extra space.

Example 1:

给定数组 nums = [1,1,2], 
函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。 
你不需要考虑数组中超出新长度后面的元素。

Example 2:

给定 nums = [0,0,1,1,1,2,2,3,3,4],
函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。
你不需要考虑数组中超出新长度后面的元素。
   public int removeDuplicates(int[] nums) {
       if( nums.length == 0) return 0;
       //慢指针
       int i = 0;
       //快指针
       for(int j = 1; j < nums.length; j ++){
           if(nums[j] != nums[i]) nums[++i] = nums[j];
       }
       //返回长度
       return i + 1;
   }

27. Remove elements

Given you an array of  nums  and a value of  val , you need to   remove all  elements whose value is equal to  val in place , and return the new length of the removed array.

Don't use extra array space, you must use only O(1) extra space and  modify the input array in-situ .

The order of the elements can be changed. You don't need to consider the elements in the array beyond the new length.

Example 1:

给定 nums = [3,2,2,3], val = 3,
函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。
你不需要考虑数组中超出新长度后面的元素。

Example 2:

给定 nums = [0,1,2,2,3,0,4,2], val = 2,
函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。
注意这五个元素可为任意顺序。
你不需要考虑数组中超出新长度后面的元素。
    public int removeElement(int[] nums, int val) {
        int k = 0;
        for(int i = 0; i < nums.length; i ++){
            if(nums[i] != val){
                nums[k++] = nums[i];
            }
        }
        return k;
    }

28. Implement strStr()

Implement the strStr() function.

Given a haystack string and a needle string, find the first position (starting from 0) where the needle string appears in the haystack string. If it does not exist, -1 is returned  .

Example 1:

输入: haystack = "hello", needle = "ll"
输出: 2

Example 2:

输入: haystack = "aaaaa", needle = "bba"
输出: -1

Description:

When needle is an empty string, what value should we return? This is a good question in an interview.

For this question, we should return 0 when needle is an empty string. This is consistent with the definition of strstr() in C language and indexOf() in Java.

class Solution {
    public int strStr(String haystack, String needle) {
        int m = haystack.length(), n = needle.length();
        if (n == 0) return 0;
        for(int i = 0;i <= m - n ; i ++){
            //if(haystack.substring(i , i + n).equals(needle))  return i;
            if(check(haystack.substring(i , i + n), needle))  return i;
        }        return -1;
    }	//相当于equals函数    boolean check(String s1, String s2){        int k = 0;
        while(k < s2.length()){
            if(s1.charAt(k) != s2.charAt(k)) return false;
            k ++;        }        return true;
    }}

29. Divide Two Numbers

Given two integers, the dividend and the divisor. Divide two numbers without using multiplication, division, and mod operators.

Returns the quotient obtained by dividing the dividend by the divisor.

The result of integer division should be truncated (truncate) its decimal part, for example: truncate(8.345) = 8 and truncate(-2.7335) = -2

Example 1:

输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = truncate(3.33333..) = truncate(3) = 3

Example 2:

输入: dividend = 7, divisor = -3
输出: -2
解释: 7/-3 = truncate(-2.33333..) = -2

prompt:

  • Both the dividend and the divisor are 32-bit signed integers.
  • The divisor is not zero.
  • Assuming that our environment can only store 32-bit signed integers, the value range is [−231, 231 − 1]. In this question, if the division result overflows, 231 − 1 is returned.

Convert both the dividend and the divisor into a positive or negative number for calculation. Because in Java, when t=Integer.MIN_VALUE (the opposite of t is still itself), there may be an out-of-bounds problem, so negative numbers are used for calculation.

    //O(N) 时间复杂度 超时
    public int divide(int a, int b) {
        //特殊情况
        if(a == Integer.MIN_VALUE && b == -1) return Integer.MAX_VALUE;
        //k标识a与b是否同号
        boolean k = (a > 0 && b > 0) || (a < 0 && b < 0);
        int res = 0;
        //转化为负数
        a = -Math.abs(a);
        b = -Math.abs(b);
        //循环减相当于除法操作
        while(a <= b){
            a -= b;
            res ++;
        }
        return k? res : -res;
    }

Use dichotomy to improve, a subtracts 2n2n b each time, and res adds 2n2n each time

    //O(log(n)) 
    public int divide(int a, int b) {
        //特殊情况
        if(a == Integer.MIN_VALUE && b == -1) return Integer.MAX_VALUE;
        //k标识a与b是否同号
        boolean k = (a > 0 && b > 0) || (a < 0 && b < 0);
        int res = 0;
        //转化为负数
        a = -Math.abs(a);
        b = -Math.abs(b);
        //循环减相当于除法操作
        while(a <= b){
            int temp = b;
            int c = 1;
            //每次减去2^n
            while(a - temp <= temp){
                temp = temp << 1;
                c = c << 1;
            }
            a -= temp;
            res += c;
        }
        return k? res : -res;
    }

30. Concatenate all substrings of words

Given a string  s  and some words of the same length  . Find   the starting position of the substring in s  that can be formed by  concatenating all the words in words.

Note that the substring must   exactly match the words in words, and there can be no other characters in the middle, but there is no need to consider   the sequence of words in words.

Example 1:

输入:
  s = "barfoothefoobarman",
  words = ["foo","bar"]
输出:[0,9]解释:从索引 0 和 9 开始的子串分别是 "barfoo" 和 "foobar" 。
输出的顺序不重要, [9,0] 也是有效答案。

Example 2:

输入:
  s = "wordgoodgoodgoodbestword",
  words = ["word","good","best","word"]
输出:[]public List<Integer> findSubstring(String s, String[] words) {    List<Integer> res = new ArrayList<>();    int wordNum = words.length;    if(wordNum == 0) return res;
    int wordLen = words[0].length();
    // allWords存储所有单词
    HashMap<String, Integer> allWords = new HashMap<>();    for(String w : words) allWords.put(w, allWords.getOrDefault(w, 0) + 1);
    // 遍历所有子串
    for(int i = 0; i < s.length() - wordNum * wordLen + 1; i ++){
        // hasWords存储当前扫描的字符串含有的单词
        HashMap<String, Integer> hasWords = new HashMap<>();        int num = 0;
        // 判断该子串是否符合
        while(num < wordNum){
            //每次取一段
            String word = s.substring(i + num * wordLen, i + (num + 1) * wordLen);
            if(allWords.containsKey(word)){
                hasWords.put(word, hasWords.getOrDefault(word, 0) + 1);
                // 判断当前单词的value 和 allWords中该单词的value
                if(hasWords.get(word) > allWords.get(word)) break;
            }else{
                break;
            }            num ++;        }        // 判断是不是所有的单词都符合条件
        if(num == wordNum) res.add(i);
    }
    return res;
}


31. Next Permutation

To achieve the function of obtaining the next permutation, the algorithm needs to rearrange the given sequence of numbers into the next larger permutation in the lexicographic order.

If there is no next larger arrangement, the numbers are rearranged to the smallest arrangement (that is, ascending order).

It must be modified in- situ , only extra constant space is allowed.

Here are some examples. The input is in the left column and the corresponding output is in the right column. 1,2,3 → 1,3,2 3,2,1 → 1,2,31,1,5 → 1,5,1

public void nextPermutation(int[] nums) {
        int i = nums.length - 2;
        //找到第一个不再递增的位置
        while (i >= 0 && nums[i + 1] <= nums[i]) {
            i--;        }        //如果到了最左边,就直接倒置输出        if (i < 0) {
            reverse(nums, 0);
            return;
        }        //找到刚好大于 nums[i]的位置        int j = nums.length - 1;
        while (j >= 0 && nums[j] <= nums[i]) {
            j--;        }        //交换        swap(nums, i, j);        //利用倒置进行排序
        reverse(nums, i + 1);
    }    private void swap(int[] nums, int i, int j) {
        int temp = nums[j];
        nums[j] = nums[i];        nums[i] = temp;    }    private void reverse(int[] nums, int start) {
        int i = start, j = nums.length - 1;
        while (i < j) {
            swap(nums, i, j);            i++;            j--;        }    }

32. Longest valid parenthesis

Given a string containing only'(' and')', find the length of the longest substring containing valid parentheses.

Example 1:

输入: "(()"
输出: 2解释: 最长有效括号子串为 "()"

Example 2:

输入: ")()())"
输出: 4
解释: 最长有效括号子串为 "()()"//")()(" --> 1001
    public int longestValidParentheses(String s) {
        Stack<Integer> stack = new Stack<>();        int n = s.length();
        char[] chs = s.toCharArray();        int[] mark = new int[n];
        int left = 0, len = 0, ans = 0;
        for(int i = 0; i < n; i ++){
            if(chs[i] == '(') stack.push(i);
            else{
                //没有匹配的左括号的右括号,置1
                if(stack.isEmpty())mark[i] = 1;
                //如果有匹配的左括号,弹出
                else stack.pop();
            }        }        // System.out.println(Arrays.toString(mark));        //多余的左括号,置1
        while(!stack.isEmpty()){
            mark[stack.pop()] = 1;
        }        //找到最长连续0的长度
        for(int i = 0; i < n; i ++){
            if(mark[i] == 1){
                len = 0;
                continue;
            }            len ++;            ans = Math.max(ans , len);        }        return ans;
    }

33. Search rotated sorted array

Assume that the array sorted in ascending order is rotated at a point unknown in advance.

(For example, the array [0,1,2,4,5,6,7] may become [4,5,6,7,0,1,2] ).

Search for a given target value, if the target value exists in the array, return its index, otherwise return -1.

You can assume that there are no duplicate elements in the array.

The time complexity of your algorithm must be  O (log  n ) level.

Example 1:

输入: nums = [4,5,6,7,0,1,2], target = 0
输出: 4

Example 2:

输入: nums = [4,5,6,7,0,1,2], target = 3
输出: -1public int search(int[] nums, int target) {
        if(nums.length == 0) return -1;
        int l = 0, r = nums.length -1;
        //找到最小值的索引位置
        while(l < r){
            int mid = l + r >> 1;
            if( nums[mid] <= nums[nums.length -1 ]) 
                r = mid;            else 
                l = mid + 1;
        }//此时l == r  == k        if( target <= nums[nums.length -1]) 
            //[k,len-1]
            r = nums.length -1; 
        else {
            //左边那段中寻找[0,k-1]
            l = 0;
            r --; //因为上面二分完之后找到了第二段的第一个索引,因此r = r-1
        }        while(l < r){
            int mid = l + r >> 1;
            if( nums[mid] >= target) r = mid;
            else l = mid + 1;
        }        //二分得出的是第一个>=target的值,需要判断一下是否就是寻找的那个数        if( nums[l]  ==  target) return l;
        return -1;
    }

34. Find the first and last position of an element in a sorted array

Given an integer array nums in ascending order, and a target value target. Find the start and end positions of the given target value in the array.

The time complexity of your algorithm must be  O (log  n ) level.

If there is no target value in the array, return [-1, -1].

Example 1:

输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]

Example 2:

输入: nums = [5,7,7,8,8,10], target = 6
输出: [-1,-1]public int[] searchRange(int[] nums, int t) {
        if(nums.length == 0) return new int[]{-1, -1};
        int l = 0, r = nums.length -1;
        //找第一个数
        while(l < r){
            int mid = l + r >>> 1;
            //假设mid位置为8,前面可能还有,r = mid
            if(nums[mid] >= t){
                r = mid;            }else{
                l = mid + 1;
            }        }        //将会二分出大于等于t的第一个数如果不等于t 则不存在        if(nums[r] != t) return new int[]{-1, -1};
        int start = r;
        l = 0;
        r = nums.length -1;
        while(l < r){
            //这里条件 l = mid, 注意这里向上取整
            int mid = l + r + 1 >>> 1;
            //找到第一个 <= target的数
            if( nums[mid] <= t){
                l = mid;            }else{
                r = mid - 1;
            }        }        int end = r;
        return new int[]{start, end};
    }

35. Search for insertion location

Given a sorted array and a target value, find the target value in the array and return its index. If the target value does not exist in the array, return the position where it will be inserted in order.

You can assume that there are no duplicate elements in the array.

Example 1:

输入: [1,3,5,6], 5
输出: 2

Example 2:

输入: [1,3,5,6], 2
输出: 1public int searchInsert(int[] nums, int target) {
        if(nums.length == 0 || nums[nums.length-1] < target) return nums.length;
        int l = 0, r = nums.length -1;
        //找到 >= target的第一个坐标
        while( l < r){
            int mid = l + r >> 1;
            if( nums[mid] >= target){
                r = mid;            }else{
                l = mid + 1;
            }        }        return r;
    }

36. Effective Sudoku

Determine whether a 9x9 Sudoku is valid. It is only necessary to verify whether the entered number is valid according to the following rules .

  1. The numbers 1-9 can only appear once per line.
  2. The numbers 1-9 can only appear once in each column.
  3. The numbers 1-9 can only appear once in each 3x3 palace separated by a thick solid line.

Technical dry goods (two): LeetCode21-40 detailed questions

 

The picture above is a partially filled and effective Sudoku.

Numbers have been filled in the blanks of Sudoku, and the blanks are indicated by'.'.

Example 2:

输入:
[
  ["8","3",".",".","7",".",".",".","."],
  ["6",".",".","1","9","5",".",".","."],
  [".","9","8",".",".",".",".","6","."],
  ["8",".",".",".","6",".",".",".","3"],
  ["4",".",".","8",".","3",".",".","1"],
  ["7",".",".",".","2",".",".",".","6"],
  [".","6",".",".",".",".","2","8","."],
  [".",".",".","4","1","9",".",".","5"],
  [".",".",".",".","8",".",".","7","9"]
]输出: false
解释: 除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。     但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。

Description:

  • A valid Sudoku (partially filled) is not necessarily solvable.
  • You only need to verify the validity of the entered numbers according to the above rules.
  • The given Sudoku sequence only contains numbers 1-9 and the character'.'.
  • A given Sudoku is always in 9x9 form.
public boolean isValidSudoku(char[][] board) {
        // 记录某行,某位数字是否已经被摆放        boolean[][] row = new boolean[9][9];
        // 记录某列,某位数字是否已经被摆放        boolean[][] col = new boolean[9][9];
        // 记录某 3x3 宫格内,某位数字是否已经被摆放        boolean[][] block = new boolean[9][9];
        for(int i = 0; i < 9; i ++){
            for(int j = 0; j < 9; j ++){
                //.的情况不用考虑
                if(board[i][j] == '.') continue;
                //数字为1-9
                int num = board[i][j] - '1';
                //映射到子数独中
                int index = i / 3 * 3 + j / 3;
                if(row[i][num] || col[j][num] || block[index][num]) 
                    return false;
                else{
                    row[i][num] = true;
                    col[j][num] = true;
                    block[index][num] = true;
                }
            }
        }
        return true;
    }

37. Solving Sudoku

Write a program to solve Sudoku problems by filling spaces.

A Sudoku solution must follow the following rules :

  1. The numbers 1-9 can only appear once per line.
  2. The numbers 1-9 can only appear once in each column.
  3. The numbers 1-9 can only appear once in each 3x3 palace separated by a thick solid line.

Blank cells are represented by'.'.

Technical dry goods (two): LeetCode21-40 detailed questions

 

A Sudoku.

Technical dry goods (two): LeetCode21-40 detailed questions

 

The answer is marked in red.

prompt:

  • The given Sudoku sequence only contains numbers 1-9 and the character'.'.
  • You can assume that a given Sudoku has only one unique solution.
  • A given Sudoku is always in 9x9 form.
public void solveSudoku(char[][] board) {
        boolean flag = dfs(board, 0 ,0);
        return;
    }
    boolean dfs(char[][] board, int i , int j){
        if(i == 9) return true;
        //到最后一列,换下一行
        if(j == 9) return dfs(board, i + 1, 0); 
        if(board[i][j] != '.') return dfs(board, i , j + 1);
        //选择列表1 - 9
        for(char c = '1'; c <= '9'; c ++){ 
            if (!isValid(board, i ,j ,c)) continue; 
            //选择
            board[i][j] = c; 
            //下一层
            if (dfs(board, i, j + 1)) return true;
            //撤销选择
            board[i][j] = '.';
        }
        return false;
    }
    boolean isValid(char[][] board , int x , int y ,char n){
        for (int i = 0;i < 9; i ++){
            //列重复
            if (board[i][y] == n) return false;
            //行重复
            if (board[x][i] == n) return false;
        }
        //找到九宫格左上元素,依次遍历
        for (int i = x / 3 * 3; i < x / 3 * 3 + 3; i ++){ 
            for (int j = y / 3 * 3;j < y / 3 * 3 + 3; j ++){
                if (board[i][j] == n) return false;
            }
        }
        return true;
    }

38. Appearance series

Given a positive integer  n (1 ≤  n  ≤ 30), output the nth  item of the appearance sequence  .

Note: Each item in the integer sequence will be represented as a string.

"Appearance sequence" is a sequence of integers, starting with the number 1, each item in the sequence is a description of the previous item. The first five items are as follows:

1.     1
2.     11
3.     21
4.     1211
5.     111221

The first item is the number 1

Describe the previous item, this number is 1 that is "a 1", recorded as 11

Describe the previous item, this number is 11, which is "two 1s", recorded as 21

Describe the previous item, this number is 21, which means "one 2 and one 1", recorded as 1211

Describe the previous item, this number is 1211, which is "one 1 one 2 two 1", recorded as 111221

Example 1:

输入: 1
输出: "1"
解释:这是一个基本样例。

Example 2:

输入: 4
输出: "1211"
解释:当 n = 3 时,序列是 "21",其中我们有 "2" 和 "1" 两组,"2" 可以读作 "12",也就是出现频次 = 1 而 值 = 2;类似 "1" 可以读作 "11"。所以答案是 "12" 和 "11" 组合在一起,也就是 "1211"。public String countAndSay(int n) {
        String s = "1";
        //循环n - 1次
        for(int i = 0; i < n - 1 ; i ++){
            StringBuilder sb = new StringBuilder();            //每一次记录相同一段的个数
            for(int j = 0; j < s.length(); j ++){
                int k = j;
                while(k < s.length() && s.charAt(k) == s.charAt(j)){
                    k++;                }                //个数                String count = k - j + "";
                //个数 + 字符
                sb.append(count + s.charAt(j));                j = k - 1;
            }            s= sb.toString();
        }        return s;
    }

39. Combined Sum

Given an array candidates with no duplicate elements and a target number target, find all combinations of candidates that can make the number sum target.

The number in candidates can be repeatedly selected without limitation.

Description:

  • All numbers (including target) are positive integers.
  • The solution set cannot contain repeated combinations.

Example 1:

输入:candidates = [2,3,6,7], target = 7,
所求解集为:
[
  [7],
  [2,2,3]
]

https://www.cnblogs.com/summerday152/p/13615904.html

public List<List<Integer>> combinationSum(int[] arr, int t) {
        List<List<Integer>> res = new ArrayList<>();        List<Integer> path = new ArrayList<>();
        Arrays.sort(arr);//排序是剪枝的前提
        dfs(res,path,0,arr,t);
        return res;
    }        void dfs(List<List<Integer>> res,List<Integer> path,int s,int[] arr, int t){
        if(t <= 0){
            if(t == 0){
                res.add(new ArrayList<>(path));
            }            return;
        }        for(int i = s; i < arr.length; i++){
            if(arr[i] > t){ //由于数组已经有序,当前这个数应该小于等于剩余数t
                break;
            }            path.add(arr[i]);
            dfs(res,path,i,arr,t-arr[i]); //因为
            path.remove(path.size()-1);
        }      }

40. Combination Sum II

Given an array of candidates and a target number target, find all combinations of candidates that can make the number sum target.

Each number in candidates can only be used once in each combination.

Description:

  • All numbers (including the target number) are positive integers.
  • The solution set cannot contain repeated combinations.

Example 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:[  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]public List<List<Integer>> combinationSum2(int[] arr, int t) {        List<List<Integer>> res = new ArrayList<>();        List<Integer> path = new ArrayList<>();
        Arrays.sort(arr);//排序是剪枝的前提
        dfs(res,path,0,arr,t);
        return res;
    }	// s 可以看成层数, i可以看成这一层从第几个开始    void dfs(List<List<Integer>> res,List<Integer> path,int s,int[] arr, int t){
        if(t <= 0){
            if(t == 0){
                res.add(new ArrayList<>(path));
            }            return;
        }        for(int i = s; i < arr.length; i++){ 
                        if(arr[i] > t){ //由于数组已经有序,当前这个数应该小于等于剩余数t
                break;
            }            //保证递归树的同一个层级不出现相同的元素            if(i > s && arr[i] == arr[i - 1]) continue;
            path.add(arr[i]);
            dfs(res,path,i+1,arr,t-arr[i]); 
            path.remove(path.size()-1);
        }      }

 If you think this article is helpful to you, you can like it and follow it to support it, or you can follow my public account. There are more technical dry goods articles and related information sharing on it, everyone learns and progresses together!

Guess you like

Origin blog.csdn.net/weixin_50205273/article/details/108941097