此算法基础必须掌握,以下是个人JavaScript算法题积累,持久更新ing...
建议:新手入门可以配合看书籍:《算法图解》
indexOf() 内部也是一个循环,所以是三个for循环。
时间复杂度为 :T(n) = O(n^3)
let nums = [2, 7, 8, 6, 5, 3, 1, 11, 15]
let target = 9
function sum(arry, target) {
// 双重for循环遍历数组,进行判断后将符合的去和数组作indexOf() 找到对应的索引值
let arr = arry
for (let i = 0; i < arr.length; i++) {
let ele = arr[i]
for (let j = 1; j < arr.length; j++) {
let nele = arr[j]
if (ele + nele == target) {
console.log([arr.indexOf(ele), arr.indexOf(nele)])
arr[i], arr[j] = null
}
}
}
}
sum(nums, target)
此时的时间复杂度为:T(n) = O(n^2)
let nums = [2, 7, 8, 6, 5, 3, 1, 11, 15]
let target = 9
// 通过temp中间变量来接受,目标值-当前循环的值(差值)
// 在通过temp的值去和原数组判断是否相等
function funny(arry, target) {
let arr = arry
for (let i = 0; i < arr.length; i++) {
let temp = target - arr[i]
for (let j = 1; j < arr.length; j++) {
if (arr[j] === temp) {
arr[i], arr[j] = null
console.log([i, j])
}
}
}
}
funny(nums, target)
此时的性能最佳,时间复杂度为:T(n) = O(n)
/**
*
* @param {*传入的数组} arry
* @param {*目标值} target
*
* 此方法用的是哈希算法。
* 将arr数组变为了一个伪数组对象。键是元素,对应的值是索引
*
*/
function fun(arry, target) {
let arr = []
for (let i = 0; i < arry.length; i++) {
let temp = target - arry[i]
if (arr[temp] !== undefined) {
console.log([arr[temp], i])
} else {
arr[arry[i]] = i
}
}
}
// arry = [2, 7, 8, 6, 5, 3, 1, 11, 15]
// temp=7, 2=>0,
// temp=2, 7=>1
// temp=1, 8=>2
// temp=3, 6=>3
// temp=4, 5=>4
// ............
fun(nums, target)
给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: 1->2->3->4->5->NULL, k = 2
输出: 4->5->1->2->3->NULL
解释:
向右旋转 1 步: 5->1->2->3->4->NULL
向右旋转 2 步: 4->5->1->2->3->NULL
主要的思路就是找到旋转后的第一个结点,我们可以在遍历的过程中添加反向指针prev形成双向指针来方便我们获取结点,注意当k等于或超过列表长度时,我们要进行取余操作
链表中的点已经相连,一次旋转操作意味着:
新的链表头:在位置 n-k 处,其中 n 是链表中点的个数。
新的链表尾:新的链表尾就在头的前面,位于位置 n-k-1。
我们这里假设 k < n
如果 k >= n 怎么处理?
k 可以被写成 k = (k // n) * n + k % n 两者加和的形式,其中前面的部分不影响最终的结果,因此只需要考虑 k%n 的部分,这个值一定比 n 小。
找到旧的尾部并将其与链表头相连 old_tail.next = head,整个链表闭合成环,同时计算出链表的长度 n。
找到新的尾部,第 (n - k % n - 1) 个节点 ,新的链表头是第 (n - k % n) 个节点。
断开环 new_tail.next = None,并返回新的链表头 new_head。
var rotateRight = function(head, k) {
// 如果是 空链表或者只有一个元素的链表,则返回该链表
if(!head || !head.next) return head
var cur = head
// 从头部开始循环,获取链表长度。由于头部也是一个节点,所以 length 初始值为1
var length = 1;
while(cur.next) {
cur = cur.next
length++
}
// 获取实际要重复的次数
var num = k % length
// 链表闭环
cur.next = head
var new_list = head
// 找到新的尾部 new_tail : 走length - k % length - 1 步
// 找到新的头部 new_head : 走length - k % length 步
for(var i = 0;i < length - num - 1 ; i++){
new_tail = new_tail.next
}
var new_head = new_tail.next
new_tail.next = null
return new_head
};
var rotateRight = function(head, k) {
let len = 0;
let linkHead = head;
if (!head || k === 0) return head;
if (head.next == null) return head;
let prev = null;
while(head) {
len++;
head.prev = prev;
prev = head;
head = head.next;
}
let linkLast = prev;
k = k % len;
if (k === 0) return linkHead;
while(k > 1) {
prev = prev.prev;
k--;
}
linkLast.next = linkHead;
prev.prev.next = null;
return prev;
};