栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

力扣每日练习-java版(一)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

力扣每日练习-java版(一)

力扣每日练习(一)

2000. 反转单词前缀

思路代码时空复杂度备注 48. 旋转图像

思路代码时空复杂度备注 22. 括号生成

思路代码时空复杂度备注 617. 合并二叉树

思路代码时空复杂度 160. 相交链表

思路代码时空复杂度备注 78. 子集

思路代码时空复杂度备注

2000. 反转单词前缀

https://leetcode-cn.com/problems/reverse-prefix-of-word/

思路

1.找字符所在位置,没找到返回原字符串,否则进行第二步
2.反转0 ~ i位置的字符串,拼接上i+1 ~ n-1 位置的字符串,返回

代码
class Solution {
	public String demo(String word,char ch){
		int pos = word.indexOf(ch);
        if (pos < 0) return word;
		return new StringBuilder(word.substring(0,pos+1)).reverse().append(word.substring(pos+1)).toString();
	}
}
时空复杂度

1.时间复杂度 O(n)
遍历字符串
2.空间复杂度 O(n)

备注
    str.charAt(i) 获取字符串str第i个位置上的字符,i从0开始str.substring(a,b) 截取a ~ b位置的字符串 [a,b)str.substring(a) 截取a位置之后的所有字符串(包括a位置)new StringBuilder(str).reverse() 反转字符串new StringBuilder(str).append(str2) 在当前字符串后追加字符串new StringBuilder(str).toString() StringBuilder转String类型char[] chars = str.toCharArray(); 字符串转字符数组
48. 旋转图像

https://leetcode-cn.com/problems/rotate-image/

思路

找规律

    顺时针转90度。
    - 二维矩阵 方向对角线镜像处理
    - 二维矩阵 左右镜像逆时针90度。
    - 二维矩阵 / 方向对角线镜像处理
    - 二维矩阵 左右镜像
代码
class Solution {
    public void rotate(int[][] matrix) {
    //矩阵大小
		int n = matrix.length;
		// 先沿对角线镜像对称二维矩阵
		for(int i = 0;i < n;i++) {
			for(int j = i;j< n;j++) {
				if(j!=i){
					int tmp = matrix[i][j];
					matrix[i][j] = matrix[j][i];
					matrix[j][i] = tmp;
				}
			}
		}
		// 然后反转二维矩阵的每一行(左右镜像对称)
		for(int i = 0;i 
时空复杂度 
    时间复杂度 O(N2)
    其中 N 是matrix 的边长。对于每一次翻转操作,我们都需要枚举矩阵中一半的元素。空间复杂度 O(1)
    原地旋转,没有开辟新的空间。
备注
    arr.length 数组长度str.length() 字符串长度list.size() / set.size() 列表/集合长度
22. 括号生成

https://leetcode-cn.com/problems/generate-parentheses/

思路

找出所有可行解->回溯
分析:
题目可以改写为,n对括号,共2n个位置,每个位置都可以放左括号或右括号,能够生成多少种合法的组合?
我们可以把所有情况穷举出来,去掉不合法的情况,就得到了最终结果。

明确下合法组合的要求:

    有效括号组合一定是左括号数和右括号数相等对于一个「合法」的括号字符串组合 p,必然对于任何 0 <= i < len( p ) 都有:子串 p[0…i] 中左括号的数量都大于或等于右括号的数量。
代码
class Solution {
    public List generateParenthesis(int n) {
        if(n<=0) return new ArrayList();
		//有效括号组合
		List ans = new ArrayList<>();
		//每次回溯过程的路径
		StringBuilder track = new StringBuilder();
		//left剩下可用左括号的数量,right可用右括号数量,都初始化为n
		backtrack(n, n, track, ans);
		return ans;
    }

    public void backtrack(int left, int right, StringBuilder track, List ans) {
        //如果左括号剩下的多,或数量小于0,不合法
        if(left>right || left <0 || right < 0) return;
        //所有括号都恰好用完,得到一个合法的括号组合
        if(left==0 && right==0) {
            ans.add(track.toString());
            return;
        }
        //否则,继续往下遍历
        //尝试放一个左括号
        track.append("(");
        backtrack(left-1,right,track,ans);
        track.deleteCharAt(track.length()-1);
        //尝试放一个右括号
        track.append(")");
        backtrack(left,right-1,track,ans);
        track.deleteCharAt(track.length()-1);
    }
}
时空复杂度

    时间复杂度:

    递归函数本身的时间复杂度是 O(1),递归次数主要是看「状态」的个数,对于 backtrack 函数,状态有三个,分别是 left, right, track,这三个变量的所有组合个数就是 backtrack 函数的状态个数(调用次数)。left 和 right 的组合取值就是 0 ~ n ,组合起来 n2 种; track 的长度虽然取在 0~2n,但对于每一个长度,它还有指数级的括号组合,这个是不好算的。
    有时间可以了解下「卡特兰数」相关的知识。

    空间复杂度:O(n)

    除了答案数组之外,我们所需要的空间取决于递归栈的深度,每一层递归函数需要 O(1) 的空间,最多递归 2n 层,因此空间复杂度为 O(n)

备注
    str.deleteCharAt(i); 删除某位置的字符对于递归相关的算法,时间复杂度 =(递归次数)*(递归函数本身的时间复杂度)。
617. 合并二叉树

https://leetcode-cn.com/problems/merge-two-binary-trees/

思路

dfs,从根节点开始合并 -> 二叉树先序遍历。

代码
class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        //两个节点都为null,返回null
		if(root1==null && root2==null) return null;
		//一个节点为null,另一个节点非空,直接合并为非空的节点
		if(root1==null) return root2;
		if(root2==null) return root1;
		//都不为空,合并数值
		TreeNode newNode = new TreeNode(root1.val+root2.val);
		newNode.left = mergeTrees(root1.left,root2.left);
		newNode.right = mergeTrees(root1.right,root2.right);
		return newNode;
    }
}
时空复杂度
    时间复杂度 O(min(m,n))
    其中 m 和 n分别是两个二叉树的节点个数。空间复杂度 O(min(m,n))
    递归栈的深度
160. 相交链表

https://leetcode-cn.com/problems/intersection-of-two-linked-lists/

思路

方法一:暴力解法,将链表A的节点装入set,再将链表B的节点依次存入set,如果有相交节点,就返回
方法二:双指针,将空间复杂度降为O(1)
这个方法关键在于怎么能让 p1 和 p2 能够同时到达相交节点 c1。
如果用两个指针 p1 和 p2 分别在两条链表上前进,我们可以让 p1 遍历完链表 A 之后开始遍历链表 B,让 p2 遍历完链表 B 之后开始遍历链表 A,这样相当于「逻辑上」两条链表接在了一起。

代码

方法一:

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA == null || headB == null) return null;
        Set set = new HashSet<>();
        ListNode tmpA = headA;
        while(tmpA != null) {
            set.add(tmpA);
            tmpA = tmpA.next;
        }
        ListNode tmpB = headB;
        while(tmpB != null) {
            if(!set.add(tmpB)){
                return tmpB;
            }
            tmpB = tmpB.next;
        }
        return null;
    }
}

方法二:

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if (headA == null || headB == null) {
            return null;
        }
        ListNode pA = headA, pB = headB;
        while (pA != pB) {
            pA = pA == null ? headB : pA.next;
            pB = pB == null ? headA : pB.next;
        }
        return pA;
    }
}
时空复杂度
    时间复杂度
    方法一: O(m+n)
    其中 mm 和 nn 是分别是链表headA 和headB 的长度。需要遍历两个链表各一次。
    方法二:O(m+n)
    其中 m 和 n 是分别是链表headA 和headB 的长度。两个指针同时遍历两个链表,每个指针遍历两个链表各一次。空间复杂度
    方法一:O(m)
    其中 m 是链表headA 的长度。需要使用哈希集合存储链表headA 中的全部节点。
    方法二:O(1)
备注
    set.add(x) 插入成功返回true,失败(有重复的元素)返回false
78. 子集

https://leetcode-cn.com/problems/subsets/

思路

找出全部可行解->回溯。本质是遍历一颗回溯树。

代码
class Solution {
    List> res=new ArrayList<>();
    public List> subsets(int[] nums) {
        //记录走过的路径
        List track = new ArrayList<>();
        backtrack(nums,0,track);
        return res;
    }
    void backtrack(int[] nums, int start, List track) {
        //注意这里不能直接add(track),否则add到res中的是track的引用,最后会全部变成空list []
        res.add(new ArrayList(track));
        for(int i = start;i 
时空复杂度 

    时间复杂度 O(N*2N)
    一个大小为 N 的集合的子集总共有2N个,所以说至少要对 res 添加 2N次元素,还要考虑将这些元素追加到res的效率,因为nums[i]也是数组,追加 是把 nums[i] copy 一份然后添加到数组的最后,所以一次操作的时间是 O(N)。总的时间复杂度就是 O(N*2N)。

    空间复杂度 O(n)
    如果不计算储存返回结果所用的空间的,只需要 O(N) 的递归堆栈空间。如果计算 res 所需的空间,应该是 O(N*2N)。

备注
    res.add(new ArrayList(track));
    注意这里不能直接add(track),否则add到res中的是track的引用,最后会全部变成空list,[]list.remove(i) 移除list某位置的元素
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/727783.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号