Compan

 

 

Given a sorted array of distinct integers and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.

You must write an algorithm with O(log n) runtime complexity.

 

 

풀이

 

 

단순하게 traget 숫자가 배열의 몇번째에 있는지 찾는 문제이다.

 

for문을 통해서 단순하게 해결 할 수 있지만  문제에서 O(log n)의 시간복잡도를 가져야한다는 조건을 가지고 있다.

시간복잡도 O(log n)을 보자마자 이진탐색이 떠올랐고 이진탐색으로 문제를 풀어보았다.

 

왼쪽 시작점과 오른쪽 시작점의 중간을 mid로 지정 한 후 

mid값이 target보다 크다면 right를 mid-1로 지정

mid값이 target보다 작다면 left를 mid+1 로 지정

 

class Solution(object):
    def searchInsert(self, nums, target):
        left =0
        right = len(nums)-1
        while left<right:
            mid = (left+right)//2
            if nums[mid] == target:
                return mid
            elif nums[right] ==target:
                return right
            elif nums[left]== target:
                return left
            if nums[mid]<target:
                right=mid-1
            else:
                left=mid+1
 

하지만.. 계속해서 시간 초과가 났었다. ㅠㅠ 

 

1.무엇이 문젠지 고민을 했는데, 굳이 right left값이 동일한지 확인하는 과정이 불필요하다는걸 깨닫고  mid값으로만 찾게했다 - > 하지만 실패

 

2. if문에서 이미 값이 크다면 right =  mid-1 , 작다면  left =mid+1로 값을 변경되도록 만들었는데 부호를 반대로 줘서 계속해서 돌다 mid가 0으로 나누어떨어지며 시간초과가 난다는걸 발견 한 후 다시 수정했다.

 

class Solution(object):
    def searchInsert(self, nums, target):
        left =0
        right = len(nums)-1

        while left<=right:
            mid = (left+right)//2
            m = nums[mid]
            if nums[mid]== target:
                return mid
            if nums[mid]>target:
                right=mid-1
            else:
                left=mid+1
        return left

 

해결 완료 

'알고리즘 > LeetCode' 카테고리의 다른 글

LeetCode 1. Two Sum  (0) 2023.08.31
LeetCode 155. Min Stack  (0) 2023.08.31
LeetCode 141. Linked List Cycle  (0) 2023.08.29
LeetCode 209. Minimum Size Subarray Sum  (0) 2023.08.29
LeetCode 3. Longest Substring Without Repeating Characters  (0) 2023.08.29

Given head, the head of a linked list, determine if the linked list has a cycle in it.

There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next pointer. Internally, pos is used to denote the index of the node that tail's next pointer is connected to. Note that pos is not passed as a parameter.

Return true if there is a cycle in the linked list. Otherwise, return false.

 

 

 

#풀이

 

 

 

 

 

 

문제를 접하고 처음에 든 생각은 '음..head..이론으로는 알겠지만 파이썬으로는 어떻게 사용하지?' ㅎㅎ..

 

구글에서 조사를 해보니 보통 class를 통해서 head와 tail을 지정하여 객체로 만들어내는걸 알았다.

 

문제에서도 동일하게 head,next,tail로 변수를 지정해서 각각의 노드와 방향을 알 수 있게 만들어놨다.

 

이후에 문제의 답을 보고 코드를 만들었는데. while문을 통해 head의 다음 노드를 이동하며 , 모든 노드를 돌게 되었을때 방문했던 노드를 다시 방문하게 된다면 순환하는 linkedlist라고 할 수 있다.

 

list를 통해서 값을 확인하여 중복값이 많아져서 값이 많이 늘어났는데 다른 사람은 set을 사용해서 방문노드 중복을 막아 시간을 단축한 걸 볼 수 있었다.

 

class Solution(object):
    def hasCycle(self, head):
        visit = []
        while head :
            if head in visit:
                return True
            
            visit.append(head)
            head = head.next
        return False

파이썬에서는 list()를 많이 사용했었지만, 동적리스트와 정적리스트의 차이를 모르고 사용했었다. 최근에 강의를 통해

리스트구조가 어떻게 만들어지는지 알게 되었다. 

 

leetcode문제를 풀면서도 느끼지만, 확실히  기본기부분에서 부족한 부분이 많다는걸 느낀다.

 

열심히 공부해야지ㅣㅣ..

Given an array of positive integers nums and a positive integer target, return the minimal length of a 

subarray whose sum is greater than or equal to target. If there is no such subarray, return 0 instead.

 

 

#풀이

 

그림으로 그려서 각 인덱스를 포인터가 증가 될 떄마다 2중 for문을 통해 중복되는 값을 제외하고 계산한값을 모두 탐색하는 방법을 생각했다.

 

하지만 .....

 

class Solution(object):
    def minSubArrayLen(self, target, nums):
        min_range=1e9
        for i in range(len(nums)):  #인덱스
            for ii in range(i,-1,-1):
                if target ==sum(nums[-(ii+1):]):
                    min_range= min(min_range,ii+1)
        if min_range == 1e9:
            min_n
            
        return min_range

틀렸다고 나오는 테스트케이스

1,2,3,4,5 중 3개의 번호를 뽑아서 11을 만들어야한다는데.. 연속된 수로 나오는 값으로는 만들 수 없는 값인데 어떻게..?

 왜 안되지라고 고민하던 중.. 문제에서 target의 값과 같은게 아니라 동일하거나 큰 값을 만들 수 있는 경우를 찾는거였다

문제를 잘 읽어야지 ㅠㅠ 

 

결론은 뒤에서부터 슬라이싱해서 자르는 방법이라 중간에 나오는 두가지 값을 더해주지는 못했다 결국 

포인터를 만든 후 포인터를 움직여서 값을 찾는 방식으로 바꿨다.

 

 

 left 포인터를 사용해서 right 포인터를 두고 작다면  왼쪽포인터의 값을 +1 증가시키고 , while문을 통해 값의 조건식 (크거나 같음)을 만족시키면 멈추고  만족시키지 못한다면 left 포인터가 오른쪽으로 움직이며 값을 증가시키게 된다,

class Solution(object):
    def minSubArrayLen(self,s, nums):
        min_range=1e9
        left =0
        temp = 0
        
        for i in range(len(nums)):
            temp += nums[i]
            while temp >= s:
                min_range = min(min_range, i - left + 1)
                temp -= nums[left]
                left += 1
        if min_range == 1e9:
            min_range= 0

        return min_range

 

 

문제를 잘 읽자 ...!  ㅠㅠ 

Given a string s, find the length of the longest substring without repeating characters.

 

 

풀이

1.

처음엔 단순하게 중복문자가  나온다면 중복 문자를 넣고 초기화 하는 방법으로 했는데

실패했다 , 문제에서 요구하는 바는 중복되는 '문자열'을 확인해야했다.

 

2.

슬라이딩 윈도우로 for문을 돌면서 중복되는 문자열이 나온다면

result 리스트안의 문자가 겹치는 부분을 슬라이싱을 통해서 뗴낸 후 다시 for문을 넣는 방법을 생각했지만

인덱싱 슬라이스를 하며 초기화 되는부분을 상세하게 넣지 못해서 계속 실패했다.

 

 

 

1.
class Solution(object):
    def lengthOfLongestSubstring(self, s):
        counter =0
        result =[]
        for i in range(len(s)):
            if s[i] not in result:
                result.append(s[i])
            else:
                result =[s[i]]
            counter= max(counter,len(result))
        return counter​
        
"dvdf" vdf


2.

counter =0
result =[]

for i in range(len(s)):
    if s[i] not in result:
        result.append(s[i])
    else:
        for j in range(len(result)):
            if s[i] == result[j]:
                result =result[j:]
                print(result)
                break
    # print(result)
    counter= max(counter,len(result))

이후에 솔루션을 찾아보니 비슷한 방법으로 푼 사람의 코드를 보니 

 

내 코드는 

중복되는 문자열을 발견했을 때 인덱스 슬라이싱을 한 후 result문자열에 넣는 방법이 잘못되었다는걸 깨달았다.

# result =""
# max_length = 0
# for i in s:
# 	if i in result:
# 		result = result[result.index(i)+1:]
# 		"""if abcdas is the string, here after abcd the length would be 4 and result will be replaced as bcda"""
# 	result += i
# 	max_length = max(max_length, len(result))
# return (max_length)

 

 

아직도 어지럽다..ㅋㅋㅋ 비슷한 문제를 다시 풀어봐야지 익숙해질것같다.

 

'알고리즘 > LeetCode' 카테고리의 다른 글

LeetCode 141. Linked List Cycle  (0) 2023.08.29
LeetCode 209. Minimum Size Subarray Sum  (0) 2023.08.29
LeetCode 167. Two Sum II - Input Array Is Sorted  (0) 2023.08.28
LeetCode 125. Valid Palindrome  (0) 2023.08.27
LeetCode 55. Jump Game  (0) 2023.08.25

 

 

Given a 1-indexed array of integers numbers that is already sorted in non-decreasing order, find two numbers such that they add up to a specific target number. Let these two numbers be numbers[index1] and numbers[index2] where 1 <= index1 < index2 < numbers.length.

Return the indices of the two numbers, index1 and index2, added by one as an integer array [index1, index2] of length 2.

The tests are generated such that there is exactly one solution. You may not use the same element twice.

Your solution must use only constant extra space.

 

 

#풀이

 

비교적 간단한 문제라서 금방 풀었다!

 

left와 right 포인터를 둔 후 같다면 값을 리턴시키고 작다면 left포인터 +1 크다면 right 포인터를 -1로 줄이는 방법을 사용했다.

class Solution(object):
    def twoSum(self, numbers, target):

        left = 0
        right = len(numbers)-1
        while True:
            if numbers[left]+numbers[right] == target:
                result = [left+1,right+1]
                break
            elif numbers[left]+numbers[right]> target:
                    right-=1
            elif numbers[left]+numbers[right]< target:
                    left+=1
        return result

 

다른사람의 코드 

class Solution:
    def twoSum(self, numbers: List[int], target: int) -> List[int]:
        i = 0
        j = len(numbers) -1
        
        while i<j:
            s = numbers[i] + numbers[j]
            if s == target:
                return [i + 1 , j + 1]
            
            if s > target:
                j-=1
            else:
               i+=1 
        
        return []

다들 비슷하게 투포인터를 사용해서 푼 거 같다

A phrase is a palindrome if, after converting all uppercase letters into lowercase letters and removing all non-alphanumeric characters, it reads the same forward and backward. Alphanumeric characters include letters and numbers.

Given a string s, return true if it is a palindrome, or false otherwise.

 

 

풀이

 

문자열이 앞뒤로 동일하면 회문이라한다. 이 문제는 숫자와 영어소문자로만 구분해서 앞뒤가 같은 회문인지 확인하는 문제이다.

 

문자열을 구분하기 위해서 ord함수를 사용하여 아스키코드로 변환하여 소문자 대문자 숫자를 구분해줬다.

 

 

이후에 left ,right 두 개의 포인터를 둔 후 양끝에서 하나씩 확인하는 방법으로 구현했다.

class Solution(object):
    def isPalindrome(self, s):
        word =[]
        for i in s:
            ii = ord(i)
            if 96<ii<123:
                word.append(i)
            elif 47<ii<58:
                word.append(i)
            elif 64<ii<91:
                word.append(i.lower())
        right=len(word)-1
        left = 0
        result= True
        while left<right:
            if word[left] !=word[right]:
                result = False
            right-=1
            left+=1
        return result

 

 


다른 사람의 코드

def isPalindrome(self, s):
    l, r = 0, len(s)-1
    while l < r:
        while l < r and not s[l].isalnum():
            l += 1
        while l <r and not s[r].isalnum():
            r -= 1
        if s[l].lower() != s[r].lower():
            return False
        l +=1; r -= 1
    return True

단순하게 투포인터를 사용한 후 isalnum 함수를 통해 문자와 숫자를 구분한 후 투포인터를 사용했다.

 

아..아스키코드말고 issalnum()을 통해서 숫자와 문자를 구분하는 방법도 있구나 

 

다음에 사용해봐야겠다.

You are given an integer array nums. You are initially positioned at the array's first index, and each element in the array represents your maximum jump length at that position.

Return true if you can reach the last index, or false otherwise.

 

 

 

풀이

 

문제를 보고 bfs를 사용해야겠다고 생각했다.

 

class Solution(object):
    def canJump(self, nums):
        n =len(nums)
        visit = [0] * (n)
        result = False
        q= []

        q.append(0)
        visit[0] = 1
        while q:
            node = q.pop()
            if node == n-1:
                result =True
                break
            for i in range(1,nums[node]+1):
                if node+i <n and visit[i+node] ==0:
                    print(node+i)
                    visit[i+node]=1
                    q.append(node+i)
        return result
        
        
 #sudo
 
 list = [1,1,2,3,4]
 최초 0번 인덱스에서 시작

 방문리스트 생성 = [0] *(n)
 q =[0] bfs를 시작할 리스트
 while q가 0이 될 때 까지
 	q.pop() q에 담긴 원소 꺼내기
    for i in range(list[q.pop()]) 큐에 담긴 원소를 list인덱스 값을 for문 range(범위)로 지정
   		if 현재인덱스 + i < 리스트의 원소 개수 and  visit[현재인덱스+i]==0 방문하지 않았다면:
        	q.append(i+현재인덱스)

문제를 해결하긴 했으나 속도나 성능이 굉장히 낮은 편이었다. 

 

 

다른사람이 dp를 이용해 풀이한 방법 

#dp를 통해 푼 풀이법

class Solution:
    def canJump(self, nums: List[int]) -> bool:
        n = len(nums)
        dp = [False] * n
        dp[n-1] = True
        for i in range(n-2, -1, -1):
            for j in range(i+1, min(n, i+nums[i]+1)):
                if dp[j]:
                    dp[i] = True
                    break
        return dp[0]

하향식 dp를 통해서 문제를 해결했다 . dp로 푸는 방식이 확실히 성능면에선 뛰어났다 . 

You are given an integer array prices where prices[i] is the price of a given stock on the ith day.

On each day, you may decide to buy and/or sell the stock. You can only hold at most one share of the stock at any time. However, you can buy it then immediately sell it on the same day.

Find and return the maximum profit you can achieve.

 

 

문제를 보고 이건 마지막인덱스에서 최고값을 찾아서 거꾸로 들어가면 되지 않을까? 라는 생각이 먼저 들었다.

 

제일 높은 가격을 갖고 앞인덱스로 이동하면서 각각 판매이익을 계산하는 방법으로 진행해봤다.

 

더 큰 값이 나온다면 현재 지금까지 제일 이익이 높았던 가격에 판매를 하고 최고값을 다시 갱신 후 앞으로 이동한다.

 

prices = [7,1,5,3,6,4]

start = len(prices)-1


result = 0
max_value = prices[start]
max_profit =0
temp_profit = 0
for i in range(start,-1,-1):
    if prices[i] < max_value:
        if max_value - prices[i] > max_profit:
            max_profit = max_value- prices[i]
    elif prices[i] > max_value:
        result+=max_profit
        max_profit=0
        max_value= prices[i]

result+= max_profit

print(result)

일단 답은 틀렸다.. 중간에 최고값으로만 비교해서 그런거같다 중간 중간에 temp를 통해서 중간에 팔리는 가격도 계산해줘서 넣어주면 풀릴거같으나 시간이 부족해서 보류!

'알고리즘 > LeetCode' 카테고리의 다른 글

LeetCode 125. Valid Palindrome  (0) 2023.08.27
LeetCode 55. Jump Game  (0) 2023.08.25
LeetCode 121. Best Time to Buy and Sell Stock  (0) 2023.08.25
LeetCode 189. Rotate Array  (0) 2023.08.25
LeetCode 169. Majority Element  (0) 2023.08.25

+ Recent posts