6月29日算法日记

96 阅读1分钟

1.寻找数组的中心下标

image-20220629203306779

解法

1.前缀和

思路

  1. 首先求和整个数组total=nums.reduce((a, b) => a + b, 0);
  2. 将中心下标左侧和记为sum,那么右侧的和就为total - sum - nums[i]
  3. 只要sum == total - sum - nums[i],即可返回下标i,否则就返回-1
  4. 因为数组是从前往后遍历的,因此不需要考虑存在多个中心下标时返回左侧那一个,因为即使有多个中心下标,也会先返回左侧的下标并结束函数了
var pivotIndex = function(nums) {
    let n = nums.length
    //数组综合记为total
    const total = nums.reduce((a, b) => a + b, 0);
    //左侧和记为sum
    let sum = 0
    //右侧和为 
    for(let i = 0; i < n; i++) {
        //左侧等于右侧
        if(sum == total - sum - nums[i]) return i
        sum += nums[i]
    }
    return -1
};

2.两数相加

image-20220629232836469

解法

1.常规解法

思路

  1. 首先通过while循环遍历两个链表,记录链表l1当前结点的val1值和链表l2当前结点的val2值;如果结点存在则使用结点的val值,否则值就为0
  2. 使用数组args记录每一次val1+val2的值,之后通过判断当前结点是否存在进而将下一结点赋予当前结点cur1 && (cur1 = cur1.next)
  3. 然后考虑进位的问题,当数组当前项args[i]>9,那么args[i+1]需要进1,需要判断args[i+1]是否不存在,如果不存在则直接将args[i+1]赋值为1,否则就自增
  4. 最后把数组转换为链表,这里需要用到递归的方式,定义链表的头结点为数组的第一项,然后删除第一项,然后递归公式为nodeStart.next = createList(argu),每次递归时就会删除当前数组的第一项,因为shift方法是会改变当前数组的。最终返回转换完成的链表即可
var addTwoNumbers = function(l1, l2) {
    let cur1 = l1, cur2 = l2, args = []
    while(cur1 || cur2) {
        let val1 = cur1 ? cur1.val : 0
        let val2 = cur2 ? cur2.val : 0
        let temp = val1 + val2
        args.push(temp)
        //链表1和链表2长度可能不等,所以每次需要判断当前结点是否存在才能进行赋值
        cur1 && (cur1 = cur1.next)
        cur2 && (cur2 = cur2.next)
    }
    // 考虑进位的问题
    for (let i = 0; i < args.length; i++) {
        if(args[i] > 9) {
            args[i] -= 10
            if (args[i+1] === undefined) {
                args[i+1] = 1
            } else {
                args[i+1] += 1
            }
        }
    }
    // 把数组转成链表(递归)
    function createList (argu) {
         if (argu.length > 0) {
                var nodeStart = new ListNode(argu[0])
                argu.shift()
                nodeStart.next = createList(argu)
                return nodeStart
            } else {
                return null
            }
    }
    
    return createList(args)
};