大型互联网公司最常见的leetcode编程题

2019.9.30

文章目录

  • 第一题(leetcode 46. Permutations,求字符串的全排列)
  • 第二题(leetcode 148. Sort List,给链表排序)
  • 第三题(lleetcode 22. Generate Parentheses,括号匹配问题)
  • 以下题目的类型为动态规划、回溯、深度遍历
  • 第四题(200. Number of Islands,区块计算问题)
  • 第五题(91. Decode Ways,编码组合问题)
  • 第六题(91. Decode Ways,编码组合问题)
  • 第八题(79. Word Search,常规矩阵字符串匹配问题,深度遍历类题型)

第一题(leetcode 46. Permutations,求字符串的全排列)

leetcod46,求字符串的全排列

对数组字符串等子集的排列组合题目的汇总归纳

对字符串进行全排列的问题经常出现在各大公司的面试题上,属于必须要掌握的题。
题目描述:
46. Permutations
Medium

Given a collection of distinct integers, return all possible permutations.

Example:

Input: [1,2,3]
Output:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]
import java.util.*;

import static leetcode.ImprotantSubsets.swap;

public class permute {
    public static void main(String[] args) {
        int[] array = {1,2,3};
        List> permute = permute(array);
        for (List list:permute){
            Iterator iterator = list.iterator();
            while (iterator.hasNext()){
                System.out.print(iterator.next() + " ");
            }
            System.out.println();
        }
    }

    public static List> permute(int[] nums) {
            List> result = new ArrayList<>();
            HashSet> set = new HashSet<>();
            //利用回溯法,将nums数组的元素都重新排序并装入set集合中,消除掉了重复的元素
            Resort(nums,set,0);
            // 利用集合的addAll方法,将某个集合的元素复制到本集合内
            result.addAll(set);
            return result;
    }

    private static void Resort(int[] nums, HashSet> set, int k) {
        if (k == nums.length - 1) {
            // 这里需要new 一个list 来接收nums数组的元素
            List list = new ArrayList<>();
            for (int n: nums
                 ) {
                list.add(n);
            }
            set.add(list);
        }
        // 关键的步骤,i = k不是i = 0;
        for (int i = k; i < nums.length; i++) {
            swap(nums,i,k);
            // 第三个参数要是k+1,而不是i+ 1,k
            Resort(nums,set,k+1);
            swap(nums,k,i);
        }



    }

第二题(leetcode 148. Sort List,给链表排序)

leetcode 148. Sort List


题目描述
148. Sort List
Medium

Sort a linked list in O(n log n) time using constant space complexity.

Example 1:

Input: 4->2->1->3
Output: 1->2->3->4
Example 2:

Input: -1->5->3->4->0
Output: -1->0->3->4->5

第一种方法,直接用优先队列排好序,然后重建链表,笔试的时候优先选简单的方法
//time complexity O(nlogn) space compexity O(n)

   public ListNode sortList2(ListNode head) {
        if(head==null) {
            return null;
        }
	//利用优先队列将链表中的数进行排序
        PriorityQueue q = new PriorityQueue();
        ListNode cur = head;
        ListNode dummy = cur;
        while(head!=null){
            q.add(head.val);
            head = head.next;
        }
        //重建链表
        while(q!=null&&cur!=null){
            cur.val = q.poll();
            cur = cur.next;
        }
        return dummy;
    }


第二种方法  通过归并排序来解决,

    public ListNode sortList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }

        // step 1. 通过两个指针不同移动速度行走将链表切分为等长的两段
        ListNode prev = null, slow = head, fast = head;

        while (fast != null && fast.next != null) {
            prev = slow;
            slow = slow.next;
            fast = fast.next.next;
        }

        prev.next = null;

        // step 2. 对两段链表进行排序
        ListNode l1 = sortList(head);
        ListNode l2 = sortList(slow);

        // step 3. 将两段链表进行合并
        return merge(l1, l2);
    }
		// 合并的方法,和数组合并的原理相同
    ListNode merge(ListNode l1, ListNode l2) {
        ListNode l = new ListNode(0), p = l;

        while (l1 != null && l2 != null) {
            if (l1.val < l2.val) {
                p.next = l1;
                l1 = l1.next;
            } else {
                p.next = l2;
                l2 = l2.next;
            }
            p = p.next;
        }

        if (l1 != null)
            p.next = l1;

        if (l2 != null)
            p.next = l2;

        return l.next;
    }
//

第三题(lleetcode 22. Generate Parentheses,括号匹配问题)

leetcode 22. Generate Parentheses,括号匹配

题目描述
22. Generate Parentheses
Medium

Share
Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

For example, given n = 3, a solution set is:

[
  "((()))",
  "(()())",
  "(())()",
  "()(())",
  "()()()"
]


// 利用回溯的方法可以减少匹配的复杂度
   /* public static List generateParenthesis1(int n) {
        List list = new ArrayList();
        backtrack(list, "", 0, 0, n);
        return list;
    }

    public static void backtrack(List list, String str, int open, int close, int max){
        // 递归的终止条件为字符串str的长度达到最大值
        if(str.length() == max*2){
            list.add(str);
            return;
        }
        // 先进行左括号递归
        if(open < max) {
            backtrack(list, str + "(", open + 1, close, max);
        }
        // 要达到匹配的条件为右括号的个数一定小于等于左括号,但这里得是"<",因为
        // 这一步 open 的值为max +1
        if(close < open) {
            backtrack(list, str + ")", open, close + 1, max);
        }
    }*/

以下题目的类型为动态规划、回溯、深度遍历

第四题(200. Number of Islands,区块计算问题)

200. Number of Islands

// 该题也是笔试常见题型,求1组成的区块岛屿有多少个,一般的思路是遍历一遍二维数组,在遍历的过程中,将属于同一区块的1设置为0,然后 count++,统计所有的区块个数
题目描述:
200. Number of Islands
Medium
Given a 2d grid map of '1's (land) and '0's (water), count 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:
11110
11010
11000
00000

Output: 1


Example 2:

Input:
11000
11000
00100
00011

Output: 3




int n,m ;
    public int numIslands(char[][] grid) {
        int cout = 0;
        n = grid.length;
        m = grid[0].length;
        // 遍历数组,找到 字符为 '1' 的元素 并对所有和'1'字符相连的元素进行递归修改
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (grid[i][j] == '1') {
                    resulve(grid,i,j);
                    cout++;
                }
            }
        }
        return cout;
    }

    private void resulve(char[][] grid, int i, int j) {
        
        if (i < 0 || i >= n || j < 0 || j >= m || grid[i][j] =='0') {
            return;
        }
        // 将 '1' 字符修改为 '0',并对其上下左右的字符元素进行递归判断
        grid[i][j] = '0';
        resulve(grid,i+1,j);
        resulve(grid,i,j+1);
        resulve(grid,i,j-1);
        resulve(grid,i-1,j);
    }

第五题(91. Decode Ways,编码组合问题)

leetcod91. Decode Ways,编码组合问题

这类编码问题需要找到题目内在的规律,才能通过动态规划的转化表达式来求出结果,



题目描述:A message containing letters from A-Z is being encoded to numbers using the following mapping:

'A' -> 1
'B' -> 2
...
'Z' -> 26
Given a non-empty string containing only digits, determine the total number of ways to decode it.

Example 1:

Input: "12"
Output: 2
Explanation: It could be decoded as "AB" (1 2) or "L" (12).
Example 2:

Input: "226"
Output: 3
Explanation: It could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6).

题解代码如下:

class Solution {
    public int numDecodings(String s) {
          if(s == null || s.length()==0){
            return 0;
        }
 
        int[] dp = new int[s.length()];
        // 考虑字符为'0'的情况,字符为零的时候是不能被表示的
        dp[0] = s.charAt(0)=='0'? 0 : 1;
        for(int i=1; i=10 && pre<=26){
                dp[i] += i>=2? dp[i-2] : 1;
            } 
        }
        return dp[s.length()-1];
    }
}

第六题(91. Decode Ways,编码组合问题)

leetcod91. Decode Ways,编码组合问题





题目描述:139. Word Break


Favorite

Share
Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words.

Note:

The same word in the dictionary may be reused multiple times in the segmentation.
You may assume the dictionary does not contain duplicate words.
Example 1:

Input: s = "leetcode", wordDict = ["leet", "code"]
Output: true
Explanation: Return true because "leetcode" can be segmented as "leet code".
Example 2:

Input: s = "applepenapple", wordDict = ["apple", "pen"]
Output: true
Explanation: Return true because "applepenapple" can be segmented as "apple pen apple".
             Note that you are allowed to reuse a dictionary word.
Example 3:

Input: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
Output: false```
这类题有多种解法,通用的解法是可以建立字典树,然后用字典树来找到每个单词的dp。当然也可以直接使用dp的方法,不过找转化方程要难度大很多。



纯使用dp的题解代码如下:

public class WordBreak139 {
    public boolean wordBreak(String s, List wordDict) {

        int len = s.length();
        //用一个长度为length的boolean数组来表示每个单词是否可以匹配
        boolean[] v = new boolean[len+1];
        v[0] = true;

        for(int i = 0;i wordDict) {
        TrieNode t = new TrieNode(), cur;
        // 建立字典树
        for (String i : wordDict) addWord(t, i);
        char[] str = s.toCharArray();
        int len = str.length;
        boolean[] f = new boolean[len + 1];
        f[len] = true;
        // 通过字典树来进行判断
        for (int i = len - 1; i >= 0; i--) {
            //System.out.println(str[i]);
            cur = t;
            for (int j = i; cur != null && j < len ; j++) {
                cur = cur.c[(int)str[j]];
                if (cur != null && cur.isWord && f[j + 1]) {
                    f[i] = true;
                    break;
                }
            }
        }
        return f[0];
    }
}

第八题(79. Word Search,常规矩阵字符串匹配问题,深度遍历类题型)

79. Word Search





79. Word Search
Medium


Share
Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

Example:

board =
[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

Given word = "ABCCED", return true.
Given word = "SEE", return true.
Given word = "ABCB", return false.
这类矩阵的字符串匹配问题通用的解法就是进行深度遍历,注意一些递归的条件基本能很快做出来

代码如下: 

public class WordSearch79 {

    public static void main(String[] args) {
        char[] []board =
                {
                        {'A', 'B', 'C', 'E'},
                        {'S', 'F', 'C', 'S'},
        {'A', 'D', 'E', 'E'}
    };
        String word = "ABCCED";
        boolean exist = exist(board, word);
        System.out.println(exist);
    }
    public static boolean exist(char[][] board, String word) {
        int row = board.length;
        int col = board[0].length;
        char[] chars = word.toCharArray();
        boolean flag = false;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
               /* if (board[i][j] == chars[0]) {
                    flag = getResult(board, chars, i, j, 0);
                    break;
                }*/
               if (getResult(board,chars,i,j,0)) {
                   return true;
               }
            }

        }
        return flag;
    }

    private static boolean getResult(char[][] board, char[] chars, int i, int j,int count) {

        if (count == chars.length) {
            return true;
        }
        if ( i < 0 || j < 0 || i >= board.length || j >= board[0].length || board[i][j] != chars[count]  ) {
            return false;
        }
        // 这里需要把遍历过的字符标记一下,避免重复遍历
        board[i][j] = '*';
       boolean result = getResult(board,chars,i+1,j,count+1) ||
        getResult(board,chars,i-1,j,count+1) ||

        getResult(board,chars,i,j+1,count+1) ||

        getResult(board,chars,i,j-1,count+1);
       // 把标记的字符还原
       board[i][j] = chars[count];
       return result;
    }
    }

你可能感兴趣的:(算法题)