【学习日记】【刷题回溯、贪心、动规】

1.k个一组翻转

java 复制代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        if(head==null||k == 1){
            return head;
        }

        //需要三 + 一个指针,上一组的尾部preTail
        //当前组的 头和尾
        //下一组的存储 尾部 

        //最后指针更新


        ListNode dummy  = new ListNode(0);
        dummy.next = head;
        ListNode curr = head;//只需要上一组和当先组
        ListNode preTail = dummy;//只需要上一组和当先组


        while(curr!=null){

            ListNode kNode = getKNode(curr,k);

            if(kNode == null){
                break;
            }
            //2.存储下一组头部 做连接
            ListNode nextGroupHead = kNode.next;


            //3.断开翻转
                ListNode currGroupHead = curr;
                ListNode currGroupTail = kNode;

                ListNode[] a = reverseList(currGroupHead,currGroupTail);


                currGroupHead = a[0];
                currGroupTail = a[1];
            //4.连接;   更新指针

                preTail.next = currGroupHead;
                currGroupTail.next = nextGroupHead;

            //5. 更新指针

            preTail = currGroupTail;
            curr = nextGroupHead;

        }
        return dummy.next;
    

       
    }


    private ListNode getKNode(ListNode head,int k){
        //这里相当于head往后数k个得到的节点
        ListNode curr = head;
        while(curr!=null&&k!=1){
            curr= curr.next;
            k--;
        }
        return curr;
    }


    private ListNode[] reverseList(ListNode head,ListNode tail){
        ListNode pre =  tail.next;
        ListNode curr = head;

        while(pre!=tail){
            ListNode next = curr.next;
            curr.next = pre;
            pre = curr;
            curr = next;
        }




        //这里实现翻转后,就相当于tail在前面,head在后面
        //而且也接上了
        return  new ListNode[]{tail,head};
    }
}

感觉链表的题的话,主要注意下,对于不能链表的切断和连接,对于引用类型,"指针"指向的位置,以及前后关系注意;

2.回溯算法

N皇后

复制代码
class Solution {
    public List<List<String>> solveNQueens(int n) {
        List<List<String>> result = new ArrayList<>();
        char[][] board = new char[n][n];

        for(int i = 0;i<n;i++){
            Arrays.fill(board[i],'.');
        }
        Set<Integer> cols = new HashSet<>();
        Set<Integer> diag1 = new HashSet<>();
        Set<Integer> diag2 = new HashSet<>();

        backtrack(result,board,0,n,cols,diag1,diag2);
        return result;
    }
    private static void backtrack(List<List<String>> result,char[][] board,int row,int n,
                                        Set<Integer> cols,Set<Integer> diag1,Set<Integer> diag2){
    if(row ==n){
        result.add(construtBoard(board));
        return;
    }
    for(int col = 0;col < n;col++){
        if(cols.contains(col) || diag1.contains(row -col) ||
        diag2.contains(row + col)){
            continue;
        }
        board[row][col] = 'Q';
        cols.add(col);
        diag1.add(row -col);
        diag2.add(row+col);

        backtrack(result,board,row+1,n,cols,diag1,diag2);
        board[row][col] = '.';
        cols.remove(col);
        diag1.remove(row-col);
        diag2.remove(row+col);
    }


    
    
    
    }
    private static List<String> construtBoard(char[][] board){
        List<String> res = new ArrayList<>();
        for(char[] row : board){
            res.add(new String(row));
        }
        return res;
    }


}

这里主要复习了下回溯的步骤;里面还有static静态关键字,静态方法里面调用对象、创建对象调用方法;不能直接调用实例方法;

静态方法的限制是:不能隐式的使用this,只要数据是显示提供的,(通过参数、局部变量、new等),就可以操作

3.贪心、动态规划

有的问题适合用贪心、有的问题适合用动态规划,不行就用回溯暴力搜索,
像这种32最长有效括号,这种动态规划、hard题,一般都是注意对边界条件处理,注意状态转移方程;

// 核心状态转移方程:

// 当前有效长度 = 前一个有效长度 + 2(当前匹配对) + pre前一段的有效长度

dpi = dpi - 1 + 2 + (pre > 0 ? dppre - 1 : 0);

0-1背包问题,按照变式,注意边界条件和初始化,遍历顺序;

二刷的过程感觉自己理解的快了,但是还不会咋优化,一些基本的算法如二分、排序、双指针等等还不能信手拈来,后面慢慢来吧

相关推荐
一隅论数智2 天前
给AI一张“业务概念地图“:本体如何从哲学走向企业智能
大数据·人工智能·经验分享·笔记·学习·学习方法·政务
XiHongShi20162 天前
STM32F407 RTC定时器例程,建议保存
stm32·单片机·学习
爱吃苹果的日记本2 天前
离散数学第六课
学习·离散数学
AI职业加油站2 天前
AI智能体应用工程师证书:政策红利下的职业新风口
大数据·运维·人工智能·学习·职场发展
旖旎夜光2 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
奇思妙想聪明勤奋的小羊2 天前
DeepAgents第5章:子Agent 与上下文隔离—让 Agent学会委派
人工智能·python·学习·语言模型
霍霍的袁2 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
彧azz2 天前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试
我爱cope2 天前
【操作系统 | 计算机硬件:CPU、内存与 I/O 如何支撑操作系统?】
学习·操作系统