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

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

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

相关推荐
jz_ddk21 小时前
[学习] 卫星导航的码相位与载波相位计算
学习·算法·gps·gnss·北斗
华清远见成都中心1 天前
人工智能要学习的课程有哪些?
人工智能·学习
hssfscv1 天前
Javaweb学习笔记——后端实战2_部门管理
java·笔记·学习
白帽子黑客罗哥1 天前
不同就业方向(如AI、网络安全、前端开发)的具体学习路径和技能要求是什么?
人工智能·学习·web安全
于越海1 天前
材料电子理论核心四个基本模型的python编程学习
开发语言·笔记·python·学习·学习方法
我命由我123451 天前
开发中的英语积累 P26:Recursive、Parser、Pair、Matrix、Inset、Appropriate
经验分享·笔记·学习·职场和发展·求职招聘·职场发展·学习方法
北岛寒沫1 天前
北京大学国家发展研究院 经济学原理课程笔记(第二十三课 货币供应与通货膨胀)
经验分享·笔记·学习
知识分享小能手1 天前
Ubuntu入门学习教程,从入门到精通,Ubuntu 22.04中的Java与Android开发环境 (20)
java·学习·ubuntu
好奇龙猫1 天前
【大学院-筆記試験練習:数据库(データベース問題訓練) と 软件工程(ソフトウェア)(10)】
学习
wdfk_prog1 天前
[Linux]学习笔记系列 -- [fs][proc]
linux·笔记·学习