1.二进制中1的个数
题目:输入一个整数,输出该数32位二进制表示中1的个数。其中负数用补码表示。
思路:如果一个整数不为0,那么这个整数至少有一位是1。如果我们把这个整数减1,那么原来处在整数最右边的1就会变为0,原来在1后面的所有的0都会变成1(如果最右边的1后面还有0的话)。其余所有位将不会受到影响。
举例:
一个二进制数1100,从右边数起第三位是处于最右边的一个1。减去1后,第三位变成0,它后面的两位0变成了1,而前面的1保持不变,因此得到的结果是1011.我们发现减1的结果是把最右边的一个1开始的所有位都取反了。这个时候如果我们再把原来的整数和减去1之后的结果做与运算,从原来整数最右边一个1那一位开始所有位都会变成0。如1100&1011=1000.
也就是说,把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0.那么一个整数的二进制有多少个1,就可以进行多少次这样的操作。
function NumberOf1(n)
{
// write code here
var count = 0
while (n) {
count++
n = (n -1) & n
}
return count
}
补充:
例:求-5的补码。
- 5对应正数5(00000101)→所有位取反(11111010)→加1(11111011)
2.数值的整数次方
题目:给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
保证base和exponent不同时为0。不得使用库函数,同时不需要考虑大数问题,也不用考虑小数点后面0的位数。
思路:幂数相乘
function Power(base, exponent)
{
// write code here
if(exponent < 0) {
if (base == 0) {
return false
} else {
return 1/Power(base, -exponent)
}
}else if(exponent == 0) {
return 1
} else {
if (base == 0) {
return false
} else {
return Power(base, exponent-1) * base
}
}
}
3.调整数组顺序使奇数位于偶数前面
题目:
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变
思路:主要使用数组的两种方法,数组遍历方法forEach(),数组合并方法concat()
先循环遍历数组,判断奇偶,再分别放入数组,最后进行数组合并
function reOrderArray( array ) {
// write code here
var oddArr = []
var evenArr = []
array.forEach(function(item,index) {
if (item % 2 ==0) {
evenArr.push(item)
} else {
oddArr.push(item)
}
});
return oddArr.concat(evenArr)
}
4.链表中倒数第K个节点
题目:输入一个链表,输出一个链表,该输出链表包含原链表中从倒数第k个结点至尾节点的全部节点。
如果该链表长度小于k,请返回一个长度为 0 的链表
思路:先定义两个指针,先让第一个指针和第二个指针都指向头结点,然后再让第一个指正走(k-1)步,到达第k个节点。然后两个指针同时往后移动,当第一个指针到达末尾的时候,第二个指针所在位置就是倒数第k个节点了
function FindKthToTail( pHead , k ) {
// write code here
if(pHead == null || k <=0) {
return false
}
var p1 = pHead
var p2 = pHead
for(var i = 1; i < k; i++) {
if(!p1.next) {
return 0
}else {
p1 = p1.next
}
}
while(p1.next) {
p1 = p1.next
p2 = p2.next
}
return p2
}
5.反转链表
题目:输入一个链表,反转链表后,输出新链表的表头。
/*function ListNode(x){
this.val = x;
this.next = null;
}*/
function ReverseList(pHead)
{
// write code here
if(pHead == null) {
return false
}
var p1 = pHead
var p2 = null ,temp = null
while(p1) {
temp = p1.next
p1.next = p2
p2 = p1
p1 = temp
}
return p2
}
6.合并两个排序的链表
题目:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
思路:用递归思想,依次将两个链表的每个元素递归对比后实现
/*function ListNode(x){
this.val = x;
this.next = null;
}*/
function Merge(pHead1, pHead2)
{
// write code here
if(pHead1 == null) {
return pHead2
} else if(pHead2 == null) {
return pHead1
}
var p1 = pHead1, p2 = pHead2
var newHead = null
if(p1.val > p2.val) {
newHead = p2
newHead.next = Merge(p1,p2.next)
}else {
newHead = p1
newHead.next = Merge(p1.next,p2)
}
return newHead
}
7.二叉树的镜像
题目:操作给定的二叉树,将其变换为源二叉树的镜像。
思路:判断树是否为空,然后交换左右子树,最后递归交换左右子树
/*
* function TreeNode(x) {
* this.val = x;
* this.left = null;
* this.right = null;
* }
*/
function Mirror( pRoot ) {
// write code here
if(pRoot === null) {
return pRoot
}
var temp = null
temp = pRoot.left
pRoot.left = pRoot.right
pRoot.right = temp
Mirror(pRoot.left)
Mirror(pRoot.right)
return pRoot
}
8.包含min函数的栈
题目:定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数,并且调用 min函数、push函数 及 pop函数 的时间复杂度都是 O(1)
push(value):将value压入栈中
pop():弹出栈顶元素
top():获取栈顶元素
min():获取栈中最小元素
思路:JS中数组底层是基于栈实现,因此本题目可根据此属性直接实现,但是注意此题的空值判断
var stack = []
function push(node)
{
// write code here
stack.push(node)
}
function pop()
{
// write code here
return stack.length == 0? null :stack.pop()
}
function top()
{
// write code here
return stack.length == 0? null :stack[stack.length-1]
}
function min()
{
// write code here
return stack.length == 0? null :Math.min.apply(null,stack)
}
9.栈的压入、弹出序列
题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
思路:
借用一个辅助的栈,遍历压栈顺序,先讲第一个放入栈中,这里是1,然后判断栈顶元素是不是出栈顺序的第一个元素,这里是4,很显然1≠4,所以我们继续压栈,直到相等以后开始出栈,出栈一个元素,则将出栈顺序向后移动一位,直到不相等,这样循环等压栈顺序遍历完成,如果辅助栈还不为空,说明弹出序列不是该栈的弹出顺序。
举例:
入栈1,2,3,4,5
出栈4,5,3,2,1
首先1入辅助栈,此时栈顶1≠4,继续入栈2
此时栈顶2≠4,继续入栈3
此时栈顶3≠4,继续入栈4
此时栈顶4=4,出栈4,弹出序列向后一位,此时为5,,辅助栈里面是1,2,3
此时栈顶3≠5,继续入栈5
此时栈顶5=5,出栈5,弹出序列向后一位,此时为3,,辅助栈里面是1,2,3
….
依次执行,最后辅助栈为空。如果不为空说明弹出序列不是该栈的弹出顺序。
function IsPopOrder(pushV, popV)
{
// write code here
var arr = []
for (var i = 0; i < pushV.length; i++) {
arr.push(pushV[i])
while(arr.length > 0) {
if(arr[arr.length-1] == popV[0]) {
arr.pop()
popV.shift()
} else {
break
}
}
}
return arr.length == 0
}
10.
二叉搜索树与双向链表
题目: