Leetcode hot 100题目 medium部分 思路

22. 括号生成

思路:需要用到树形结构,穷举出所有的n对括号的组合,同时还要再进行剪枝操作。当左括号数量占了字符数量一般以上,或字符串中右括号数量大于左括号数量,进行剪枝。当字符串的长度等于2 * 传入的n  时,说明满足条件,将字符添加到list中。

可以看视频题解:https://leetcode.cn/problems/generate-parentheses/solution/pei-yang-chou-xiang-si-wei-hui-su-jie-fa-7dwu/

DFS
class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> res = new ArrayList<>();
        if (n <= 0) return res;
        dfs(n, "", res, 0, 0);
        return res;
    }

    private void dfs(int n, String path, List<String> res, int open, int close) {
        if (open > n || close > open) return;

        if (path.length() == 2 * n) {
            res.add(path);
            return;
        }

        dfs(n, path + "(", res, open + 1, close);
        dfs(n, path + ")", res, open, close + 1);
    }
}
作者:tangweiqun
链接:https://leetcode.cn/problems/generate-parentheses/solution/pei-yang-chou-xiang-si-wei-hui-su-jie-fa-7dwu/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

114. 二叉树展开为链表

思路:借助前序遍历,将二叉树的节点存储到单链表中,再遍历链表,将左右子树设置为左子树为空,右子树为下一个节点。

查看代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public void flatten(TreeNode root) {
        List<TreeNode> list = new ArrayList<TreeNode>();
        preorderTraversal(root, list);
        int size = list.size();
        for (int i = 1; i < size; i++) {
            TreeNode prev = list.get(i - 1), curr = list.get(i);
            prev.left = null;
            prev.right = curr;
        }
    }

    public void preorderTraversal(TreeNode root, List<TreeNode> list) {
        if (root != null) {
            list.add(root);
            preorderTraversal(root.left, list);
            preorderTraversal(root.right, list);
        }
    }
}

更多解法:leetcode

 

34. 在排序数组中查找元素的第一个和最后一个位置

参考剑指offer53题实现,思路大概不变。

要注意判断数组为空的条件:

nums == null || 0 == nums.length

 

二分查找边界

class Solution {
    public int[] searchRange(int[] nums, int target) {
        if(nums == null || 0 == nums.length) return new int[]{-1,-1};

        boolean flag = false;
        for(int num : nums){
            if(num == target){
                flag = true;
            }
        }
        if(flag == false) return new int[]{-1,-1};
        

        int i = 0,j = nums.length-1;
        while(i <= j){
            int mid = (i + j) / 2;
            if(nums[mid] <= target) i = mid + 1;
            else j = mid -1;
        }
        int right = i;

        i = 0;j = nums.length-1;
        while(i <= j){
            int mid = (i + j) / 2;
            if(nums[mid] >= target) j = mid - 1;
            else i = mid + 1;
        }
        int left = j;
        return new int[]{left+1, right-1};
    }
}

 

还可以参考解法:https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/solution/tu-jie-er-fen-zui-qing-xi-yi-dong-de-jia-ddvc/

思考:关于‘二分查找’的几种写法。

102. 二叉树的层序遍历

剑指offer 32题。


class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        if(root == null) return new ArrayList();
        Queue<TreeNode> q = new LinkedList<TreeNode>(){{offer(root);}};
        List tar = new ArrayList();
        while(!q.isEmpty()){
            List<Integer> list = new ArrayList<Integer>();

            int count = q.size();

            while(count > 0){
                TreeNode node = q.poll();
                list.add(node.val);
                if(node.left != null) q.offer(node.left);
                if(node.right != null) q.offer(node.right);
                count--;
            }
            tar.add(list);
        }
        return tar;
    }
}

3. 无重复字符的最长子串

剑指offer48题

滑动窗口

public int lengthOfLongestSubstring(String s) {
        //if(s==null) return 0;这句话可以不加,s.length()长度为0时,不进入下面的循环,会直接返回max=0;
        //划定当前窗口的坐标为(start,i],左开右闭,所以start的初始值为-1,而非0。
        int max = 0,start =-1;
        //使用哈希表map统计各字符最后一次出现的索引位置
        HashMap<Character,Integer> map = new HashMap<>();
        for(int i=0;i<s.length();i++){
            char tmp = s.charAt(i);
            
            //当字符在map中已经存储时,需要判断其索引值index和当前窗口start的大小以确定是否需要对start进行更新:
            //当index>start时,start更新为当前的index,即更新窗口的左边界,否则保持不变。
            //注意若index作为新的start,计算当前滑动空间的长度时也是不计入的,左开右闭,右侧s[i]会计入,这样也是防止字符的重复计入。
            //带入字符串:pwwkew
            if(map.containsKey(tmp)) start = Math.max(start,map.get(tmp));
            
            //如果map中不含tmp,此处是在map中新增一个键值对,否则是对原有的键值对进行更新
            map.put(tmp,i);
            
            //i-start,为当前滑动空间(start,i]的长度,若其大于max,则需要进行更新。
            max = Math.max(max,i-start);
        }
        return max;
    }

79. 单词搜索

剑指 Offer 12题

posted on 2022-05-29 07:36  passionConstant  阅读(23)  评论(0编辑  收藏  举报