1.两个链表相加
总的来说类似于数学运算,思路就是依次将链表的值取出,然后进行按位相加,必须的变量有一个进位,最后返回链表时需要一个节点,运算方法除了相加还需要进行取模取余,最后由于计算是从低位到高位,所以还需要取节点时进行头部插入。
代码如下。但使用特别特别长的链表时,有时会报超时,需继续优化(TODO)
1 // 假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。 2 // 给定两个这种链表,请生成代表两个整数相加值的结果链表。 3 // 例如:链表 1 为 9->3->7,链表 2 为 6->3,最后生成新的结果链表为 1->0->0->0。 4 5 // 超时——TODO 6 /* 7 * function ListNode(x){ 8 * this.val = x; 9 * this.next = null; 10 * } 11 */ 12 13 /** 14 * 15 * @param head1 ListNode类 16 * @param head2 ListNode类 17 * @return ListNode类 18 */ 19 function addInList( head1 , head2 ) { 20 var arr1 = [], 21 arr2 = [], 22 // sumArr = [], 23 sum = 0, 24 deg = 0, 25 len = 0 26 while(head1 != null || head2 != null) { 27 if (head1 != null) { 28 arr1.unshift(head1.val) 29 head1 = head1.next 30 } 31 if (head2 != null) { 32 arr2.unshift(head2.val) 33 head2 = head2.next 34 } 35 len++ 36 } 37 var p,p1=null 38 for (var i=0;i<len;i++) { 39 var _sum = (+(arr1[i]||0))+(+(arr2[i]||0))+deg 40 // sumArr.push(_sum%10) 41 deg = Math.floor(_sum/10) 42 p=new ListNode(_sum%10) 43 p.next = p1 44 p1 = p 45 } 46 if (deg > 0) { 47 // sumArr.push(deg) 48 p=new ListNode(deg) 49 p.next = p1 50 } 51 // for (var j=0;j<sumArr.length;j++) { 52 // p=new ListNode(sumArr[j]) 53 // p.next = p1 54 // p1 = p 55 // } 56 return p 57 } 58 module.exports = { 59 addInList : addInList 60 };
2.用2个栈实现队列
栈,先进后出,尾部进,尾部出,队列,先进先出,尾部进,头部出。
思路就是进的时候直接进,出的时候先判断一个栈是否空,空的话则全部将另一个栈入栈,非空则直接弹出顶部元素。题目多少比较混淆人。
1 // 用两个栈来实现一个队列,分别完成在队列尾部插入整数(push)和在队列头部删除整数(pop)的功能。 队列中的元素为int类型。保证操作合法,即保证pop操作时队列内已有元素。 2 3 // 示例: 4 // 输入: 5 // ["PSH1","PSH2","POP","POP"] 6 // 返回: 7 // 1,2 8 // 解析: 9 // "PSH1":代表将1插入队列尾部 10 // "PSH2":代表将2插入队列尾部 11 // "POP“:代表删除一个元素,先进先出=>返回1 12 // "POP“:代表删除一个元素,先进先出=>返回2 13 14 var _quene1 = [] 15 var _quene2 = [] 16 function push(node) 17 { 18 _quene1.push(node) 19 } 20 function pop() 21 { 22 if (_quene2.length == 0) { 23 while(_quene1.length > 0) { 24 _quene2.push(_quene1.pop()) 25 } 26 } 27 return _quene2.pop() 28 } 29 module.exports = { 30 push : push, 31 pop : pop 32 };
3.翻转链表
思路很简单,就是简单的遍历然后翻转指针。
实际操作,首先是进行循环原链表,然后需要一个当前指针变量,还需要一个next节点变量,需要进行到下个节点时,将当前节点变成上个节点,因而一共需要3个变量。循环条件就是节点不为null。需要注意的是操作顺序是严格一步步进行的,因为如果顺序不对,节点会相互缠绕。而最后返回的,则是最后一个节点。而我们循环终止时,最后一个是null,因而再往前的一个节点就是我们要返回的变量。
1 /*function ListNode(x){ 2 this.val = x; 3 this.next = null; 4 }*/ 5 function ReverseList(pHead) 6 { 7 let cur = pHead 8 let pre = null 9 while (cur != null) { 10 let cnext = cur.next 11 cur.next = pre 12 pre = cur 13 cur = cnext 14 } 15 return pre 16 }
4.解析url参数
url的格式:协议://域名(:端口)/url路径?参数1=值1&参数2=值2#锚点id
相应的参数截取方法,则是先以?分割,再以#分割,来截取中间部分,再以&切割开不同键值对,最后以=区分键值。
1 function getUrlParam(sUrl, sKey) { 2 const urlMap = {} 3 try { 4 let urlMapAr = sUrl.split("?")[1].split("#")[0].split("&") 5 urlMapAr.forEach(e => { 6 let er = e.split("=") 7 if (urlMap[er[0]] === undefined) { 8 urlMap[er[0]] = er[1] 9 } else { 10 if (Array.isArray(urlMap[er[0]])) { 11 urlMap[er[0]].push(er[1]) 12 } else { 13 urlMap[er[0]] = [urlMap[er[0]], er[1]] 14 } 15 } 16 }) 17 } catch(e) {} 18 return sKey ? (urlMap[sKey] || "") : urlMap 19 }
5.青蛙跳(斐波那契数列-递归)
问题抽象为,一次只能加1或者2,要实现和为n,有多少种方法。
n为1时,只有1,n为2时,有2和1,1......。思路的关键点是,要想到达n,则先要到达n-1时最后一步是1,或者到达n-2最后一步是2(是1+1的和n-1重复),因而使用反向递归的方法可以解决。但是其实斐波那契数列在参数稍微大一点时就进行了大量的递归,效率方面有严重不足(10g内存到32就无法计算了),可以考虑使用其他方法解决。(时间复杂度On方和On的关系)
1 // 一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。 2 function jumpFloor(number) {// On^2,递归 3 if (number > 2) { 4 return jumpFloor(number - 1) + jumpFloor(number - 2) 5 } else { 6 return number 7 } 8 } 9 10 function jumpFloor(num) {// On,for循环 11 if (num > 2) { 12 var num1 = 1; 13 var num2 = 1; 14 for (var i = 2; i < num; i++) { 15 num2 = num1 + num2; 16 num1 = num2 - num1; 17 } 18 return num1 + num2; 19 // 可以使用解构赋值简化 20 // [n1, n2] = [n2, n1 + n2] 21 // return n2// 确认没问题吧TODO 22 } else { 23 return num 24 } 25 } 26 27 const fb4 = function(){// 闭包(差了1——TODO),去除重复计算的递归 28 var mem = [0,1]; 29 var f = function(n){ 30 var res = mem[n]; 31 if(typeof res !== ‘number‘){ 32 mem[n] = f(n-1) + f(n-2); 33 res = mem[n]; 34 } 35 return res; 36 } 37 return f; 38 }(); 39 40 // 惰性序列??TODO 41 42 // class Matrix 43 // { 44 // public: 45 // int n; 46 // int **m; 47 // Matrix(int num) 48 // { 49 // m=new int*[num]; 50 // for (int i=0; i<num; i++) { 51 // m[i]=new int[num]; 52 // } 53 // n=num; 54 // clear(); 55 // } 56 // void clear() 57 // { 58 // for (int i=0; i<n; ++i) { 59 // for (int j=0; j<n; ++j) { 60 // m[i][j]=0; 61 // } 62 // } 63 // } 64 // void unit() 65 // { 66 // clear(); 67 // for (int i=0; i<n; ++i) { 68 // m[i][i]=1; 69 // } 70 // } 71 // Matrix operator=(const Matrix mtx) 72 // { 73 // Matrix(mtx.n); 74 // for (int i=0; i<mtx.n; ++i) { 75 // for (int j=0; j<mtx.n; ++j) { 76 // m[i][j]=mtx.m[i][j]; 77 // } 78 // } 79 // return *this; 80 // } 81 // Matrix operator*(const Matrix &mtx) 82 // { 83 // Matrix result(mtx.n); 84 // result.clear(); 85 // for (int i=0; i<mtx.n; ++i) { 86 // for (int j=0; j<mtx.n; ++j) { 87 // for (int k=0; k<mtx.n; ++k) { 88 // result.m[i][j]+=m[i][k]*mtx.m[k][j]; 89 // } 90 // } 91 // } 92 // return result; 93 // } 94 // }; 95 // int main(int argc, const char * argv[]) { 96 // unsigned int num=2; 97 // Matrix first(num); 98 // first.m[0][0]=1; 99 // first.m[0][1]=1; 100 // first.m[1][0]=1; 101 // first.m[1][1]=0; 102 // int t; 103 // cin>>t; 104 // Matrix result(num); 105 // result.unit(); 106 // int n=t-2; 107 // while (n) { 108 // if (n%2) { 109 // result=result*first; 110 // } 111 // first=first*first; 112 // n=n/2; 113 // } 114 // cout<<(result.m[0][0]+result.m[0][1])<<endl; 115 // return 0; 116 // } 117 // TODO——改成js 118 119 module.exports = { 120 jumpFloor: jumpFloor 121 };