文章目录
13、调整数组顺序
题目描述:
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
思路一
定义两个数组,array1存奇数,array2存偶数,用数组forEach的循环迭代方法,判断奇偶分别存入,这里判断奇数偶数用了按位与的方法。
代码
function reOrderArray(array)
{
var array1 = [];
var array2 = [];
//forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。
//item当前元素、index当前元素的索引值、array当前元素所属的数组对象
array.forEach(function(item,index,array){
item & 1 ? array1.push(item):array2.push(item);
//位与运算 判断奇偶
//三相运算符
});
//concat() 方法用于连接两个或多个数组。
return array1.concat(array2);
}
思路二
通过map函数,判断每个数组元素是否为偶数
代码
function reOrderArray(array)
{
// write code here
var arr1=[],arr2=[];
/* map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
map() 方法按照原始数组元素顺序依次处理元素。
注意: map() 不会对空数组进行检测。
注意: map() 不会改变原始数组。 */
array.map(function(a){
//a是当前元素
a%2==0?arr2.push(a):arr1.push(a);
})
return arr1.concat(arr2);
}
14、链表中倒数第k个结点
题目描述
输入一个链表,输出该链表中倒数第k个结点。
思路一
确定链表k前k后的长度。
代码
/*function ListNode(x){
this.val = x;
this.next = null;
}*/
function FindKthToTail(head, k)
{
if(head == null || k <= 0) return null;
var init = head;
var count = 0;
while(head != null){
head = head.next; //链表的取后一位
count++; //链表总长度
}
var rek = count - k; //k后的长度
if(rek < 0) return null;
for(var i = 0 ; i < rek ; i++){
init = init.next;
}
return init;
}
思路二
通过prev和tail来获取距离为k的一段,然后就tail指向链表最后
代码
function FindKthToTail(head, k)
{
// write code here
if(head==null||k<=0) return null;
var prev = head;
var tail = head;
for(var index=0;index<k-1;index++){
if(tail.next!=null){
tail=tail.next;
}else{
return null;
}
}
//保持k的距离
while(tail.next!=null){
prev=prev.next;
tail=tail.next;
}
return prev;
}
15、反转链表
题目描述
输入一个链表,反转链表后,输出链表的所有元素。
思路
通过prev固定反转后链表头,通过head来反转,通过next指向剩下的链表头部。
代码
function ReverseList(pHead)
{
//链表
if(pHead == null || pHead.next == null) return pHead;
var prev = null;
var next = null;
while(pHead != null){
//存储一下头
next = pHead.next;
//断开连接 将最开始的头覆个空指针
pHead.next = prev;
//依次后移 pre pHead next
prev = pHead;
pHead = next;
}
return prev;
}
16、合并两个排序的链表
题目描述
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
思路一
非递归方法,不消耗内存,两个指针分别指向链表元素,然后比较两个元素大小,小的则连到合成后链表,直到达到一个链表的末尾。然后如果哪一个链表还有元素,直接连到合成后链表后面即可。过程中head一直是那个head,但是head表示的位置却不是刚开始的head了,但是因为构造函数出来的对象是引用类型,pHead还是那个head,表示的位置也还是那个位置。(此处重在理解)
两个指针分别指向链表元素,然后比较两个元素大小,小的则连到合成后链表,直到达到一个链表的末尾。然后如果哪一个链表还有元素,直接连到合成后链表后面即可。
代码
/*function ListNode(x){
this.val = x;
this.next = null;
}*/
function Merge(pHead1, pHead2)
{
function ListNode(x){
this.val = x;
this.next = null;
}
var head = new ListNode(0);
var pHead = head;
while(pHead1 != null && pHead2 != null){
if(pHead1.val >= pHead2.val){
head.next = pHead2;
pHead2 = pHead2.next;
}else{
head.next = pHead1;
pHead1 = pHead1.next;
}
head = head.next;
}
if(pHead1 != null){
head.next = pHead1;
}
if(pHead2 != null){
head.next = pHead2;
}
return pHead.next;
}
思路二
递归方法,消耗内存,使用自身进行比较合并。比思路1好理解有没有!
代码
function Merge(pHead1, pHead2)
{
if(pHead1 == null) return pHead2;
if(pHead2 == null) return pHead1;
var node = null;
if(pHead1.val > pHead2.val){
node = pHead2;
node.next = Merge(pHead1,pHead2.next);
}else{
node = pHead1;
node.next = Merge(pHead1.next,pHead2);
}
return node;
}
17、树的子结构
题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
思路
比较B是不是A的子树,B是不是A的右子树的子树,B是不是A的左子树的子树。如果根元素相同,则开始判断左子树和右子树。
代码
/* function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
} */
function isSubtree(pRoot1,pRoot2){
if(pRoot2 == null) return true; //pRoot2为null,表示子树已经遍历完
if(pRoot1 == null) return false;
if(pRoot1.val == pRoot2.val){
return isSubtree(pRoot1.left,pRoot2.left) && isSubtree(pRoot1.right,pRoot2.right)
}else{
return false;
}
}
function HasSubtree(pRoot1, pRoot2)
{
if(pRoot1 == null || pRoot2 == null){
return false;
}
return isSubtree(pRoot1,pRoot2) || HasSubtree(pRoot1.left, pRoot2) || HasSubtree(pRoot1.right, pRoot2);
}
18、二叉树镜像
题目描述
操作给定的二叉树,将其变换为源二叉树的镜像。
思路
先将根的左右节点互换,然后就是递归调用,对左右子树进行分别处理
代码
/* function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
} */
function Mirror(root)
{
// write code here
if(root==null) return null;
//首先先将左右节点互换
var tmp = root.left;
root.left=root.right;
root.right=tmp;
//递归
Mirror(root.left);
Mirror(root.right);
}