最近在看八股文。整理了一下思路,想深入了解还得多去写,无奈时间紧迫的情况下抛砖引玉也不失为下策:
1.Two Sum Easy
给出一个数组,找出其中两个和为目标值的坐标。
思路:
[1]排序。
和为目标值,一般的思路是先排序,然后取两点坐标分别从首尾向中间移动。若和为目标值则返回两点坐标。若和大于目标值,右端坐标值-1,反之左端坐标值+1;
[2]因为需要返回坐标值。需要对键值对进行按值排序。以保留原始坐标。
2.Add Two Numbers Medium
有两个反向存储数字的链表,求他们的和。
思路:
[1]这种需要求和,进位频繁的工作选取一个全局变量来存储临时的和。(比如两个数的个位分别是9和8,那么先不必考虑进位,这个全局变量的值就是17,运算完成后,和的个位值为 全局变量%10, 然后执行 全局变量 /= 10,得出全局变量的剩余值。在计算十位的时候要加上这个剩余值。)
[2]这道题主要还顺带考察了链表的用法。
[3]注意while循环自带逻辑判断。这两个链表的长度不一,所以循环结构可以这样写:
while(链表1当前节点不为空且链表2当前节点不为空) ;//两个链表都还有值
while(链表1当前节点不为空); //链表2已空
while(链表2当前节点不为空); //链表1已空
if(全局变量 > 0) //如果全局变量>0 说明有进位操作,还需要加长结果链表
3.Longest Substring Without Repeating Characters Medium
找出一个字符串的最长子串,这个字串满足的条件是不出现重复字符。
思路:
[1]一次循环就搞定,不要多次遍历字符串。
[2]怎样标志一个字符是否出现过。因为字符的数量是有限的,一般256个标志位就能标志基本ANSC码的所有字符。
[3]求最长、最大值的思路,是创建一个值用来保存这个“最大值”,每有可能是最大值的值产生的时候,让这个值和原有的最大值进行比较取二者的最大值作为新的最大值。
[4]解题思路。创建一个int类型的数组 charView[256],其中的每个值都初始化成-1。
创建变量 start(目前而言正在判断的字符串的开始坐标) maxlength(得知的最长字符串的长度)
从给出的字符串的第一个字符到最后一个字符逐个遍历。当前坐标为i start初始化为0
如果charView[str[i]] 的值小于0 说明该字符一次都没出现过,start值不变(即当前所计算的字符串还没出现重复字符,继续计算下去) maxlength = max(i-start, maxlength);然后将charView[str[i]]赋值为i
如果charView[str[i]] 的值大于0 说明该字符出现过。那么我就判断这个值是否在start值的左边(start > i),如果在则说明他对我们当前判断的字符串没有影响,我们不必改变start的值,正常maxlength = max(i-start, maxlength)计算,并将charView[str[i]]赋值为i
如果这个值在start值的右边(start < i),那么说明我们当前计算的字符串出现了重复(就是这个str[i]字符)。我们将start值赋值为i,然后继续去遍历。
最后返回maxlength。
4.Median of Two Sorted Arrays Hard
这题看似简单其实很恶啊,大意就是给出两个已经排序好的数组,找出两个数组所有元素中的中位数。
思路:
[1].设数组1的长度为m 数组2的长度为n总数就是m+n 我们就是要找两个数组中第m+n/2大的元素的值。我们设m+n/2为k
[2].如果a1[k/2-1]大于a2[k/2-1],那么a2[0]到a2[k/2-1]的所有值当中都不可能有中值。原因可以这么推倒。
[3]就算取a2[0]~a2[k/2-1]当中最大的值作为中值a2[k/2-1],那么需要从a1中取出k/2+1个数排在a2[k/2-1]的左边才能凑够k个数,让a2[k/2]成为两数组第k大的元素。然而a1中取出k/2个最小的元素当中已经有比a2[k/2-1]大的元素了,所以并不能凑齐k-1个比a2[k/2]小的数。
[4]上述是理想情况下(k/2-1既小于a1的长度也小于a2的长度)。如果不是,那么就用短的数组的长度代替这个值进行相同的判断。
[5]然后将删除不可能的元素的两个数组重新判断,这回要找的是第 k -(k/2-1)或这 k-短的那个数组长度 大的值。删除元素的数组的长度和首指针都进行更新。
findKth方法写的非常经典。更能看出这道题的解题思路:
1. 保持A是短的那一个数组,B是长的
2. 平分k, 一半在A,一半在B (如果A的长度不足K/2,那就pa就指到最后一个)
3. 如果pa的值 < pb的值,那证明第K个数肯定不会出现在pa之前,递归,把A数组pa之前的砍掉,同理递归砍B数组。
4. 递归到 m == 0 (短的数组用完了) 就返回 B[k - 1], 或者k == 1(找第一个数)就返回min(A第一个数,B第一个数)。
double findKth(int a[], int m , int b[], int n, int k) { if(m > n) return findKth(b,n,a,m,k); if(m == 0) return b[k-1]; if(k == 1) return min(a[0], b[0]); int pa = min(k/2, m), pb = k-pa; if(a[pa -1] < b[pb-1]) return findKth(a + pa, m - pa, b, n, k - pa); else if(a[pa - 1] > b[pb - a]) return findKth(a, m, b + pb, n - pb, k - pb); else return a[pa - 1]; return 0; } double findMid(int A[], int m, int B[], int n) { int total = m + n; if(total & 0x1) { return findKth(A,m,B,n, total/2+1); } else { return (findKth(A,m,B,n, total/2) + findKth(A,m,B,n, total/2 + 1)) / 2; } }
待更新
Longest Palindromic Substring Medium
ZigZag Conversion Easy
Reverse Integer Easy
String to Integer (atoi) Easy
Palindrome Number Easy
Regular Expression Matching Hard
Container With Most Water Medium
Integer to Roman Medium
Roman to Integer Easy
Longest Common Prefix Easy
3Sum Medium
3Sum Closest Medium
Letter Combinations of a Phone Number Medium
4Sum Medium
Remove Nth Node From End of List Easy
Valid Parentheses Esay