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

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背包问题,按照变式,注意边界条件和初始化,遍历顺序;

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

相关推荐
石像鬼₧魂石6 小时前
如何配置Fail2Ban的Jail?
linux·学习·ubuntu
Nan_Shu_6148 小时前
学习:VueUse (1)
学习
Li.CQ8 小时前
SQL学习笔记(二)
笔记·sql·学习
Huangxy__8 小时前
指针的补充学习
学习
Smartdaili China9 小时前
掌握Java网页抓取:技术与示例完整指南
java·网络·学习·指南·网页·住宅ip·爬虫api
charlie11451419110 小时前
如何快速在 VS2026 上使用 C++ 模块 — 完整上手指南
开发语言·c++·笔记·学习·现代c++
炽烈小老头12 小时前
【每天学习一点算法 2025/12/15】环形链表
学习·算法·链表
白帽子凯哥哥14 小时前
转行网络安全学习计划与报班建议
学习·安全·web安全·网络安全·渗透测试·漏洞挖掘·网安培训
ReaF_star15 小时前
【基线】关于Debian的一些简单安全配置及验证
学习·安全·debian