1.LC题
1.1每日一题——统计元音字母序列的数目
以上定义等价于:
元音‘a’前面只能跟’e’,‘u’,‘i’
元音‘e’前面只能跟’a’,‘i’
元音’i’前面可以跟’e’,‘o’
元音’o’前面可以跟’i’
元音’u’前面可以跟’o’,‘i’
动态规划,设一个二维数组d[i][j]。i代表目前是第几位;j=0,1,2,3,4,分别代表这一位为a,e,i,o,u。
递推公式:
class Solution {
public int countVowelPermutation(int n) {
long mod = 1000000007;
long[] dp = new long[5];
long[] ndp = new long[5];
for (int i = 0; i < 5; ++i) {
dp[i] = 1;
}
for(int i=2;i<=n;i++){
ndp[0]=(dp[1]+dp[2]+dp[4])%mod;
ndp[1]=(dp[0]+dp[2])%mod;
ndp[2]=(dp[1]+dp[3])%mod;
ndp[3]=(dp[2])%mod;
ndp[4]=(dp[2]+dp[3])%mod;
System.arraycopy(ndp,0,dp,0,5);
}
long ans=0;
for(int i=0;i<5;i++){
ans=(ans+dp[i])%mod;
}
return (int)ans;
}
}
System.arraycopy数组复制
1.2 两数相加
新定义两个节点,一个head作为头节点,指向l3原始地址, l3不断运动增加,最后输出head即可。
用carry判断是否进位,l1,l2,carry不为零即增加l3节点,节点的值由l1,l2的三目表达式以及上一位的进位相加而来。
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int carry=0;
ListNode l3=new ListNode(-1);
ListNode head=l3;
while(l1!=null||l2!=null||carry!=0){
int newVal=((l2==null?0:l2.val)+(l1==null?0:l1.val)+carry)%10;
carry=((l1==null?0:l1.val)+(l2==null?0:l2.val)+carry)/10;
l3.next = new ListNode(newVal);
l3=l3.next;
l1 = l1 == null? null: l1.next;
l2 = l2 == null? null: l2.next;
}
return head.next;
}
}
1.3无重复字符的最长字串
class Solution {
public int lengthOfLongestSubstring(String s) {
// 哈希集合,记录每个字符是否出现过
Set<Character> occ = new HashSet<Character>();
int n = s.length();
// 右指针,初始值为 -1,相当于我们在字符串的左边界的左侧,还没有开始移动
int rk = -1, ans = 0;
for (int i = 0; i < n; ++i) {
if (i != 0) {
// 左指针向右移动一格,移除一个字符
occ.remove(s.charAt(i - 1));
}
while (rk + 1 < n && !occ.contains(s.charAt(rk + 1))) {
// 不断地移动右指针
occ.add(s.charAt(rk + 1));
++rk;
}
// 第 i 到 rk 个字符是一个极长的无重复字符子串
ans = Math.max(ans, rk - i + 1);
}
return ans;
}
}