1.删除重复节点
编写代码,移除未排序链表中的重复节点。保留最开始出现的节点。
示例1:
输入:[1, 2, 3, 3, 2, 1]
输出:[1, 2, 3]
示例2:
输入:[1, 1, 1, 1, 2]
输出:[1, 2]
提示:
链表长度在[0, 20000]范围内。
链表元素在[0, 20000]范围内。
IPO过程
I :输入一个链表
P:移除重复节点,保留最开始的节点
思路:采用双指针的做法,里层循环为将头指针固定,后续指针在移动,移动过程中如果出现与头指针的值相同的节点,删除该结点,否则继续移动指针。外层循环是头指针在移动
O:输出一个没有重复结点的链表
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var removeDuplicateNodes = function(head) {
//p为头指针
let p=head
while(p){
//q为内层循环移动的指针,这里不采用从p的next开始,是为了后续考虑
let q=p
while(q.next){
if(q.next.val==p.val){
q.next=q.next.next
}else{
q=q.next
}
}
//外层移动
p=p.next;
}
return head
}
2.最长回文子串
题目描述
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
示例 2:
输入: “cbbd”
输出: “bb”
思路
这是一道最长回文的题目,要我们求出给定字符串的最大回文子串。
解决这类问题的核心思想就是两个字“延伸”,具体来说
如果一个字符串是回文串,那么在它左右分别加上一个相同的字符,那么它一定还是一个回文串
如果在一个不是回文字符串的字符串两端添加任何字符,或者在回文串左右分别加不同的字符,得到的一定不是回文串
事实上,上面的分析已经建立了大问题和小问题之间的关联,基于此,我们可以建立动态规划模型。
我们可以用 dp[i][j] 表示 s 中从 i 到 j(包括 i 和 j)是否可以形成回文,状态转移方程只是将上面的描述转化为代码即可:
if (s[i] === s[j] && dp[i + 1][j - 1]) {
dp[i][j] = true;
}
base case就是一个字符(轴对称点是本身),或者两个字符(轴对称点是介于两者之间的虚拟点)。
关键点
”延伸“(extend)
从中我们可以看出当只有一个字符的时候,dp[i][j]=true
;当有两个字符的时候,dp[i][j]=true
的情况只有是当两个字符相同的情况;当有三个以上,那么dp[i[j]为true的情况是中间的s[i] === s[j] &&dp[i + 1][j - 1]
;
以上的IPO过程是:
I:输入一个待验证的字符串
P:判断最大的回文字符串(只需要找出一个)
(1)由于dp[i][j]的结果是依赖于dp[i+1][j-1],因此我们从后往前找,用i表示开始位置,j表示结束位置
(2)从i = s.length - 1开始,循环一次之后i- -;j从i开始,j++
分为以下三种情况
1. 当只有一个字符的时候,`dp[i][j]=true`;
2. 当有两个字符的时候,`dp[i][j]=true`的情况只有是当**两个字符相同**的情况;
3. 当有三个以上,那么dp[i[j]为true的情况是中间的`s[i] === s[j] &&dp[i + 1][j - 1]`;
定义一个res,当dp[i][j] && j - i + 1 > res.length的时候,说明有新的更长的字符串出现,这个时候我们只需要更新res即可
O:输出最大的回文字符串
/**
* @param {string} s
* @return {string}
*/
var longestPalindrome = function(s) {
// babad
// tag : dp
if (!s || s.length === 0) return "";
let res = s[0];
const dp = [];
// 倒着遍历简化操作, 这么做的原因是dp[i][..]依赖于dp[i + 1][..]
for (let i = s.length - 1; i >= 0; i--) {
dp[i] = [];
for (let j = i; j < s.length; j++) {
if (j - i === 0) dp[i][j] = true;
// specail case 1
else if (j - i === 1 && s[i] === s[j]) dp[i][j] = true;
// specail case 2
else if (s[i] === s[j] && dp[i + 1][j - 1]) {
// state transition
dp[i][j] = true;
}
if (dp[i][j] && j - i + 1 > res.length) {
// update res
res = s.slice(i, j + 1);
}
}
}
return res;
};
图解来源作者:fe-lucifer
链接:https://leetcode-cn.com/problems/longest-palindromic-substring/solution/hui-wen-wen-ti-dong-tai-gui-hua-jspython5-zui-chan/