LeetCode - Algorithms - 171. Excel Sheet Column Number

这题算Easy,Excel列编号好像可以理解成26进制,少不了查下JDK API Specification,查看JavaScript Bible

Java

1
2
3
4
5
6
7
8
9
10
class Solution {
public int titleToNumber(String s) {
int n = 0;
int len = s.length();
for(int i=s.length()-1;i>=0;i--) {
n += (Character.getNumericValue(s.charAt(i))-9)*Math.pow(26, len-i-1);
}
return n;
}
}

Submission Detail

  • 1000 / 1000 test cases passed.
  • Your runtime beats 5.55 % of java submissions.

JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
/**
* @param {string} s
* @return {number}
*/
var titleToNumber = function(s) {
var n = 0;
var len = s.length;
for(var i=s.length-1;i>=0;i--) {
n+=(s.charCodeAt(i)-64)*Math.pow(26,len-i-1);
}
return n;
};

Submission Detail

  • 1000 / 1000 test cases passed.
  • Your runtime beats 99.02 % of javascript submissions.

LeetCode - Algorithms - 371. Sum of Two Integers

这题不Easy呀,像智力题,像脑筋急转弯。
代码是人家的,我可想不出来。真是“会者不难,难者不会”。

JavaScript

自增自减运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* @param {number} a
* @param {number} b
* @return {number}
*/
var getSum = function(a, b) {
if (a>0) {
while(a>0) {
a--;
b++
}
}
if (a<0) {
while(a<0) {
a++;
b--;
}
}
return b;
};

Submission Detail

  • 13 / 13 test cases passed.
  • Your runtime beats 3.38 % of javascript submissions.

位运算+递归

1
2
3
4
5
6
7
8
9
10
11
12
/**
* @param {number} a
* @param {number} b
* @return {number}
*/
var getSum = function(a, b) {
var sum,carry;
if (b==0) return a;
sum = a^b;
carry = (a&b)<<1;
return getSum(sum,carry);
};

Submission Detail

  • 13 / 13 test cases passed.
  • Your runtime beats 69.57 % of javascript submissions

消除递归的位运算

知其然而不知其所以然,居然可以这么做,觉得很神奇

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* @param {number} a
* @param {number} b
* @return {number}
*/
var getSum = function(a, b) {
while(b!=0) {
var carry=a&b;
a = a^b;
b = carry<<1;
}
return a;
};

Submission Detail

  • 13 / 13 test cases passed.
  • Your runtime beats 100.00 % of javascript submissions.

Java

消除递归的位运算

1
2
3
4
5
6
7
8
9
10
class Solution {
public int getSum(int a, int b) {
while (b!=0) {
int carry = a&b;
a = a^b;
b = carry<<1;
}
return a;
}
}

Submission Detail

  • 13 / 13 test cases passed.
  • Your runtime beats 100.00 % of java submissions.

递归+位运算

1
2
3
4
5
6
7
8
9
class Solution {
public int getSum(int a, int b) {
int sum,carry;
if (b==0) return a;
sum = a ^ b;
carry = (a & b) << 1;
return getSum(sum,carry);
}
}

Submission Detail

  • 13 / 13 test cases passed.
  • Your runtime beats 100.00 % of java submissions.

自增自减运算符

这个解很像脑筋急转弯,不难,但让人想不到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public int getSum(int a, int b) {
if (a>0) {
while(a>0) {
a--;
b++;
}
}
if (a<0) {
while(a<0) {
a++;
b--;
}
}
return b;
}
}

Submission Detail

  • 13 / 13 test cases passed.
  • Your runtime beats 3.44 % of java submissions.

LeetCode - Algorithms - 204. Count Primes

虽然Difficulty标为Easy,但对自己来说不算简单呀,犯了各种错误。

参考网上的各种代码,才终于跑通了。 算法其实就是经典的 Sieve of Eratosthenes,复杂度 O(NloglogN)

ref

Java

1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public int countPrimes(int n) {
if (n<=2) return 0;
int x = 0;
int sqrt = (int) Math.sqrt(n);
boolean[] b = new boolean[n];
b[0]=b[1]=false;
for(int i=2;i<n;i++)
b[i]=true;
for(int i=2;i<=sqrt;i++) {
if (b[i]) {
for(int j=i*i;j<n;j+=i) {
b[j]=false;
}
}
}
for(int i=0;i<b.length;i++) {
if (b[i])
x++;
}
return x;
}
}

Submission Detail

  • 20 / 20 test cases passed.
  • Your runtime beats 42.53 % of java submissions.

2

这道题好像可以拿来作为范例学习Java 8 Streams:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.BitSet;
import java.util.IntSummaryStatistics;
import java.util.stream.IntStream;

class Solution {
public int countPrimes(int n) {
final BitSet sieve = new BitSet(n);
final IntSummaryStatistics stats = IntStream.rangeClosed(2, n-1)
.filter(x -> !sieve.get(x))
.peek(x -> {
if (x*x < n)
for(int i = x; i < n; i+=x)
sieve.set(i);
})
.summaryStatistics();
return new Long(stats.getCount()).intValue();
}
}

Submission Detail

  • 20 / 20 test cases passed.
  • Your runtime beats 14.45 % of java submissions.

代码更精炼了,但性能变差了

3 bottom-up approach

solution of Leetcode 204. Count Primes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
public int countPrimes(int n) {
boolean notPrime[] = new boolean[n];
int count = 0;
for (int i = 2; i < n; i++) {
if (!notPrime[i]) {
count++;
for (int j = 2; i * j < n; j++) {
notPrime[i * j] = true;
}
}
}
return count;
}
}

Submission Detail

  • 20 / 20 test cases passed.
  • Runtime: 13 ms, faster than 77.25% of Java online submissions for Count Primes.
  • Memory Usage: 38.3 MB, less than 5.66% of Java online submissions for Count Primes.

JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* @param {number} n
* @return {number}
*/
var countPrimes = function(n) {
if (n<=2) return 0;
var sqrt = Math.floor(Math.sqrt(n));
var b = new Array(n);
b[0]=false;
b[1]=false;
for(var i=2;i<n;i++) b[i]=true;
for(var i=2;i<=sqrt;i++) {
if (b[i]) {
for(var j=i*i;j<n;j+=i) {
b[j]=false;
}
}
}
var x=0;
for(var i=0;i<n;i++) {
if (b[i]) x++;
}
return x;
};

Submission Detail

  • 20 / 20 test cases passed.
  • Your runtime beats 97.46 % of javascript submissions.

Java 8 用法

ref

Java 8 新特性概述
https://www.ibm.com/developerworks/cn/java/j-lo-jdk8newfeature/index.html

Java 8 被动迭代式特性介绍
https://www.ibm.com/developerworks/cn/java/j-lo-java8-iterator/index.html

使用 Java 8 作为 Java 下一代语言
评估 Java 8 是否适合代替 Java
https://www.ibm.com/developerworks/cn/java/j-jn15/index.html

Java 8 中的 Streams API 详解
Streams 的背景,以及 Java 8 中的使用详解
https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/index.html

Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。Stream API 借助于同样新出现的 Lambda 表达式,极大的提高编程效率和程序可读性。同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用 fork/join 并行方式来拆分任务和加速处理过程。通常编写并行代码很难而且容易出错, 但使用 Stream API 无需编写一行多线程的代码,就可以很方便地写出高性能的并发程序。所以说,Java 8 中首次出现的 java.util.stream 是一个函数式语言+多核时代综合影响的产物。

The Java 8 Stream API Tutorial
https://www.baeldung.com/java-8-streams

Java 8 Stream Tutorial
https://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/

Lambdas and Streams in Java 8 Libraries
http://www.drdobbs.com/jvm/lambdas-and-streams-in-java-8-libraries/240166818

Streams

数组连接成字符串

Joining Objects into a String with Java 8 Stream API

1
2
String[] strs = {"flower","flow","flight"};
System.out.println(Arrays.stream(strs).collect(Collectors.joining( "," )));

返回数组最大值

1
2
int[] arr = {2,7,3,13,59,31};
Arrays.stream(arr).max().getAsInt();

List join as String

1
2
List<Integer> primes = primeNumbersTill(100);
String s = primes.stream().map(Object::toString).collect(Collectors.joining(","));
1
2
int[][] matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
Stream.of(matrix).map(Arrays::toString).forEach(System.out::println);

java 8 打印素数序列

1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public static boolean isPrime(int number) {
return IntStream.rangeClosed(2, number/2).noneMatch(i -> number%i == 0);
}

public static List<Integer> primeNumbersTill(int n) {
return IntStream.rangeClosed(2, n)
.filter(x -> isPrime(x)).boxed()
.collect(Collectors.toList());
}

public static void main(String[] args) {
final int n = 100;
List<Integer> primes = primeNumbersTill(n);
String s = primes.stream().map(Object::toString).collect(Collectors.joining(","));
System.out.println(s);
}

2 Sieve of Eratosthenes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public static List<Integer> primeNumber(int n) {
final BitSet sieve = new BitSet(n+1);
List<Integer> plist = IntStream.rangeClosed(2, n)
.filter(x -> !sieve.get(x))
.peek(x -> {
if (x*x < n)
for(int i = x; i <= n; i+=x)
sieve.set(i);
}).boxed()
.collect(Collectors.toList());
return plist;
}

public static void main(String[] args) {
final int n = 100;
List<Integer> plist = primeNumber(n);
System.out.println(plist.stream().map(Object::toString).collect(Collectors.joining(",")));
}

Lambda

LocalDate

1
2
3
LocalDate now = LocalDate.now();
LocalDate firstDayOfYear = now.with(TemporalAdjusters.firstDayOfYear());
System.out.println( firstDayOfYear.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) );

LeetCode - Algorithms - 14. Longest Common Prefix

此题在LeetCode上难度标为Easy,LintCode上却标为Medium

这题虽然不能脱离IDE直接刷题,但没怎么被卡住,一天之内就做完了,还算简单吧。有共同前缀的字符串,它们的首字母肯定一样。

JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
* @param {string[]} strs
* @return {string}
*/
var longestCommonPrefix = function(strs) {
var lcp = "";
if (strs==null || strs.length==0)
return lcp;
var minLen = strs[0].length;
var idx = 0;
for(var i=1;i<strs.length;i++) {
if (strs[i].length<minLen) {
minLen = strs[i].length;
idx = i;
}
}
var lcp = "";
var ch = strs[idx].charAt(0);
var b = true;
for(var i=0;i<strs.length;i++) {
b = b && strs[i].charAt(0)==ch?true:false;
}
if (b) {
lcp+=ch;
for(var j=1;j<minLen;j++) {
ch = strs[idx].charAt(j);
b = true;
for(var i=0;i<strs.length;i++) {
b = b && (strs[i].charAt(j)==ch?true:false);
}
if (b)
lcp += ch;
}
}
return lcp;
};

Submission Detail

  • 118 / 118 test cases passed.
  • Your runtime beats 81.84 % of javascript submissions.

如果在

1
2
if (b)
lcp += ch;

后面加个break语句用于跳出循环判断,改成

1
2
3
4
if (b)
lcp += ch;
else
break;

性能倒反降低了,这个有点不明白?

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Solution {
public String longestCommonPrefix(String[] strs) {
if (strs==null || strs.length==0) return "";
int minStrLen = strs[0].length();
int idx = 0;
for(int i=1;i<strs.length;i++) {
if (strs[i].length()<minStrLen) {
minStrLen = strs[i].length();
idx = i;
}
}
StringBuilder lcp = new StringBuilder();
if (strs[idx]!=null && strs[idx].length()>0) {
char ch = strs[idx].charAt(0);
boolean b = true;
for(int i=0;i<strs.length;i++) {
b = b && (strs[i].charAt(0)==ch?true:false);
}
if (b) {
lcp.append(ch);
for(int j=1;j<minStrLen;j++) {
ch = strs[idx].charAt(j);
b = true;
for(int i=0;i<strs.length;i++) {
b = b && (strs[i].charAt(j)==ch?true:false);
}
if (b) {
lcp.append(ch);
}
else {
break;
}
}
}
}
return lcp.toString();
}
}

Submission Detail

  • 118 / 118 test cases passed.
  • Your runtime beats 11.84 % of java submissions.

跟js代码的情况一样,加了跳出循环判断的break语句

1
2
3
4
5
6
if (b) {
lcp.append(ch);
}
else {
break;
}

性能倒反降低,不解?

LeetCode - Algorithms - 344. Reverse String

这题确实easy,做这题倒真可以脱离IDE在leetcode编辑器里刷题了。
做这题,又犯了一次java与js字符串的小错误,在Java里获取String长度的length()是method,在js里获取字符串长度的length是property,老是搞混淆了。

Javascript

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* @param {string} s
* @return {string}
*/
var reverseString = function(s) {
var r = "";
if (s!=null && s.length>0) {
for(var i=s.length-1;i>=0;i--) {
r+=s[i];
}
}
return r;
};

Submission Detail

  • 476 / 476 test cases passed.
  • Your runtime beats 96.31 % of javascript submissions.

Java

LOOP+SB

1

1
2
3
4
5
6
7
8
9
10
11
class Solution {
public String reverseString(String s) {
StringBuilder sb = new StringBuilder();
if (s!=null && !s.isEmpty()) {
for(int i=s.length()-1;i>=0;i--) {
sb.append(s.charAt(i));
}
}
return sb.toString();
}
}

Submission Detail

  • 476 / 476 test cases passed.
  • Your runtime beats 13.87 % of java submissions.

跟js写法差不多,这java代码的性能倒不行

2

1
2
3
4
5
6
7
8
9
10
11
12
class Solution {
public String reverseString(String s) {
StringBuilder sb = new StringBuilder();
if (s!=null && !s.isEmpty()) {
char[] arr = s.toCharArray();
for(int i=arr.length-1;i>=0;i--) {
sb.append(arr[i]);
}
}
return sb.toString();
}
}

Submission Detail

  • 476 / 476 test cases passed.
  • Your runtime beats 5.40 % of java submissions.

SB

1
2
3
4
5
6
7
8
9
10
class Solution {
public String reverseString(String s) {
String r = "";
if (s!=null && !s.isEmpty()) {
StringBuilder sb = new StringBuilder(s);
r = sb.reverse().toString();
}
return r;
}
}

Submission Detail

  • 476 / 476 test cases passed.
  • Your runtime beats 5.40 % of java submissions.

直接用StringBuilder的reverse(),用StringBuffer好像也类似,性能没什么变化

逆转字符数组

Ref

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
public String reverseString(String s) {
String r = "";
if (s!=null && !s.isEmpty()) {
char[] arr = s.toCharArray();
for (int i=0; i<arr.length/2; i++) {
char temp = arr[i];
arr[i] = arr[arr.length-1-i];
arr[arr.length-1-i] = temp;
}
r = new String(arr);
}
return r;
}
}

Submission Detail

  • 476 / 476 test cases passed.
  • Your runtime beats 7.62 % of java submissions.

Rust

Rust 95%+

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
impl Solution {
pub fn reverse_string(s: &mut Vec<char>) {
let len = s.len();
if len > 0 {
let mut midpoint = len / 2;
if len % 2 != 0 {
midpoint += 1;
}
for i in 0..midpoint {
let j = len - i - 1;
let buffer = s[i];
s[i] = s[j];
s[j] = buffer;
}
}
}
}

Submission Detail

  • 478 / 478 test cases passed.
  • Runtime: 20 ms, faster than 95.94% of Rust online submissions for Reverse String.
  • Memory Usage: 5.1 MB, less than 100.00% of Rust online submissions for Reverse String.

LeetCode - Algorithms - 300. Longest Increasing Subsequence

Longest increasing subsequence 看来也是道比较经典的算法题,LeetCode 与 LintCode 都有此题。

有名的算法网站 Rosetta Code 上有此题的N种语言之实现 Longest increasing subsequence

Dynamic Programming

琢磨不出来,上网搜罗

google关键字:

  • longest increasing subsequence dynamic programming
  • longest increasing subsequence optimal substructure

这是相关资料:

代码虽然在LeetCode上跑通了,但还是没有完全理解其中的步骤,还是处于知其然而不知其所以然的阶段,好像有点数学归纳法的意味,也有点像递归,动态规划好像也能用来解决兔子序列问题。

java

Efficient algorithms followed Wikipedia

binary search + DP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Solution {
public int lengthOfLIS(int[] nums) {
int N = nums.length;
int[] M = new int[N + 1];

int L = 0;
for (int i = 0; i < N; i++) {
int lo = 1;
int hi = L;
while (lo <= hi) {
int mid = new Double(Math.ceil((lo + hi) / 2)).intValue();
if (nums[M[mid]] < nums[i])
lo = mid + 1;
else
hi = mid - 1;
}

int newL = lo;

M[newL] = i;

if (newL > L)
L = newL;
}
return L;
}
}

Submission Detail

  • 54 / 54 test cases passed.
  • Runtime: 5 ms, faster than 75.39% of Java online submissions for Longest Increasing Subsequence.
  • Memory Usage: 39.2 MB, less than 12.91% of Java online submissions for Longest Increasing Subsequence.

o(n^2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public int lengthOfLIS(int[] nums) {
if (nums.length==0)
return 0;
int[] L = new int[nums.length];
L[0]=1;
for(int i=1;i<nums.length;i++) {
for(int j=0;j<i;j++) {
if(nums[j]<nums[i] && L[j]>L[i])
L[i] = L[j];
}
L[i]++;
}
return Arrays.stream(L).max().getAsInt();
}
}

Submission Detail

  • 24 / 24 test cases passed.
  • Your runtime beats 5.56 % of java submissions.

javascript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
* @param {number[]} nums
* @return {number}
*/
var lengthOfLIS = function(nums) {
if (nums==null || nums.length==0)
return 0;
var arr = new Array(nums.length);
for(i=0;i<arr.length;i++)
arr[i] = 0;
arr[0] = 1;
for(i=1;i<nums.length;i++) {
for(j=0;j<i;j++) {
if (nums[j]<nums[i] && arr[j]>arr[i]) {
arr[i] = arr[j];
}
}
arr[i]++;
}
var maxLISLen = arr[0];
for(var i=1;i<arr.length;i++) {
if (arr[i]>maxLISLen)
maxLISLen = arr[i];
}
return maxLISLen;
};

Submission Detail

  • 24 / 24 test cases passed.
  • Your runtime beats 13.56 % of javascript submissions.

此题使用动态规划的算法看来性能不好,时间复杂度为O(n2),维基百科上说最有效的算法为 Patience sorting,能达到 O(n log n)

LeetCode - Algorithms - 283. Move Zeroes

就这么一道tag为Easy的题,对自己来说也不简单呐,犯了各种错误,死循环,数组越界,逻辑错误…,先是用js在页面上试验,结果死循环浏览器卡死,只好先换成java在eclipse上调试。按理这道题用到的就是冒泡排序、选择排序里的操作吧。

自己只会用各种库与框架,如果要从头写,看来连对数组操作也不熟悉,google关键字java array shift elements left,找到:

最后总算在leetcode上跑通了,不过还是稀里糊涂的。性能不行,不知道人家高手是怎么做的?难道用快速排序的思路?

java

1
2
3
4
5
6
7
8
9
10
11
12
class Solution {
public void moveZeroes(int[] nums) {
for(int i=nums.length-1;i>=0;i--) {
if (nums[i]==0) {
for(int j=i+1; j<nums.length; j++) {
nums[j-1]=nums[j];
}
nums[nums.length-1]=0;
}
}
}
}

Submission Detail

  • 21 / 21 test cases passed.
  • Your runtime beats 11.98 % of java submissions.

javascript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
var moveZeroes = function(nums) {
for(i=nums.length-1;i>=0;i--) {
if (nums[i]==0) {
for(j=i+1;j<nums.length;j++) {
nums[j-1]=nums[j];
}
nums[nums.length-1]=0;
}
}
};

Submission Detail

  • 21 / 21 test cases passed.
  • Your runtime beats 18.25 % of javascript submissions.

What makes a good life? Lessons from the longest study on happiness - Robert Waldinger - TEDx talk - Transcript

00:00
What keeps us healthy and happy as we go through life? If you were going to invest now in your future best self, where would you put your time and your energy? There was a recent survey of millennials asking them what their most important life goals were, and over 80 percent said that a major life goal for them was to get rich. And another 50 percent of those same young adults said that another major life goal was to become famous.

00:38
(Laughter)

00:40
And we’re constantly told to lean in to work, to push harder and achieve more. We’re given the impression that these are the things that we need to go after in order to have a good life. Pictures of entire lives, of the choices that people make and how those choices work out for them, those pictures are almost impossible to get. Most of what we know about human life we know from asking people to remember the past, and as we know, hindsight is anything but 20/20. We forget vast amounts of what happens to us in life, and sometimes memory is downright creative.

01:24
But what if we could watch entire lives as they unfold through time? What if we could study people from the time that they were teenagers all the way into old age to see what really keeps people happy and healthy?

01:43
We did that. The Harvard Study of Adult Development may be the longest study of adult life that’s ever been done. For 75 years, we’ve tracked the lives of 724 men, year after year, asking about their work, their home lives, their health, and of course asking all along the way without knowing how their life stories were going to turn out.

02:13
Studies like this are exceedingly rare. Almost all projects of this kind fall apart within a decade because too many people drop out of the study, or funding for the research dries up, or the researchers get distracted, or they die, and nobody moves the ball further down the field. But through a combination of luck and the persistence of several generations of researchers, this study has survived. About 60 of our original 724 men are still alive, still participating in the study, most of them in their 90s. And we are now beginning to study the more than 2,000 children of these men. And I’m the fourth director of the study.

03:03
Since 1938, we’ve tracked the lives of two groups of men. The first group started in the study when they were sophomores at Harvard College. They all finished college during World War II, and then most went off to serve in the war. And the second group that we’ve followed was a group of boys from Boston’s poorest neighborhoods, boys who were chosen for the study specifically because they were from some of the most troubled and disadvantaged families in the Boston of the 1930s. Most lived in tenements, many without hot and cold running water.

03:42
When they entered the study, all of these teenagers were interviewed. They were given medical exams. We went to their homes and we interviewed their parents. And then these teenagers grew up into adults who entered all walks of life. They became factory workers and lawyers and bricklayers and doctors, one President of the United States. Some developed alcoholism. A few developed schizophrenia. Some climbed the social ladder from the bottom all the way to the very top, and some made that journey in the opposite direction.

04:23
The founders of this study would never in their wildest dreams have imagined that I would be standing here today, 75 years later, telling you that the study still continues. Every two years, our patient and dedicated research staff calls up our men and asks them if we can send them yet one more set of questions about their lives.

04:48
Many of the inner city Boston men ask us, “Why do you keep wanting to study me? My life just isn’t that interesting.” The Harvard men never ask that question.

04:59
(Laughter)

05:08
To get the clearest picture of these lives, we don’t just send them questionnaires. We interview them in their living rooms. We get their medical records from their doctors. We draw their blood, we scan their brains, we talk to their children. We videotape them talking with their wives about their deepest concerns. And when, about a decade ago, we finally asked the wives if they would join us as members of the study, many of the women said, “You know, it’s about time.”

05:38
(Laughter)

05:39
So what have we learned? What are the lessons that come from the tens of thousands of pages of information that we’ve generated on these lives? Well, the lessons aren’t about wealth or fame or working harder and harder. The clearest message that we get from this 75-year study is this: Good relationships keep us happier and healthier. Period.

06:11
We’ve learned three big lessons about relationships. The first is that social connections are really good for us, and that loneliness kills. It turns out that people who are more socially connected to family, to friends, to community, are happier, they’re physically healthier, and they live longer than people who are less well connected. And the experience of loneliness turns out to be toxic. People who are more isolated than they want to be from others find that they are less happy, their health declines earlier in midlife, their brain functioning declines sooner and they live shorter lives than people who are not lonely. And the sad fact is that at any given time, more than one in five Americans will report that they’re lonely.

07:07
And we know that you can be lonely in a crowd and you can be lonely in a marriage, so the second big lesson that we learned is that it’s not just the number of friends you have, and it’s not whether or not you’re in a committed relationship, but it’s the quality of your close relationships that matters. It turns out that living in the midst of conflict is really bad for our health. High-conflict marriages, for example, without much affection, turn out to be very bad for our health, perhaps worse than getting divorced. And living in the midst of good, warm relationships is protective.

07:45
Once we had followed our men all the way into their 80s, we wanted to look back at them at midlife and to see if we could predict who was going to grow into a happy, healthy octogenarian and who wasn’t. And when we gathered together everything we knew about them at age 50, it wasn’t their middle age cholesterol levels that predicted how they were going to grow old. It was how satisfied they were in their relationships. The people who were the most satisfied in their relationships at age 50 were the healthiest at age 80. And good, close relationships seem to buffer us from some of the slings and arrows of getting old. Our most happily partnered men and women reported, in their 80s, that on the days when they had more physical pain, their mood stayed just as happy. But the people who were in unhappy relationships, on the days when they reported more physical pain, it was magnified by more emotional pain.

08:52
And the third big lesson that we learned about relationships and our health is that good relationships don’t just protect our bodies, they protect our brains. It turns out that being in a securely attached relationship to another person in your 80s is protective, that the people who are in relationships where they really feel they can count on the other person in times of need, those people’s memories stay sharper longer. And the people in relationships where they feel they really can’t count on the other one, those are the people who experience earlier memory decline. And those good relationships, they don’t have to be smooth all the time. Some of our octogenarian couples could bicker with each other day in and day out, but as long as they felt that they could really count on the other when the going got tough, those arguments didn’t take a toll on their memories.

09:49
So this message, that good, close relationships are good for our health and well-being, this is wisdom that’s as old as the hills. Why is this so hard to get and so easy to ignore? Well, we’re human. What we’d really like is a quick fix, something we can get that’ll make our lives good and keep them that way. Relationships are messy and they’re complicated and the hard work of tending to family and friends, it’s not sexy or glamorous. It’s also lifelong. It never ends. The people in our 75-year study who were the happiest in retirement were the people who had actively worked to replace workmates with new playmates. Just like the millennials in that recent survey, many of our men when they were starting out as young adults really believed that fame and wealth and high achievement were what they needed to go after to have a good life. But over and over, over these 75 years, our study has shown that the people who fared the best were the people who leaned in to relationships, with family, with friends, with community.

11:09
So what about you? Let’s say you’re 25, or you’re 40, or you’re 60. What might leaning in to relationships even look like?

11:19
Well, the possibilities are practically endless. It might be something as simple as replacing screen time with people time or livening up a stale relationship by doing something new together, long walks or date nights, or reaching out to that family member who you haven’t spoken to in years, because those all-too-common family feuds take a terrible toll on the people who hold the grudges.

11:52
I’d like to close with a quote from Mark Twain. More than a century ago, he was looking back on his life, and he wrote this: “There isn’t time, so brief is life, for bickerings, apologies, heartburnings, callings to account. There is only time for loving, and but an instant, so to speak, for that.”

12:22
The good life is built with good relationships.

12:27
Thank you.

12:28
(Applause)