算法設計(二)

1.html

給定一個整數數組 nums ,找到一個具備最大和的連續子數組(子數組最少包含一個元素),返回其最大和。node

示例:算法

輸入: [-2,1,-3,4,-1,2,1,-5,4],
輸出: 6
解釋: 連續子數組 [4,-1,2,1] 的和最大,爲 6。

進階:數組

若是你已經實現複雜度爲 O(n) 的解法,嘗試使用更爲精妙的分治法求解:ide

public class Solution {
public int MaxSubArray(int[] nums) 
{
  int res = nums[0];
  int sum = nums[0];
  for(int i = 1; i < nums.Length; i++)
  { 
    sum = Math.Max(nums[i], sum + nums[i]);
    res = Math.Max(res, sum);
  }
  return res;
  }
}spa

 

2.code

給定一個整數數組 nums 和一個目標值 target,請你在該數組中找出和爲目標值的那 兩個 整數,並返回他們的數組下標。htm

你能夠假設每種輸入只會對應一個答案。可是,你不能重複利用這個數組中一樣的元素。blog

示例:字符串

給定 nums = [2, 7, 11, 15], target = 9

由於 nums[0] + nums[1] = 2 + 7 = 9
因此返回 [0, 1]

複雜度分析:

  • 時間複雜度:O(n)O(n), 咱們只遍歷了包含有 nn 個元素的列表一次。在表中進行的每次查找只花費 O(1)O(1) 的時間。

  • 空間複雜度:O(n)O(n), 所需的額外空間取決於哈希表中存儲的元素數量,該表最多須要存儲 nn 個元素。

事實證實,咱們能夠一次完成。在進行迭代並將元素插入到表中的同時,咱們還會回過頭來檢查表中是否已經存在當前元素所對應的目標元素。若是它存在,那咱們已經找到了對應解,並當即將其返回。

 public int[] twoSum(int[] nums, int target) {

  Map<Integer, Integer> map = new HashMap<>();
  for (int i = 0; i < nums.length; i++) {
    int complement = target - nums[i];
    if (map.containsKey(complement))

      {

      return new int[] { map.get(complement), i };

     }
    map.put(nums[i], i);
    }
    throw new IllegalArgumentException("No two sum solution");
}

 

3.兩數相加

給出兩個 非空 的鏈表用來表示兩個非負的整數。其中,它們各自的位數是按照 逆序 的方式存儲的,而且它們的每一個節點只能存儲 一位 數字。

若是,咱們將這兩個數相加起來,則會返回一個新的鏈表來表示它們的和。

您能夠假設除了數字 0 以外,這兩個數都不會以 0 開頭。

示例:

輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出:7 -> 0 -> 8
緣由:342 + 465 = 807

算法

就像你在紙上計算兩個數字的和那樣,咱們首先從最低有效位也就是列表 l1l1 和 l2l2 的表頭開始相加。因爲每位數字都應當處於 0 \ldots 909 的範圍內,咱們計算兩個數字的和時可能會出現「溢出」。例如,5 + 7 = 125+7=12。在這種狀況下,咱們會將當前位的數值設置爲 22,並將進位 carry = 1carry=1 帶入下一次迭代。進位 carrycarry 一定是 00 或 11,這是由於兩個數字相加(考慮到進位)可能出現的最大和爲 9 + 9 + 1 = 199+9+1=19。

僞代碼以下:

  • 將當前結點初始化爲返回列表的啞結點。
  • 將進位 carrycarry 初始化爲 00。
  • 將 pp 和 qq 分別初始化爲列表 l1l1 和 l2l2 的頭部。
  • 遍歷列表 l1l1 和 l2l2 直至到達它們的尾端。
    • 將 xx 設爲結點 pp 的值。若是 pp 已經到達 l1l1 的末尾,則將其值設置爲 00。
    • 將 yy 設爲結點 qq 的值。若是 qq 已經到達 l2l2 的末尾,則將其值設置爲 00。
    • 設定 sum = x + y + carrysum=x+y+carry。
    • 更新進位的值,carry = sum / 10carry=sum/10。
    • 建立一個數值爲 (sum \bmod 10)(summod10) 的新結點,並將其設置爲當前結點的下一個結點,而後將當前結點前進到下一個結點。
    • 同時,將 pp 和 qq 前進到下一個結點。
  • 檢查 carry = 1carry=1 是否成立,若是成立,則向返回列表追加一個含有數字 11 的新結點。
  • 返回啞結點的下一個結點。

請注意,咱們使用啞結點來簡化代碼。若是沒有啞結點,則必須編寫額外的條件語句來初始化表頭的值。

複雜度分析

  • 時間複雜度:O(\max(m, n))O(max(m,n)),假設 mm 和 nn 分別表示 l1l1 和 l2l2 的長度,上面的算法最多重複 \max(m, n)max(m,n) 次。

  • 空間複雜度:O(\max(m, n))O(max(m,n)), 新列表的長度最多爲 \max(m,n) + 1max(m,n)+1。

 1  // Definition for singly-linked list.
 2   public class ListNode {
 3       public int val;
 4       public ListNode next;
 5       public ListNode(int x) { val = x; }
 6   }
 7  
 8 public class Solution {
 9     public ListNode AddTwoNumbers(ListNode l1, ListNode l2) 
10     {
11         ListNode node1 = l1.next;
12         ListNode node2 = l2.next;
13         int arry = 0;  
14         ListNode newNode = new ListNode(0);
15         while(node1 !=null || node2 != null)
16         {
17             int x = node1 != null ? node1.val:0;
18             int y = node2 != null ? node2.val:0;
19             int sum = x + y + arry;
20             arry = sum / 10;
21             newNode.next = new ListNode(sum % 10);
22             newNode = newNode.next;
23             
24             node1 = (node1!=null)? node1.next:null;
25             
26             node2 = (node2!=null)? node2.next:null;   
27         }
28        
29         if(arry > 0)
30             newNode.next = new ListNode(arry);
31         
32         return newNode;
33     }
34 }
View Code

 4.無重複字符的最長字串

給定一個字符串,請你找出其中不含有重複字符的 最長子串 的長度。

示例 1:

輸入: "abcabcbb"
輸出: 3 
解釋: 由於無重複字符的最長子串是 長度爲 3。
"abc",因此其

示例 2:

輸入: "bbbbb"
輸出: 1
解釋: 由於無重複字符的最長子串是 ,因此其長度爲 1。
"b"

示例 3:

輸入: "pwwkew"
輸出: 3
解釋: 由於無重複字符的最長子串是 ,因此其長度爲 3。
     請注意,你的答案必須是 子串 的長度, 是一個子序列,不是子串。"wke""pwke"
 1 public class Solution {
 2     public int LengthOfLongestSubstring(string s) {
 3         int[] map = new int[128];
 4         int left = 0, right = 0, cnt = 0;
 5         while (right < s.Length){
 6             int c = (int)(s[right]);
 7             if (map[c] == 0){
 8                 map[c] = 1;
 9                 right++;
10             } else {
11                 map[(int)(s[left])] = 0;
12                 left++;
13             }
14             if (right - left > cnt) cnt = right - left;
15         }
16         return cnt;
17     }
18 }
View Code
相關文章
相關標籤/搜索