21年9月第四周 力扣每日一题记录

题目

lc725.分隔链表
lc326. 3的幂
lc430. 扁平化多级双向链表
lc583. 两个字符串的删除操作
lc371. 两整数之和

09-22 lc725.分隔链表

  • 第一天开始每日一题,做个记录吧,也是让自己坚持下去
  • 题意为按照k来将链表分成k份,任意两份长度不超过1
  • 那么很显然,最长的区间长度,len/k + 1, 个数一共有len%k个 最短的len/k
  • 代码如下,基本是优解
  • 好久没写java了,手挺生的,敲挺慢的哈哈哈
class Solution {
    
    
    //首先需要知道长度
    //平均长度 len/k,则有len % k个是len/k +1的其余都是len/k
    //然后进行分割
    public ListNode[] splitListToParts(ListNode head, int k) {
    
    
        //确定链表长度
        int len = 0;
        ListNode cur = head;
        while(cur!=null){
    
    
            cur = cur.next;
            len++;
        }
        //计算平均长度
        int avg = len/k;
        int longer = len%k;//avg +1 的有这么多
        //进行分割
        cur = head;
        ListNode[] res = new ListNode[k];
        for(int i=0; i<k; i++){
    
    
            ListNode newHead = splitHelp(cur,longer-->0?avg+1:avg);
            res[i] = cur;
            cur = newHead;
        }
        return res;
    }

    //截取k个长度的链表,返回新头部
    private ListNode splitHelp(ListNode head, int k){
    
    
        if(k==0||head==null) return head;
        while(k>1){
    
    
            head = head.next;
            k--;
            if(head==null) return head;
        }
        ListNode next = head.next;
        head.next = null;
        return next;
    }
}

09-23 lc326. 3的幂

  • 不让用迭代和递归
  • 这题两个思路,一个是将正数的3的幂全部写出来,放到set中,然后对比就行
  • 另一个思路是,写出最大的3的幂,用它来除。对于质数的幂,它的因子只可能是质数的幂
	public boolean isPowerOfThree(int n) {
    
    
        //n是0,直接false
        //否则看看能不能被1162261467 整除
        return n>0 && 1162261467%n==0;
    }

09-24 lc430. 扁平化多级双向链表

  • 这一题就是将多个链表进行合并成一个链表,而多个链表之间通过child指针来进行连接
  • 遍历的逻辑是遇到child就走child,没有child就走next,如果为空,就返回让一次的child那里,继续走next
  • 所以整体的逻辑可以用栈来进行表示,如果有child的节点,就把它的next放进栈里,(当然要进行判空)
  • 这里的输入,写的非常的难懂,配的图片又小,有点不太开心,直接看图片就能懂,别看那个数组了,有点反人类
  • 题还是非常简单的,一眼就能出思路,不过链表嘛,以及循环逻辑,还是稍微有一点点麻烦的
  • 然后因为要返回一个链表,所以我就新建了节点,空间复杂度高一点,不然会很麻烦
class Solution {
    
    
    //这边的这个输入没有什么问题,不用看这个
    //然后就是感觉像是栈
    //遍历链表,如果当前节点有child,就放入栈,访问child,如果没有就访问next,如果也没有next,就访问出栈的节点
    //然后这个是要返回一个新的链表,所以直接复制一个好了
    public Node flatten(Node head) {
    
    
        Deque<Node> stack = new LinkedList<>();
        Node cur = head;
        Node newHead = new Node();
        Node newCur = newHead;
        while(cur!=null||!stack.isEmpty()){
    
    
            if(cur==null) cur = stack.pop();
            Node newNext = new Node(cur.val);
            newCur.next = newNext;
            newNext.prev = newCur;
            newCur = newNext;

            if(cur.child!=null){
    
    
                if(cur.next!=null) stack.push(cur.next);
                cur = cur.child;
            }
            else cur = cur.next;
        }
		//处理一下头部
        if(head!=null) newHead.next.prev=null;
        return newHead.next;
    }
}

09-25 lc583. 两个字符串的删除操作

  • 这是一个标准的双序列dp问题,难度较低
  • 平板的键盘不太行,用起来太煎熬了,打算买个键盘
  • f [ i ] [ j ] = w o r d 1 前 i 个 和 w o r d 2 前 j 个 相 同 的 步 骤 数 f[i][j]=word1前i个和word2前j个相同的步骤数 f[i][j]=word1iword2j
  • 如果当前i字符和j字符相等,则 f [ i ] [ j ] = f [ i − 1 ] [ j − 1 ] f[i][j]=f[i-1][j-1] f[i][j]=f[i1][j1],如果不等,则就直接是 f [ i − 1 ] [ j ] + 1 , f [ i ] [ j − 1 ] + 1 f[i-1][j]+1, f[i][j-1]+1 f[i1][j]+1,f[i][j1]+1的最大值了。
  • 总之就是把问题抛给上一个就可以了
  • 代码比较简单明了,注意要初始化,别忘了就行,逻辑比较简单

class Solution {
    
    
    public int minDistance(String word1, String word2) {
    
    
        char[] w1 = word1.toCharArray();
        char[] w2 = word2.toCharArray();
        int m = w1.length, n = w2.length;
        int[][] f = new int[m+1][n+1];
        
        //初始条件:当i为0时,就为j,j为0时,就为i
        for(int i=0; i<m+1; i++) f[i][0] = i;
        for(int j=0; j<n+1; j++) f[0][j] = j;
        
        for(int i=1; i<=m; i++){
    
    
            for(int j=1; j<=n; j++){
    
    
                if(w1[i-1]==w2[j-1]) f[i][j] = f[i-1][j-1];
                else f[i][j] = Math.min(f[i-1][j],f[i][j-1])+1;
            }
        }
        return f[m][n];
    }
}

09-26 lc371. 两整数之和

  • 不让用+,-
  • 所以自然而然用位运算,
  • 这里其实是可以用位运算来解决所有的加减法的,贴上个链接https://blog.csdn.net/ojshilu/article/details/11179911
  • 递归加位运算
	//每次递归都是: 不考虑进位加法结果 + 进位结果 》》》递归得出最终结果
	public int getSum(int a, int b) {
    
    
        if(b==0) return a;
        int s = a^b;//不考虑进位的加情况
        int c = (a&b)<<1;//这里是进位情况,左移一就到了该到的位置
        return getSum(s,c);
    }

猜你喜欢

转载自blog.csdn.net/qq_34687559/article/details/120417379