ARTS Week 11

Algorithm

本周的 LeetCode 题目为 15. 三数之和

题目简介:给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]

题目思路:先将数组从小到大进行排序,前两个数 first,second 可以从左端开始,第三个数 k,可以从后向前进行遍历,当 third == second 或者 nums[first] + nums[second] + nums[third] < 0 时,就说明需要遍历下一个 second,third 再次从尾部开始遍历。同时,因为题目解答里不能包含重复的三元组,因此在遍历 first, second 时可以检查其是否与前一个数是否相同(因为已经排好序),若相同,则直接使用 continue 跳过。

最终代码

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> ans = new ArrayList<>();
        int length = nums.length;
        for (int first = 0; first < length - 1; first++) {
            if (first > 0 && nums[first] == nums[first-1]) {
                continue;
            }
            for (int second = first + 1; second < length; second++) {
                if (second > first + 1 && nums[second] == nums[second-1]) {
                    continue;
                }
                int third = length - 1;
                while (second < third && nums[first] + nums[second] + nums[third] > 0) {
                    third--;
                }
                if (second == third) {
                    break;
                }
                if (nums[first] + nums[second] + nums[third] == 0) {
                    List<Integer> tmp = new ArrayList<>();
                    tmp.add(nums[first]);
                    tmp.add(nums[second]);
                    tmp.add(nums[third]);
                    ans.add(tmp);
                }
            }
        }
        return ans;
    }
}

Review

本周 Review 的英文文章为:在 C 语言中,你如何知道动态分配是否成功?

在 C 语言中,我们经常使用 malloc() 函数来在堆上分配空间,但实际上,malloc() 函数分配的是虚拟内存,只有当发生真正读写内存时,才会通过缺页中断分配物理内存,例如下面的测试程序:

#include <stdio.h>
#include <stdlib.h>

int main() {
  size_t large = 1099511627776;
  char *buffer = (char *)malloc(large);
  if (buffer == NULL) {
    printf("error!\n");
    return EXIT_FAILURE;
  }
  printf("Memory allocated\n");
  for (size_t i = 0; i < large; i += 4096) {
    buffer[i] = 0;
  }
  free(buffer);
  return EXIT_SUCCESS;
}

运行该程序,也许你会发现打印出了 Memory allocated,代表内存成功分配。但也有可能,你会看到 error! ,内存并未分配成功,这是因为当程序试图分配远远大于物理内存的虚拟内存时(这种情况称为 overcommit),其是否分配成功取决于操作系统。

在 Linux 中,应对 overcommit,有三种处理方式,启发式的(默认)、总是允许、绝不允许这三种方式,具体的介绍可以参考 https://www.kernel.org/doc/Documentation/vm/overcommit-accounting

Tip

Java 中 ArrayListVector 的区别,主要是以下俩点:

  1. Vector 是线程安全的,ArrayList 不是线程安全的
  2. ArrayList 在底层数组不够用时在原来的基础上扩展0.5倍,Vector 是扩展1倍

Share

本周参加了一场面试,发现其中还是会比较涉及到多线程的有关问题,但自己在这方面比较缺少经验,未来还需要去系统性的学一下多线程编程。

posted @ 2021-11-07 10:37  永远是萌新的阿岩  阅读(27)  评论(0编辑  收藏  举报