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

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前一段的有效长度

dp[i] = dp[i - 1] + 2 + (pre > 0 ? dp[pre - 1] : 0);

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

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

相关推荐
西岸行者4 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意4 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码4 天前
嵌入式学习路线
学习
毛小茛4 天前
计算机系统概论——校验码
学习
babe小鑫4 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms4 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下4 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。4 天前
2026.2.25监控学习
学习
im_AMBER4 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J4 天前
从“Hello World“ 开始 C++
c语言·c++·学习