所有问题的下标可能涉及到越界的,要么在循环的起始条件里就要搞好,要么就特判

滑动窗口/区间类的左闭右闭思想:

(下面这种写法不要看了)

l=0
r=-1
while(r<n-1)
{
r++
//更新有关数据
while(r<n-1&&数据有效&&可以向右拓展........)
    {
    //注意此时也是合法窗口,因此也有必要更新答案
        r++;//向右拓展
        //更新有关数据
    }
//更新l(这种更新方式有很多,可以l++,也可以l = r,也可以用循环while(l<=r)缩短窗口(注意必须l<=r,l==r当然有效)
//找到了合法窗口,更新答案
}

但是我随后在某些地方也看到的全新的维护,似乎更好理解:

int l = 0;
int r = -1;
while(r<n-1){
    r++
    //进窗口,处理有关数据
    while(窗口不合法){
        //l准备出窗口
        l++;
    }
    //此时窗口合法,更新答案
}

或者变体

int l = 0;
int r = -1;
while(r<n-1){
    r++
    //进窗口,处理有关数据
    while(窗口合法但是右移更优){
        //如果“右移更优”这里需要更新答案,比如最小覆盖子串
        //l准备出窗口
        l++;
    }
}

同时这种写法的价值是:

l=0
r=-1
while(r<n-1)
{
r++
//更新有关数据
while(r<n-1&&数据有效&&可以向右拓展........)
    {
        r++;//向右拓展
        //更新有关数据
    }
//找到了合法窗口,更新答案
l = r+1;
}

这种方式主要用来处理:一直向右拓展窗口,直到某个时候不合法。然后更新答案。如合并区间 这题

链表问题

if (head ==null ||head.next==null) return head;(当然如果不好处理也可以不写,但最先想的就应该是这个)

复杂问题上哨兵

宁愿判(node!=null))也不判(node.next!=null)。当然有时两者都要判

测试数据过不去,可以直接通过判断if来处理一些边界情况

在写的过程当中,如果一些边界(比如链表末尾问题)尽量不要特判,除非你很有把握特判效果很好

动态规划

首先复习一下背包问题就行。

首先一定是要写状态转移方程,然后看这个方程里涉及的下标是否可能越界,有越界的可能才可能需要扩充dp数组; 有时候dp数组的定义就是“第i个元素”这种,那i自然就是从1开始,进而需要扩充数组