Hướng dẫn two sum leetcode solution javascript - hai giải pháp leetcode tổng hợp javascript

Vấn đề này đặc biệt khó chịu, và sâu sắc đối với tôi. Lý do là có nhiều cách để giải quyết nó. Tìm một giải pháp là đặc biệt khó khăn nếu bạn đã mã hóa trong một vài tháng. Tìm một giải pháp hợp lý sẽ được coi là chấp nhận được trong cuộc phỏng vấn kỹ thuật, là khó khăn đối với tôi. Trong bài đăng này, tôi sẽ giải thích cách tiếp cận của mình đối với vấn đề tương đối nổi tiếng này. Chúng tôi sẽ giải thích vấn đề, đưa ra việc thực hiện rõ ràng nhất, và sau đó tìm một giải pháp thanh lịch hơn.

Hai vấn đề tổng hợp nêu rõ một loạt các số nguyên, trả về các chỉ số của hai số sao cho chúng cộng vào một mục tiêu cụ thể. Chúng ta có thể sử dụng cùng một yếu tố hai lần.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

Chúng tôi sẽ bắt đầu vào các giải pháp dưới đây.

Giải pháp đầu tiên và rõ ràng nhất là những gì mà Lọ gọi là giải pháp vũ phu lặp đi lặp lại, trong đó chúng tôi lặp lại thông qua mọi sự kết hợp có thể (trong trường hợp xấu nhất) cho đến khi chúng tôi tìm thấy một giải pháp.

function twoSum(nums, target) {
for (let i = 0; i < nums.length; i++) {
for (let j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] === target) {
return [i, j];
}
}
}
}

Trong trường hợp này, chúng tôi lấy mảng (num) và đối với mỗi phần tử của mảng, chúng tôi xem xét vị trí tiếp theo của cùng một mảng (do đó các vòng lặp lồng nhau). Nếu tổng của hai số này bằng với mục tiêu, tuyệt vời! Chúng tôi đã hoàn thành, chỉ cần trả lại vị trí của hai số đó trong các vòng lặp tương ứng của tôi. Đủ đơn giản.

Tại sao đây không phải là một giải pháp tốt?

Thông thường, các giải pháp vũ lực rất dễ thực hiện và sẽ luôn tìm thấy một giải pháp nếu tồn tại. Nhưng sự đánh đổi có xu hướng là chúng tốn kém về mặt tính toán và thậm chí chỉ có thể thực hiện được nếu chúng ta biết rằng kích thước của các đầu vào là tương đối nhỏ.

Thuật toán này có thể mất nhiều thời gian. Trên thực tế, trong ký hiệu O Big O, thời gian bậc hai, hoặc O (n) bởi vì, tại trường hợp tồi tệ hơn, chúng tôi phải xem xét mọi yếu tố của mảng này và thực hiện một hoạt động của mọi yếu tố khác của mảng.

Một vòng lặp lồng nhau có xu hướng là một dấu hiệu của các cơ hội tối ưu hóa. Vì vậy, làm thế nào chúng ta có thể làm cho nó tốt hơn?

Làm cho nó hiệu quả hơn với bộ nhớ đệm thêm và một chút logic

Như đã đề cập trước đây, mọi thuật toán đều có một giao dịch. Một giải pháp hiệu quả hơn về thời gian, có sự đánh đổi mà,

a) Nó yêu cầu nhiều bộ nhớ hơn (tức là không gian)

b) Nó khó khăn hơn một chút để khái niệm hóa

Ở đây, một cách tiếp cận khác mà không phải lặp lại thông qua mảng nhiều lần:

function twoSum(nums, target) {let numObj = {};
for (let i = 0; i < nums.length; i++) {
let complement = target - nums[i];
if (numObj[complement] !== undefined) {
return [numObj[complement], i];
}
numObj[nums[i]] = i;
}
}

Thay vì tìm kiếm tổng của hai số, đó sẽ là cách tiếp cận rõ ràng và trực quan, cách tiếp cận này lấy từng số và tìm kiếm số mà khi được thêm vào, sẽ cân bằng mục tiêu (tức là bổ sung). Đối với mỗi số trong mảng, nó tạo biến bổ sung này. Nếu số bổ sung đó tồn tại trong khóa: đối tượng giá trị được gọi là NumObj mà chúng tôi đã tạo (tức là, nó không được xác định), thì thật tuyệt! Trả về vị trí số đó trong đối tượng cùng với vị trí số mà chúng tôi đang xem xét và chúng tôi đã hoàn thành. Nếu không, sau đó thêm số mà chúng tôi đang xem xét và vị trí của nó, trong đối tượng NumObj.

Nó không trực quan khi đưa ra giải pháp này, nhưng bạn có thể nhanh chóng thấy rằng, ở trường hợp tồi tệ hơn, bạn chỉ phải lặp lại toàn bộ mảng một lần. Điều này làm cho hoạt động tìm kiếm số mà chúng tôi đang tìm kiếm nhanh hơn nhiều.

Cảm ơn vì đã đọc!

Và hãy nhớ: grit> tài năng.

Giới thiệu

LeetCode. Một sự thật đáng tiếc của cuộc sống nhà phát triển là đối với một số cuộc phỏng vấn việc làm, cần phải học cấu trúc dữ liệu và thuật toán (DSA) theo một cách cụ thể. Một cách mà bạn dự kiến ​​sẽ mã hóa một giải pháp cho vấn đề DSA nơi bạn sẽ google nó.

Tôi nói _ không may _ bởi vì trong hầu hết các trường hợp, việc biết họ ở mức độ cần thiết cho các cuộc phỏng vấn kỹ thuật là không cần thiết và hầu như không phản ánh khả năng công việc thực tế._unfortunate _ because in most cases it is unnecessary to know them to the degree required for the technical interviews and hardly reflects actual job capability.

Nhưng tôi lạc đề, LeetCode là một trang web tổng hợp hàng tấn các vấn đề DSA khác nhau. Tôi sẽ trải qua một số vấn đề LeetCode trong tháng tới, giải thích và giải quyết chúng, để giúp đỡ người khác. Và nó cũng giúp tôi viết lại giải pháp. 😎

Lời nhắc

Đưa ra một loạt các số nguyên & nbsp; ________ 7 & nbsp; và một số nguyên & nbsp; ____ ____ 8, return & nbsp; chỉ số của hai số mà chúng cộng vào & nbsp; ________ 8. Bạn có thể cho rằng mỗi đầu vào sẽ có & nbsp; chính xác & nbsp; một giải pháp và bạn không được sử dụng & nbsp; cùng & nbsp; phần tử hai lần. Bạn có thể trả lại câu trả lời theo bất kỳ thứ tự nào.exactly one solution, and you may not use the same element twice. You can return the answer in any order.

Ví dụ 1:

Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].

Suy nghĩ thông qua

Đây là vấn đề LeetCode đầu tiên và khá dễ dàng. Điều đầu tiên xuất hiện trong tâm trí chỉ là lặp lại trên mảng hai lần và tìm ra số tiền cần thiết. Điều này sẽ 100% cho chúng tôi giải pháp.

Tuy nhiên, như nhiều bạn có thể biết về các loại câu hỏi này. Thông thường, nó không đủ để đúng. Đối với các vấn đề DSA, bạn muốn có hiệu quả nhất có thể.efficient as possible.

Hướng dẫn two sum leetcode solution javascript - hai giải pháp leetcode tổng hợp javascript
Ảnh của Aron Visuals trên Unplash

Vì vậy, ví dụ, giải pháp đầu tiên của chúng tôi sẽ là một cái gì đó dọc theo các dòng này:

Hướng dẫn two sum leetcode solution javascript - hai giải pháp leetcode tổng hợp javascript

Trong đó

function twoSum(nums, target) {
for (let i = 0; i < nums.length; i++) {
for (let j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] === target) {
return [i, j];
}
}
}
}
0 là giá trị của lần lặp đầu tiên của chúng tôi và
function twoSum(nums, target) {
for (let i = 0; i < nums.length; i++) {
for (let j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] === target) {
return [i, j];
}
}
}
}
1 là giá trị của lần lặp thứ hai của chúng tôi. Sau khi được thêm vào, chúng tôi nhận được
function twoSum(nums, target) {
for (let i = 0; i < nums.length; i++) {
for (let j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] === target) {
return [i, j];
}
}
}
}
2, đó là giải pháp chúng tôi cần.

Giải pháp đầu tiên

Tôi chủ yếu sử dụng JavaScript để giải pháp sẽ trông giống như thế này:

JavaScript

const twoSum(nums, target) { for(let i = 0; i < nums.length; i++) { for (let j = 0; j < nums.length; j++) { if(j === i) continue; if((nums[i] + nums[j]) === target) return [i, j]; } } }

nums là mảng số và target là giải pháp mong muốn. Tôi lặp lại trên cả hai mảng và kiểm tra xem tổng là giá trị cần thiết. Tuy nhiên, như đã nêu trong lời nhắc, chúng ta không nên sử dụng cùng một phần tử hai lần.

Vì vậy, chúng tôi có thể kiểm tra xem các lần lặp có ở cùng một phần tử không và bỏ qua:

JavaScript

if(j === i) continue;

Tuy nhiên, như tôi đã đề cập trước đây là điều này rất không được tối ưu hóa.

Giải pháp thứ hai

Một giải pháp tốt hơn nhiều sẽ là tìm kiếm mục tiêu dựa trên số hiện tại. Điều đó nghĩa là gì?current number. What does that mean?

Ví dụ: khi bạn lần đầu tiên bắt đầu lặp lại trên mảng, bạn biết số chính xác mà bạn đang tìm kiếm. Số bạn đang tìm kiếm là kết quả của phép trừ mục tiêu và giá trị lặp hiện tại.result of the subtraction of the target and the current iterated value.

Hãy lấy mảng đầu tiên của chúng tôi làm ví dụ.

Hướng dẫn two sum leetcode solution javascript - hai giải pháp leetcode tổng hợp javascript

Khi chúng tôi ở phần tử đầu tiên

function twoSum(nums, target) {
for (let i = 0; i < nums.length; i++) {
for (let j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] === target) {
return [i, j];
}
}
}
}
5, chúng tôi biết rằng chúng tôi cần tìm là
function twoSum(nums, target) {
for (let i = 0; i < nums.length; i++) {
for (let j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] === target) {
return [i, j];
}
}
}
}
2 trừ
function twoSum(nums, target) {
for (let i = 0; i < nums.length; i++) {
for (let j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] === target) {
return [i, j];
}
}
}
}
5 là 7. Nhưng, chúng tôi cần một cách để nhanh chóng truy cập lại dữ liệu của mảng.

Giới thiệu một bảng băm.

Bàn băm

Bảng băm là một cấu trúc dữ liệu ánh xạ khóa cho các giá trị. Điều này là hoàn hảo cho trường hợp sử dụng của chúng tôi bởi vì chúng tôi chỉ muốn ánh xạ

function twoSum(nums, target) {
for (let i = 0; i < nums.length; i++) {
for (let j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] === target) {
return [i, j];
}
}
}
}
8 của chúng tôi đến
function twoSum(nums, target) {
for (let i = 0; i < nums.length; i++) {
for (let j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] === target) {
return [i, j];
}
}
}
}
9 của chúng tôi.

Nhưng làm thế nào để chúng ta tạo ra bảng băm này?

Bản đồ là một đối tượng tích hợp JavaScript. Điều duy nhất bạn cần biết là nó giữ các cặp giá trị khóa và có API để nhanh chóng kiểm tra nội dung:

function twoSum(nums, target) {let numObj = {};
for (let i = 0; i < nums.length; i++) {
let complement = target - nums[i];
if (numObj[complement] !== undefined) {
return [numObj[complement], i];
}
numObj[nums[i]] = i;
}
}
0 để đặt cặp khóa và giá trị

function twoSum(nums, target) {let numObj = {};
for (let i = 0; i < nums.length; i++) {
let complement = target - nums[i];
if (numObj[complement] !== undefined) {
return [numObj[complement], i];
}
numObj[nums[i]] = i;
}
}
1 để nhận giá trị dựa trên khóa

function twoSum(nums, target) {let numObj = {};
for (let i = 0; i < nums.length; i++) {
let complement = target - nums[i];
if (numObj[complement] !== undefined) {
return [numObj[complement], i];
}
numObj[nums[i]] = i;
}
}
2 để kiểm tra xem nó có khóa không

Giải pháp thứ hai

JavaScript

const hashTable = new Map(); for(let i = 0; i < nums.length; i++) { const num = nums[i]; const substractionWeWant = target - num; if (hashTable.has(substractionGoal) { return [i, hashTable.get(substractionGoal)]; } else { hashTable.set(num, i); } }

Bây giờ chúng tôi có một cách đơn giản hóa để kiểm tra các giá trị trước đó. Quay trở lại mã trước tiên chúng tôi thực hiện một lần lặp duy nhất của vòng lặp. Bằng cách trừ đi giá trị target khỏi giá trị chỉ mục hiện tại

function twoSum(nums, target) {let numObj = {};
for (let i = 0; i < nums.length; i++) {
let complement = target - nums[i];
if (numObj[complement] !== undefined) {
return [numObj[complement], i];
}
numObj[nums[i]] = i;
}
}
4, chúng ta có thể kiểm tra xem phần còn lại đã tồn tại. Nếu nó không phải là chúng tôi chỉ cần thêm giá trị, chúng tôi chỉ cố gắng vào bản đồ và tiếp tục.

Vì vậy, để nhắc lại

  1. Chúng tôi lặp qua mảng
  2. Chúng tôi kiểm tra xem bản đồ giá trị hiện tại của chúng tôi có phép trừ target và giá trị hiện tại mà chúng tôi đang lặp lại không. Nếu chúng ta trả về cả chỉ mục của giá trị hiện tại và chỉ mục của giá trị trong bản đồ của chúng ta
  3. Nếu chúng tôi không tìm thấy một trận đấu, chúng tôi sẽ thêm nó vào bản đồ của mình và tiếp tục

Giải pháp đầu tiên:

Hướng dẫn two sum leetcode solution javascript - hai giải pháp leetcode tổng hợp javascript

Giải pháp thứ hai:

Hướng dẫn two sum leetcode solution javascript - hai giải pháp leetcode tổng hợp javascript

Gói nó lên

Nếu bạn muốn theo kịp loạt bài này, hãy theo dõi tôi ở đây hoặc bất kỳ phương tiện truyền thông xã hội nào của tôi dưới đây!

Nhiều nội dung hơn ở mã có thể tin cậy được

Hãy kết nối

Nếu bạn thích điều này, hãy kết nối với tôi trên LinkedIn hoặc Twitter

Kiểm tra lộ trình phát triển miễn phí của tôi và tin tức ngành công nghệ hàng tuần trong bản tin của tôi.

Nếu bạn thấy bất kỳ lỗi chính tả hoặc lỗi nào, bạn có thể chỉnh sửa bài viết trực tiếp trên GitHub

Hãy đứng đầu ngành công nghệ và phát triển như một nhà phát triển với một lựa chọn các bài báo và tin tức cùng với lời khuyên cá nhân, quan sát và hiểu biết. 🚀developer with a curated selection of articles and news alongside personal advice, observations, and insight. 🚀

Không có thư rác 🙅‍♂. Hủy đăng ký

bất cứ khi nào

.

Đặt mua

Làm thế nào để bạn làm leetcode hai khoản tiền?

Approach..
Lấy một yếu tố ..
Thêm phần tử này với mọi yếu tố khác ..
Sau khi thêm, so sánh tổng với mục tiêu đã cho ..
Nếu tổng bằng với mục tiêu, hãy trả lại các chỉ số của hai yếu tố này ..
Nếu tổng không bằng mục tiêu, chúng tôi sẽ kiểm tra cặp tiếp theo ..

LeetCode có JavaScript không?

Trong khóa học này, bạn sẽ tìm hiểu các cấu trúc dữ liệu và các giải pháp thuật toán nâng cao với JavaScript!Đây là những câu hỏi bạn cần chuẩn bị để vào Google, Facebook, Apple, Amazon, JPMC, Goldman và nhiều hơn nữa!LeetCode là gì?LeetCode là một bộ sưu tập lớn (1.050 và đếm) các vấn đề mã hóa đầy thách thức.! These are the questions you need to prepare to get into Google, Facebook, Apple, Amazon, JPMC, Goldman and much more! What is LeetCode? LeetCode is a massive collection (1,050 and counting) of challenging coding problems.